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 2011/04/27 18:48:52 UTC

svn commit: r1097174 - in /subversion/trunk/subversion: libsvn_wc/wc-queries.sql libsvn_wc/wc_db.c tests/libsvn_wc/op-depth-test.c

Author: philip
Date: Wed Apr 27 16:48:51 2011
New Revision: 1097174

URL: http://svn.apache.org/viewvc?rev=1097174&view=rev
Log:
Get the single-transaction delete operation to work in more cases.

* subversion/libsvn_wc/wc_db.c
  (op_delete_txn): More comprehensive implementaion.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_DELETE_WORKING_ORPHAN): New.

* subversion/tests/libsvn_wc/op-depth-test.c
  (test_op_delete): Add more cases.
  (test_funcs): Mark test_op_delete PASS.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.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=1097174&r1=1097173&r2=1097174&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed Apr 27 16:48:51 2011
@@ -784,6 +784,13 @@ DELETE FROM nodes
 WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth > ?3
   AND presence NOT IN ('base-deleted', 'not-present')
 
+-- STMT_DELETE_WORKING_ORPHAN
+DELETE FROM nodes
+WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth = ?3
+AND NOT EXISTS (SELECT 1 FROM nodes AS A
+                 WHERE A.wc_id = ?1
+                   AND A.local_relpath = nodes.local_relpath AND op_depth < ?3)
+
 -- STMT_UPDATE_WORKING_TO_DELETED
 UPDATE nodes SET
   repos_id = NULL, repos_path = NULL, revision = NULL,

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1097174&r1=1097173&r2=1097174&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Apr 27 16:48:51 2011
@@ -5099,39 +5099,106 @@ op_delete_txn(void *baton,
 {
   struct op_delete_baton_t *b = baton;
   svn_wc__db_status_t status;
-  svn_boolean_t have_base, have_work;
+  svn_boolean_t op_root, have_base, have_work;
+  svn_boolean_t add_work = FALSE, del_work = FALSE, mod_work = FALSE;
 
   SVN_ERR(read_info(&status,
                     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                    NULL, NULL, NULL,
+                    &op_root, NULL, NULL,
                     &have_base, NULL, &have_work,
                     wcroot, local_relpath,
                     scratch_pool, scratch_pool));
 
-  if (have_base && !have_work)
+  if (status == svn_wc__db_status_deleted
+      || status == svn_wc__db_status_not_present)
+    return SVN_NO_ERROR;
+
+  if (op_root)
+    {
+      svn_boolean_t below_base;
+      svn_boolean_t below_work;
+      svn_wc__db_status_t below_status;
+
+      /* Use STMT_SELECT_NODE_INFO directly instead of read_info plus
+         info_below_working */
+      SVN_ERR(info_below_working(&below_base, &below_work, &below_status,
+                                 wcroot, local_relpath, -1, scratch_pool));
+      if ((below_base || below_work)
+          && below_status != svn_wc__db_status_not_present
+          && below_status != svn_wc__db_status_deleted)
+        mod_work = TRUE;
+      else
+        del_work = TRUE;
+    }
+  else
+    add_work = TRUE;
+
+  if (del_work)
     {
       svn_sqlite__stmt_t *stmt;
       const char *like_arg = construct_like_arg(local_relpath, scratch_pool);
 
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_NODES_RECURSIVE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "issi",
+                                wcroot->wc_id, local_relpath, like_arg,
+                                b->delete_depth));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+  else if (add_work || mod_work)
+    {
+      /* To avoid notification on already deleted nodes that remain
+         deleted we want to avoid removing/reinserting any such
+         nodes. */
+
+      svn_sqlite__stmt_t *stmt;
+      const char *like_arg = construct_like_arg(local_relpath, scratch_pool);
+
+      if (mod_work)
+        {
+          /* Reusing existing queries to delete nodes so insert below
+             works, could use another single query here. */
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                            STMT_DELETE_WORKING_NODE));
+          SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                    wcroot->wc_id, local_relpath));
+          SVN_ERR(svn_sqlite__step_done(stmt));
+
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_WORKING_NODE_NOT_DELETED));
+          SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+                                    wcroot->wc_id, like_arg,
+                                    b->delete_depth - 1));
+          SVN_ERR(svn_sqlite__step_done(stmt));
+        }
+      else
+        {
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_DELETE_WORKING_NODE_NOT_DELETED));
+          SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+                                    wcroot->wc_id, like_arg, b->delete_depth));
+          SVN_ERR(svn_sqlite__step_done(stmt));
+        }
+
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_UPDATE_OP_DEPTH_RECURSIVE));
       SVN_ERR(svn_sqlite__bindf(stmt, "isi",
                                 wcroot->wc_id, like_arg, b->delete_depth));
