You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2010/11/11 13:49:26 UTC
svn commit: r1033919 - in /subversion/trunk/subversion:
libsvn_wc/wc-queries.sql libsvn_wc/wc_db.c libsvn_wc/workqueue.c
tests/libsvn_wc/op-depth-test.c
Author: philip
Date: Thu Nov 11 12:49:26 2010
New Revision: 1033919
URL: http://svn.apache.org/viewvc?rev=1033919&view=rev
Log:
When removing a base node any corresponding base-deleted working node
must also be removed; if there is then no working node any corresponding
non-conflict actual node must also be removed. Do all this in a single
database operation to maintain database consistency.
* subversion/libsvn_wc/wc_db.c
(retract_parent_delete): New.
(struct base_remove_baton): New.
(db_base_remove): New, based on svn_wc__db_base_remove but removes
dependent working and actual nodes.
(svn_wc__db_base_remove): Call db_base_remove inside a txn.
* subversion/libsvn_wc/wc-queries.sql
(STMT_DELETE_LOWEST_WORKING_NODE): New.
* subversion/libsvn_wc/workqueue.c
(remove_base_node): Always use svn_wc__db_base_remove.
* subversion/tests/libsvn_wc/op-depth-test.c
(wc_resolved): New.
(test_delete_with_update): Extend.
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/workqueue.c
subversion/trunk/subversion/tests/libsvn_wc/op-depth-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=1033919&r1=1033918&r2=1033919&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Nov 11 12:49:26 2010
@@ -304,6 +304,13 @@ WHERE wc_id = ?1 AND local_relpath = ?2
AND op_depth = (SELECT MAX(op_depth) FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0);
+-- STMT_DELETE_LOWEST_WORKING_NODE
+DELETE FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2
+ AND op_depth = (SELECT MIN(op_depth) FROM nodes
+ WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0)
+ AND presence = 'base-deleted';
+
-- STMT_DELETE_ALL_WORKING_NODES
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0;
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1033919&r1=1033918&r2=1033919&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Nov 11 12:49:26 2010
@@ -786,6 +786,28 @@ extend_parent_delete(svn_sqlite__db_t *s
return SVN_NO_ERROR;
}
+/* This is the reverse of extend_parent_delete.
+
+ When removing a base node if the parent has a working node then the
+ parent base and this node are both deleted and so the delete of
+ this node must be removed.
+ */
+static svn_error_t *
+retract_parent_delete(svn_sqlite__db_t *sdb,
+ apr_int64_t wc_id,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_DELETE_LOWEST_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ return SVN_NO_ERROR;
+}
+
/* */
@@ -1824,6 +1846,45 @@ svn_wc__db_base_add_not_present_node(svn
kind, svn_wc__db_status_not_present, conflict, work_items, scratch_pool);
}
+struct base_remove_baton {
+ const char *local_relpath;
+ apr_int64_t wc_id;
+};
+
+static svn_error_t *
+db_base_remove(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
+{
+ struct base_remove_baton *brb = baton;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_BASE_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", brb->wc_id, brb->local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ SVN_ERR(retract_parent_delete(sdb, brb->wc_id, brb->local_relpath,
+ scratch_pool));
+
+ /* If there is no working node then any actual node must be deleted,
+ unless it marks a conflict */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", brb->wc_id, brb->local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ SVN_ERR(svn_sqlite__reset(stmt));
+ if (!have_row)
+ {
+#ifndef TREE_CONFLICTS_ON_CHILDREN
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_ACTUAL_NODE));
+#else
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT));
+#endif
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", brb->wc_id, brb->local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+
+ return SVN_NO_ERROR;
+}
svn_error_t *
svn_wc__db_base_remove(svn_wc__db_t *db,
@@ -1832,7 +1893,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
{
svn_wc__db_pdh_t *pdh;
const char *local_relpath;
- svn_sqlite__stmt_t *stmt;
+ struct base_remove_baton brb;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1841,18 +1902,18 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
- SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
- STMT_DELETE_BASE_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+ brb.local_relpath = local_relpath;
+ brb.wc_id = pdh->wcroot->wc_id;
- SVN_ERR(svn_sqlite__step_done(stmt));
+ SVN_ERR(svn_sqlite__with_transaction(pdh->wcroot->sdb,
+ db_base_remove, &brb,
+ scratch_pool));
SVN_ERR(flush_entries(db, pdh, local_abspath, scratch_pool));
return SVN_NO_ERROR;
}
-
static svn_error_t *
base_get_info(svn_wc__db_status_t *status,
svn_wc__db_kind_t *kind,
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1033919&r1=1033918&r2=1033919&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Thu Nov 11 12:49:26 2010
@@ -569,21 +569,9 @@ remove_base_node(svn_wc__db_t *db,
else
SVN_ERR(err);
}
-
- /* This should remove just BASE and ACTUAL, but for now also remove
- not existing WORKING_NODE data. */
- SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, scratch_pool));
- }
- else if (wrk_status == svn_wc__db_status_added
- || (have_work && wrk_status == svn_wc__db_status_excluded))
- /* ### deletes of working additions should fall in this case, but
- ### we can't express these without the 4th tree */
- {
- /* Just remove the BASE_NODE data */
- SVN_ERR(svn_wc__db_base_remove(db, local_abspath, scratch_pool));
}
- else
- SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, scratch_pool));
+
+ SVN_ERR(svn_wc__db_base_remove(db, local_abspath, scratch_pool));
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1033919&r1=1033918&r2=1033919&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Thu Nov 11 12:49:26 2010
@@ -220,6 +220,15 @@ wc_update(wc_baton_t *b, const char *pat
TRUE, FALSE, FALSE, ctx, b->pool);
}
+static svn_error_t *
+wc_resolved(wc_baton_t *b, const char *path)
+{
+ svn_client_ctx_t *ctx;
+
+ SVN_ERR(svn_client_create_context(&ctx, b->pool));
+ return svn_client_resolved(wc_path(b, path), TRUE, ctx, b->pool);
+}
+
/* Create the Greek tree on disk in the WC, and commit it. */
static svn_error_t *
add_and_commit_greek_tree(wc_baton_t *b)
@@ -1131,6 +1140,17 @@ test_delete_with_update(const svn_test_o
};
SVN_ERR(check_db_rows(&b, "A", rows));
}
+ SVN_ERR(wc_resolved(&b, ""));
+ SVN_ERR(wc_update(&b, "", 1));
+ {
+ nodes_row_t rows[] = {
+ { 0, "A", "normal", 1, "A"},
+ { 1, "A", "normal", NO_COPY_FROM},
+ { 2, "A/B", "normal", NO_COPY_FROM},
+ { 0 }
+ };
+ SVN_ERR(check_db_rows(&b, "A", rows));
+ }
return SVN_NO_ERROR;
}