You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/01/29 17:16:24 UTC
svn commit: r1439975 - in /subversion/trunk/subversion:
libsvn_wc/wc-queries.sql libsvn_wc/wc_db_update_move.c
tests/libsvn_wc/wc-queries-test.c
Author: stsp
Date: Tue Jan 29 16:16:23 2013
New Revision: 1439975
URL: http://svn.apache.org/viewvc?rev=1439975&view=rev
Log:
Make notifications during move-update transaction-safe, by only issuing
notifiations if the transaction actually succeeds.
We store notifications in a temporary wc.db table during the update-move
editor drive, and spool notifications from it when the edit completes.
* subversion/libsvn_wc/wc-queries.sql
(STMT_CREATE_UPDATE_MOVE_LIST,
STMT_INSERT_UPDATE_MOVE_LIST,
STMT_FINALIZE_UPDATE_MOVE): New statements.
* subversion/libsvn_wc/wc_db_update_move.c
(update_move_list_add, update_move_list_notify): New helper functions.
(tc_editor_alter_directory, update_working_file): Add notifiations to
the update-move notification list instead of sending them directly.
(update_moved_away_conflict_victim): Create the move-update notification
list before starting the editor drive.
* subversion/tests/libsvn_wc/wc-queries-test.c
(schema_statements): Add STMT_CREATE_UPDATE_MOVE_LIST to this list
of statements which create temporary tables.
(slow_statements): Add STMT_SELECT_UPDATE_MOVE_LIST to the list of
statements which fail if temporary tables don't exist.
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1439975&r1=1439974&r2=1439975&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Tue Jan 29 16:16:23 2013
@@ -1315,6 +1315,30 @@ ORDER BY local_relpath
-- STMT_FINALIZE_DELETE
DROP TABLE IF EXISTS delete_list
+-- STMT_CREATE_UPDATE_MOVE_LIST
+DROP TABLE IF EXISTS update_move_list;
+CREATE TEMPORARY TABLE update_move_list (
+/* ### we should put the wc_id in here in case a move update spans multiple
+ ### working copies. queries, etc will need to be adjusted. */
+ local_relpath TEXT PRIMARY KEY NOT NULL UNIQUE,
+ action INTEGER NOT NULL,
+ kind INTEGER NOT NULL,
+ content_state INTEGER NOT NULL,
+ prop_state INTEGER NOT NULL
+ )
+
+-- STMT_INSERT_UPDATE_MOVE_LIST
+INSERT INTO update_move_list(local_relpath, action, kind, content_state,
+ prop_state)
+VALUES (?1, ?2, ?3, ?4, ?5)
+
+-- STMT_SELECT_UPDATE_MOVE_LIST
+SELECT local_relpath, action, kind, content_state, prop_state
+FROM update_move_list
+ORDER BY local_relpath
+
+-- STMT_FINALIZE_UPDATE_MOVE
+DROP TABLE IF EXISTS update_move_list
/* ------------------------------------------------------------------------- */
Modified: subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c?rev=1439975&r1=1439974&r2=1439975&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Tue Jan 29 16:16:23 2013
@@ -131,6 +131,86 @@ struct tc_editor_baton {
apr_pool_t *result_pool;
};
+/*
+ * Notifications are delayed until the entire update-move transaction
+ * completes. These functions provide the necessary support by storing
+ * notification information in a temporary db table (the "update_move_list")
+ * and spooling notifications out of that table after the transaction.
+ */
+
+/* Add an entry to the notification list. */
+static svn_error_t *
+update_move_list_add(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ svn_wc_notify_action_t action,
+ svn_node_kind_t kind,
+ svn_wc_notify_state_t content_state,
+ svn_wc_notify_state_t prop_state)
+
+{
+ svn_sqlite__stmt_t *stmt;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_INSERT_UPDATE_MOVE_LIST));
+ SVN_ERR(svn_sqlite__bindf(stmt, "sdddd", local_relpath,
+ action, kind, content_state, prop_state));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ return SVN_NO_ERROR;
+}
+
+/* Send all notifications stored in the notification list, and then
+ * remove the temporary database table. */
+static svn_error_t *
+update_move_list_notify(svn_wc__db_wcroot_t *wcroot,
+ svn_revnum_t old_revision,
+ svn_revnum_t new_revision,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ apr_pool_t *iterpool;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_UPDATE_MOVE_LIST));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ iterpool = svn_pool_create(scratch_pool);
+ while (have_row)
+ {
+ const char *local_relpath;
+ svn_wc_notify_action_t action;
+ svn_wc_notify_t *notify;
+
+ svn_pool_clear(iterpool);
+
+ local_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+ action = svn_sqlite__column_int(stmt, 1);
+ notify = svn_wc_create_notify(svn_dirent_join(wcroot->abspath,
+ local_relpath,
+ iterpool),
+ action, iterpool);
+ notify->kind = svn_sqlite__column_int(stmt, 2);
+ notify->content_state = svn_sqlite__column_int(stmt, 3);
+ notify->prop_state = svn_sqlite__column_int(stmt, 4);
+ notify->old_revision = old_revision;
+ notify->revision = new_revision;
+ notify_func(notify_baton, notify, scratch_pool);
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ svn_pool_destroy(iterpool);
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_FINALIZE_UPDATE_MOVE));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
mark_tree_conflict(struct tc_editor_baton *b,
const char *local_relpath,
@@ -619,19 +699,11 @@ tc_editor_alter_directory(void *baton,
}
if (b->notify_func)
- {
- svn_wc_notify_t *notify;
-
- notify = svn_wc_create_notify(dst_abspath,
- svn_wc_notify_update_update,
- scratch_pool);
- notify->kind = svn_node_dir;
- notify->content_state = svn_wc_notify_state_inapplicable;
- notify->prop_state = prop_state;
- notify->old_revision = b->old_version->peg_rev;
- notify->revision = b->new_version->peg_rev;
- b->notify_func(b->notify_baton, notify, scratch_pool);
- }
+ SVN_ERR(update_move_list_add(b->wcroot, dst_relpath,
+ svn_wc_notify_update_update,
+ svn_node_dir,
+ svn_wc_notify_state_inapplicable,
+ prop_state));
}
return SVN_NO_ERROR;
@@ -749,19 +821,11 @@ update_working_file(svn_skel_t **work_it
}
if (notify_func)
- {
- svn_wc_notify_t *notify;
-
- notify = svn_wc_create_notify(local_abspath,
- svn_wc_notify_update_update,
- scratch_pool);
- notify->kind = svn_node_file;
- notify->content_state = content_state;
- notify->prop_state = prop_state;
- notify->old_revision = old_version->location_and_kind->peg_rev;
- notify->revision = new_version->location_and_kind->peg_rev;
- notify_func(notify_baton, notify, scratch_pool);
- }
+ SVN_ERR(update_move_list_add(wcroot, local_relpath,
+ svn_wc_notify_update_update,
+ svn_node_file,
+ content_state,
+ prop_state));
return SVN_NO_ERROR;
}
@@ -1015,6 +1079,12 @@ tc_editor_complete(void *baton,
{
struct tc_editor_baton *b = baton;
+ /* Send all queued up notifications. */
+ SVN_ERR(update_move_list_notify(b->wcroot,
+ b->old_version->peg_rev,
+ b->new_version->peg_rev,
+ b->notify_func, b->notify_baton,
+ scratch_pool));
if (b->notify_func)
{
svn_wc_notify_t *notify;
@@ -1560,6 +1630,10 @@ update_moved_away_conflict_victim(svn_sk
svn_dirent_join(wcroot->abspath, victim_relpath,
scratch_pool),
scratch_pool));
+
+ /* Create a new, and empty, list for notification information. */
+ SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
+ STMT_CREATE_UPDATE_MOVE_LIST));
/* Create the editor... */
SVN_ERR(svn_editor_create(&tc_editor, tc_editor_baton,
cancel_func, cancel_baton,
Modified: subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1439975&r1=1439974&r2=1439975&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c Tue Jan 29 16:16:23 2013
@@ -73,6 +73,7 @@ static const int schema_statements[] =
STMT_CREATE_TARGET_PROP_CACHE,
STMT_CREATE_REVERT_LIST,
STMT_CREATE_DELETE_LIST,
+ STMT_CREATE_UPDATE_MOVE_LIST,
-1 /* final marker */
};
@@ -92,6 +93,7 @@ static const int slow_statements[] =
STMT_INSERT_ACTUAL_EMPTIES,
STMT_SELECT_REVERT_LIST_RECURSIVE,
STMT_SELECT_DELETE_LIST,
+ STMT_SELECT_UPDATE_MOVE_LIST,
/* Designed as slow to avoid penalty on other queries */
STMT_SELECT_UNREFERENCED_PRISTINES,