Author: philip
Date: Tue Apr 19 17:35:17 2011
New Revision: 1095142

URL: http://svn.apache.org/viewvc?rev=1095142&view=rev
Log:
Start work on a recursive delete implementation, it's not hooked up to
the main delete code yet.

* subversion/libsvn_wc/wc_db.c
  (svn_wc__db_op_delete): Move later in file, start implementation.
  (struct op_delete_baton_t): New.
  (op_delete_txn): New.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_INSERT_WORKING_NODE_FROM_NODE_RECURSIVE,
   STMT_UPDATE_OP_DEPTH_RECURSIVE,
   STMT_DELETE_WORKING_NODE_NOT_DELETED): New.

* subversion/tests/libsvn_wc/op-depth-test.c
  (do_delete, test_op_delete): New.
  (test_funcs): Add test_op_delete.

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=1095142&r1=1095141&r2=1095142&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Tue Apr 19 17:35:17 
2011
@@ -719,6 +719,19 @@ WHERE wc_id = ?1 AND local_relpath = ?2
 ORDER BY op_depth DESC
 LIMIT 1
 
+-- STMT_INSERT_WORKING_NODE_FROM_NODE_RECURSIVE
+INSERT INTO nodes (
+    wc_id, local_relpath, op_depth, parent_relpath, presence, kind, checksum,
+    changed_revision, changed_date, changed_author, depth, symlink_target,
+    translated_size, last_mod_time, properties)
+SELECT wc_id, local_relpath, ?4 /*op_depth*/, parent_relpath, 'base-deleted',
+       kind, checksum, changed_revision, changed_date, changed_author, depth,
+       symlink_target, translated_size, last_mod_time, properties
+FROM nodes_current
+WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
+  AND presence NOT IN ('base-deleted', 'not-present')
+      
+
 -- STMT_INSERT_WORKING_NODE_FROM_BASE_COPY
 INSERT INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
@@ -765,6 +778,15 @@ WHERE wc_id = ?1 AND local_relpath LIKE 
 UPDATE nodes SET op_depth = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
 