-      SVN_ERR(svn_sqlite__update(NULL, stmt));
+      SVN_ERR(svn_sqlite__step_done(stmt));
 
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_UPDATE_OP_DEPTH_RECURSIVE));
+                                        STMT_DELETE_WORKING_ORPHAN));
       SVN_ERR(svn_sqlite__bindf(stmt, "isi",
                                 wcroot->wc_id, like_arg, b->delete_depth));
-      SVN_ERR(svn_sqlite__update(NULL, stmt));
+      SVN_ERR(svn_sqlite__step_done(stmt));
 
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                  STMT_INSERT_WORKING_NODE_FROM_NODE_RECURSIVE));
       SVN_ERR(svn_sqlite__bindf(stmt, "issi",
                                 wcroot->wc_id, local_relpath, like_arg,
                                 b->delete_depth));
-      SVN_ERR(svn_sqlite__insert(NULL, stmt));
+      SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
   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=1097174&r1=1097173&r2=1097174&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Wed Apr 27 16:48:51 2011
@@ -2789,10 +2789,18 @@ test_op_delete(const svn_test_opts_t *op
   SVN_ERR(svn_test__sandbox_create(&b, "op_delete", opts, pool));
 
   {
-    nodes_row_t before[] = {
+    nodes_row_t before1[] = {
+      { 0, "",    "normal",       5, "" },
+      { 0, "A",   "normal",       5, "A" },
+      { 0, "A/B", "normal",       5, "A/B" },
+      { 0 }
+    };
+    nodes_row_t before2[] = {
       { 0, "",    "normal",       5, "" },
       { 0, "A",   "normal",       5, "A" },
       { 0, "A/B", "normal",       5, "A/B" },
+      { 1, "A",   "normal",       NO_COPY_FROM },
+      { 2, "A/B", "normal",       NO_COPY_FROM },
       { 0 }
     };
     nodes_row_t after[] = {
@@ -2803,7 +2811,8 @@ test_op_delete(const svn_test_opts_t *op
       { 1, "A/B", "base-deleted", NO_COPY_FROM },
       { 0 }
     };
-    SVN_ERR(do_delete(&b, "A", before, after));
+    SVN_ERR(do_delete(&b, "A", before1, after));
+    SVN_ERR(do_delete(&b, "A", before2, after));
   }
 
   {
@@ -2862,6 +2871,30 @@ test_op_delete(const svn_test_opts_t *op
   }
 
   {
+    nodes_row_t before[] = {
+      { 0, "",        "normal",       5, "" },
+      { 0, "A",       "normal",       5, "A" },
+      { 0, "A/B",     "normal",       5, "A/B" },
+      { 0, "A/B/C",   "normal",       5, "A/B/C" },
+      { 3, "A/B/C",   "normal",       3, "X" },
+      { 3, "A/B/C/D", "normal",       3, "X/D" },
+      { 4, "A/B/C/D", "base-deleted", NO_COPY_FROM },
+      { 0 }
+    };
+    nodes_row_t after[] = {
+      { 0, "",        "normal",       5, "" },
+      { 0, "A",       "normal",       5, "A" },
+      { 0, "A/B",     "normal",       5, "A/B" },
+      { 0, "A/B/C",   "normal",       5, "A/B/C" },
+      { 1, "A",       "base-deleted", NO_COPY_FROM },
+      { 1, "A/B",     "base-deleted", NO_COPY_FROM },
+      { 1, "A/B/C",   "base-deleted", NO_COPY_FROM },
+      { 0 }
+    };
+    SVN_ERR(do_delete(&b, "A", before, after));
+  }
+
+  {
     nodes_row_t state1[] = {
       { 0, "",        "normal", 5, "" },
       { 0, "A",       "normal", 5, "A" },
@@ -3249,8 +3282,8 @@ struct svn_test_descriptor_t test_funcs[
                        "test_op_revert_changelist"),
     SVN_TEST_OPTS_PASS(test_children_of_replaced_dir,
                        "test_children_of_replaced_dir"),
-    SVN_TEST_OPTS_XFAIL(test_op_delete,
-                        "test_op_delete"),
+    SVN_TEST_OPTS_PASS(test_op_delete,
+                       "test_op_delete"),
     SVN_TEST_OPTS_PASS(test_child_replace_with_same_origin,
                        "test_child_replace_with_same"),
     SVN_TEST_OPTS_PASS(test_shadowed_update,