+-- STMT_UPDATE_OP_DEPTH_RECURSIVE
+UPDATE nodes SET op_depth = ?3
+WHERE wc_id = ?1 AND local_relpath LIKE ?2 ESCAPE '#' AND op_depth > ?3
+
+-- STMT_DELETE_WORKING_NODE_NOT_DELETED
+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_UPDATE_COPYFROM_TO_INHERIT
 UPDATE nodes SET

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1095142&r1=1095141&r2=1095142&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Apr 19 17:35:17 2011
@@ -3423,17 +3423,6 @@ svn_wc__db_temp_working_set_props(svn_wc
 
 
 svn_error_t *
-svn_wc__db_op_delete(svn_wc__db_t *db,
-                     const char *local_abspath,
-                     apr_pool_t *scratch_pool)
-{
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  NOT_IMPLEMENTED();
-}
-
-
-svn_error_t *
 svn_wc__db_op_move(svn_wc__db_t *db,
                    const char *src_abspath,
                    const char *dst_abspath,
@@ -5091,6 +5080,81 @@ svn_wc__db_temp_op_delete(svn_wc__db_t *
   return SVN_NO_ERROR;
 }
 
+struct op_delete_baton_t {
+  apr_int64_t delete_depth;  /* op-depth for root of delete */
+};
+
+static svn_error_t *
+op_delete_txn(void *baton,
+              svn_wc__db_wcroot_t *wcroot,
+              const char *local_relpath,
+              apr_pool_t *scratch_pool)
+{
+  struct op_delete_baton_t *b = baton;
+  svn_wc__db_status_t status;
+  svn_boolean_t have_base, have_work;
+
+  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,
+                    &have_base, NULL, &have_work,
+                    wcroot, local_relpath,
+                    scratch_pool, scratch_pool));
+
+  if (have_base && !have_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_WORKING_NODE_NOT_DELETED));
+      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__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__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));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_op_delete(svn_wc__db_t *db,
+                     const char *local_abspath,
+                     apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+  struct op_delete_baton_t b;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+                              db, local_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  b.delete_depth = relpath_depth(local_relpath);
+
+  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, op_delete_txn, &b,
+                              scratch_pool));
+
+  SVN_ERR(flush_entries(wcroot, local_abspath, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 
 /* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of
    DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */

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=1095142&r1=1095141&r2=1095142&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Tue Apr 19 
17:35:17 2011
@@ -2765,6 +2765,79 @@ test_children_of_replaced_dir(const svn_
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+do_delete(svn_test__sandbox_t *b,
+          const char *local_relpath,
+          nodes_row_t *before,
+          nodes_row_t *after)
+{
+  const char *local_abspath = wc_path(b, local_relpath);
+
+  SVN_ERR(insert_dirs(b, before));
+  SVN_ERR(check_db_rows(b, "", before));
+  SVN_ERR(svn_wc__db_op_delete(b->wc_ctx->db, local_abspath, b->pool));
+  SVN_ERR(check_db_rows(b, "", after));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_op_delete(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+  SVN_ERR(svn_test__sandbox_create(&b, "op_delete", opts, pool));
+
+  {
+    nodes_row_t state1[] = {
+      { 0, "",        "normal", 5, "" },
+      { 0, "A",       "normal", 5, "A" },
+      { 0, "A/B",     "normal", 5, "A/B" },
+      { 0, "A/B/C",   "normal", 5, "A/B/C" },
+      { 0, "A/B/C/D", "normal", 5, "A/B/C" },
+      { 4, "A/B/C/X", "normal", NO_COPY_FROM },
+      { 0 }
+    };
+    nodes_row_t state2[] = {
+      { 0, "",        "normal",       5, "" },
+      { 0, "A",       "normal",       5, "A" },
+      { 0, "A/B",     "normal",       5, "A/B" },
+      { 0, "A/B/C",   "normal",       5, "A/B/C" },
+      { 0, "A/B/C/D", "normal",       5, "A/B/C" },
+      { 4, "A/B/C/D", "base-deleted", NO_COPY_FROM },
+      { 4, "A/B/C/X", "normal",       NO_COPY_FROM },
+      { 0 }
+    };
+    nodes_row_t state3[] = {
+      { 0, "",        "normal",       5, "" },
+      { 0, "A",       "normal",       5, "A" },
+      { 0, "A/B",     "normal",       5, "A/B" },
+      { 0, "A/B/C",   "normal",       5, "A/B/C" },
+      { 0, "A/B/C/D", "normal",       5, "A/B/C" },
+      { 2, "A/B",     "base-deleted", NO_COPY_FROM },
+      { 2, "A/B/C",   "base-deleted", NO_COPY_FROM },
+      { 2, "A/B/C/D", "base-deleted", NO_COPY_FROM },
+      { 0 }
+    };
+    nodes_row_t state4[] = {
+      { 0, "",        "normal",       5, "" },
+      { 0, "A",       "normal",       5, "A" },
+      { 0, "A/B",     "normal",       5, "A/B" },
+      { 0, "A/B/C",   "normal",       5, "A/B/C" },
+      { 0, "A/B/C/D", "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 },
+      { 1, "A/B/C/D", "base-deleted", NO_COPY_FROM },
+      { 0 }
+    };
+    SVN_ERR(do_delete(&b, "A/B/C/D", state1, state2));
+    SVN_ERR(do_delete(&b, "A/B", state2, state3));
+    SVN_ERR(do_delete(&b, "A", state3, state4));
+  }
+
+  return SVN_NO_ERROR;
+}
+
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
 
@@ -2807,5 +2880,7 @@ 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_PASS(test_op_delete,
+                       "test_op_delete"),
     SVN_TEST_NULL
   };


Reply via email to