You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2011/05/13 23:18:55 UTC

svn commit: r1102900 - in /subversion/trunk/subversion/libsvn_wc: crop.c wc-queries.sql wc_db.c wc_db.h

Author: rhuijben
Date: Fri May 13 21:18:55 2011
New Revision: 1102900

URL: http://svn.apache.org/viewvc?rev=1102900&view=rev
Log:
Limit the scope of the wc_db call for setting depth on a directory to its
only user: svn_wc_crop_tree2.

* subversion/libsvn_wc/crop.c
  (crop_children): Update caller. Add argument to avoid one db call
    per directory.
  (svn_wc_crop_tree2): Update caller.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_UPDATE_NODE_BASE_DEPTH): Only change depth on directories, to allow
    using the number of affected rows for error handling.
  (STMT_UPDATE_NODE_WORKING_DEPTH,
   STMT_UPDATE_NODE_BASE_EXCLUDED,
   STMT_UPDATE_NODE_WORKING_EXCLUDED): Remove queries.

* subversion/libsvn_wc/wc_db.c
  (set_base_depth_baton_t): New struct.
  (update_depth_values): Rename to ...
  (db_op_set_base_depth): ... this and only update BASE nodes where the
    depth can change. Remove entry flush.
  (svn_wc__db_temp_op_set_dir_depth): Rename to ...
  (svn_wc__db_op_set_base_depth): ... this and call db_op_set_base_depth in
    transaction. Flush entries here after successfull db change.

* subversion/libsvn_wc/wc_db.h
  Remove obsolete comment from before we introduced svn_wc__db_status_excluded.
  (svn_wc__db_temp_op_set_dir_depth): Rename to ...
  (svn_wc__db_op_set_base_depth): ... this.

Modified:
    subversion/trunk/subversion/libsvn_wc/crop.c
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h

Modified: subversion/trunk/subversion/libsvn_wc/crop.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/crop.c?rev=1102900&r1=1102899&r2=1102900&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/crop.c (original)
+++ subversion/trunk/subversion/libsvn_wc/crop.c Fri May 13 21:18:55 2011
@@ -50,8 +50,10 @@
   } while (0)
 
 /* Helper function that crops the children of the LOCAL_ABSPATH, under the
- * constraint of DEPTH. The DIR_PATH itself will never be cropped. The whole
- * subtree should have been locked.
+ * constraint of NEW_DEPTH. The DIR_PATH itself will never be cropped. The
+ * whole subtree should have been locked.
+ *
+ * DIR_DEPTH is the current depth of LOCAL_ABSPATH as stored in DB.
  *
  * If NOTIFY_FUNC is not null, each file and ROOT of subtree will be reported
  * upon remove.
@@ -59,7 +61,8 @@
 static svn_error_t *
 crop_children(svn_wc__db_t *db,
               const char *local_abspath,
-              svn_depth_t depth,
+              svn_depth_t dir_depth,
+              svn_depth_t new_depth,
               svn_wc_notify_func2_t notify_func,
               void *notify_baton,
               svn_cancel_func_t cancel_func,
@@ -67,31 +70,24 @@ crop_children(svn_wc__db_t *db,
               apr_pool_t *pool)
 {
   const apr_array_header_t *children;
-  svn_depth_t dir_depth;
   apr_pool_t *iterpool;
   int i;
 
-  SVN_ERR_ASSERT(depth >= svn_depth_empty && depth <= svn_depth_infinity);
+  SVN_ERR_ASSERT(new_depth >= svn_depth_empty
+                 && new_depth <= svn_depth_infinity);
 
   if (cancel_func)
     SVN_ERR(cancel_func(cancel_baton));
 
   iterpool = svn_pool_create(pool);
 
-  SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, &dir_depth, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL,
-                               db, local_abspath, pool, iterpool));
-
   if (dir_depth == svn_depth_unknown)
     dir_depth = svn_depth_infinity;
 
   /* Update the depth of target first, if needed. */
-  if (dir_depth > depth)
-    SVN_ERR(svn_wc__db_temp_op_set_dir_depth(db, local_abspath, depth,
-                                             iterpool));
+  if (dir_depth > new_depth)
+    SVN_ERR(svn_wc__db_op_set_base_depth(db, local_abspath, new_depth,
+                                         iterpool));
 
   /* Looping over current directory's SVN entries: */
   SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath, pool,
@@ -124,7 +120,7 @@ crop_children(svn_wc__db_t *db,
           svn_depth_t remove_below = (kind == svn_wc__db_kind_dir)
                                             ? svn_depth_immediates
                                             : svn_depth_files;
-          if (depth < remove_below)
+          if (new_depth < remove_below)
             SVN_ERR(svn_wc__db_op_remove_node(db, local_abspath,
                                               SVN_INVALID_REVNUM,
                                               svn_wc__db_kind_unknown,
@@ -139,7 +135,7 @@ crop_children(svn_wc__db_t *db,
              file in the future, svn_wc_remove_from_revision_control() can
              also handle it. We only need to skip the notification in that
              case. */
-          if (depth == svn_depth_empty)
+          if (new_depth == svn_depth_empty)
             IGNORE_LOCAL_MOD(
               svn_wc__internal_remove_from_revision_control(
                                                    db,
@@ -154,7 +150,7 @@ crop_children(svn_wc__db_t *db,
         }
       else if (kind == svn_wc__db_kind_dir)
         {
-          if (depth < svn_depth_immediates)
+          if (new_depth < svn_depth_immediates)
             {
               IGNORE_LOCAL_MOD(
                 svn_wc__internal_remove_from_revision_control(
@@ -170,6 +166,7 @@ crop_children(svn_wc__db_t *db,
             {
               SVN_ERR(crop_children(db,
                                     child_abspath,
+                                    child_depth,
                                     svn_depth_empty,
                                     notify_func,
                                     notify_baton,
@@ -322,6 +319,7 @@ svn_wc_crop_tree2(svn_wc_context_t *wc_c
   svn_wc__db_t *db = wc_ctx->db;
   svn_wc__db_status_t status;
   svn_wc__db_kind_t kind;
+  svn_depth_t dir_depth;
 
   /* Only makes sense when the depth is restrictive. */
   if (depth == svn_depth_infinity)
@@ -331,7 +329,7 @@ svn_wc_crop_tree2(svn_wc_context_t *wc_c
       _("Can only crop a working copy with a restrictive depth"));
 
   SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, &dir_depth, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL,
                                db, local_abspath,
@@ -374,7 +372,7 @@ svn_wc_crop_tree2(svn_wc_context_t *wc_c
         SVN_ERR_MALFUNCTION();
     }
 
-  return crop_children(db, local_abspath, depth,
+  return crop_children(db, local_abspath, dir_depth, depth,
                        notify_func, notify_baton,
                        cancel_func, cancel_baton, scratch_pool);
 }

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1102900&r1=1102899&r2=1102900&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Fri May 13 21:18:55 2011
@@ -529,22 +529,7 @@ WHERE wc_id = ?1 AND (local_relpath = ?2
 -- STMT_UPDATE_NODE_BASE_DEPTH
 UPDATE nodes SET depth = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
-
--- STMT_UPDATE_NODE_WORKING_DEPTH
-UPDATE nodes SET depth = ?3
-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_UPDATE_NODE_BASE_EXCLUDED
-UPDATE nodes SET presence = 'excluded', depth = NULL
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
-
--- STMT_UPDATE_NODE_WORKING_EXCLUDED
-UPDATE nodes SET presence = 'excluded', depth = NULL
-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 kind='dir'
 
 -- STMT_UPDATE_NODE_BASE_PRESENCE
 UPDATE nodes SET presence = ?3

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1102900&r1=1102899&r2=1102900&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri May 13 21:18:55 2011
@@ -5938,51 +5938,48 @@ svn_wc__db_temp_op_remove_working(svn_wc
   return SVN_NO_ERROR;
 }
 
+/* Baton for db_op_set_base_depth */
+struct set_base_depth_baton_t
+{
+  svn_depth_t depth;
+};
 
 static svn_error_t *
-update_depth_values(svn_wc__db_t *db,
-                    const char *local_abspath,
-                    svn_wc__db_wcroot_t *wcroot,
-                    const char *local_relpath,
-                    svn_depth_t depth,
-                    apr_pool_t *scratch_pool)
+db_op_set_base_depth(void *baton,
+                     svn_wc__db_wcroot_t *wcroot,
+                     const char *local_relpath,
+                     apr_pool_t *scratch_pool)
 {
-  svn_boolean_t excluded = (depth == svn_depth_exclude);
+  struct set_base_depth_baton_t *sbd = baton;
   svn_sqlite__stmt_t *stmt;
+  int affected_rows;
 
   /* Flush any entries before we start monkeying the database.  */
-  SVN_ERR(flush_entries(wcroot, local_abspath, scratch_pool));
-
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    excluded
-                                      ? STMT_UPDATE_NODE_BASE_EXCLUDED
-                                      : STMT_UPDATE_NODE_BASE_DEPTH));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  if (!excluded)
-    SVN_ERR(svn_sqlite__bind_text(stmt, 3, svn_depth_to_word(depth)));
-  SVN_ERR(svn_sqlite__step_done(stmt));
+                                    STMT_UPDATE_NODE_BASE_DEPTH));
+  SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id, local_relpath,
+                                         svn_depth_to_word(sbd->depth)));
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    excluded
-                                      ? STMT_UPDATE_NODE_WORKING_EXCLUDED
-                                      : STMT_UPDATE_NODE_WORKING_DEPTH));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  if (!excluded)
-    SVN_ERR(svn_sqlite__bind_text(stmt, 3, svn_depth_to_word(depth)));
-  SVN_ERR(svn_sqlite__step_done(stmt));
+  if (affected_rows == 0)
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             "The node '%s' is not a committed directory",
+                             path_for_error_message(wcroot, local_relpath,
+                                                    scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 
 svn_error_t *
-svn_wc__db_temp_op_set_dir_depth(svn_wc__db_t *db,
-                                 const char *local_abspath,
-                                 svn_depth_t depth,
-                                  apr_pool_t *scratch_pool)
+svn_wc__db_op_set_base_depth(svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_depth_t depth,
+                             apr_pool_t *scratch_pool)
 {
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
+  struct set_base_depth_baton_t sbd;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(depth >= svn_depth_empty && depth <= svn_depth_infinity);
@@ -5993,9 +5990,12 @@ svn_wc__db_temp_op_set_dir_depth(svn_wc_
 
   /* ### We set depth on working and base to match entry behavior.
          Maybe these should be separated later? */
+  sbd.depth = depth;
 
-  SVN_ERR(update_depth_values(db, local_abspath, wcroot, local_relpath, depth,
-                              scratch_pool));
+  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, db_op_set_base_depth,
+                              &sbd, scratch_pool));
+
+  SVN_ERR(flush_entries(wcroot, local_abspath, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1102900&r1=1102899&r2=1102900&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Fri May 13 21:18:55 2011
@@ -860,17 +860,6 @@ svn_wc__db_base_get_lock_tokens_recursiv
                                           apr_pool_t *result_pool,
                                           apr_pool_t *scratch_pool);
 
-/* ### how to handle depth? empty != absent. thus, record depth on each
-   ### directory? empty, files, immediates, infinity. recording depth
-   ### doesn't seem to be part of BASE, but instructions on how to maintain
-   ### the BASE/WORKING/ACTUAL trees. are there other instructional items?
-
-   ### BH: We use depth as a partial incomplete marker on directories. If
-   ### depth < svn_depth_infinity, the directory can miss entries that fall
-   ### out of the scope marked by the depth. (There can still be explicitly
-   ### pulled in targets)
-*/
-
 /* ### anything else needed for maintaining the BASE tree? */
 
 
@@ -2777,13 +2766,15 @@ svn_wc__db_temp_op_remove_working(svn_wc
                                   const char *local_abspath,
                                   apr_pool_t *scratch_pool);
 
-/* Sets the depth of LOCAL_ABSPATH in its working copy to DEPTH
-   using DB. */
+/* Sets the depth of LOCAL_ABSPATH in its working copy to DEPTH using DB.
+
+   Returns SVN_ERR_WC_PATH_NOT_FOUND if LOCAL_ABSPATH is not a BASE directory
+ */
 svn_error_t *
-svn_wc__db_temp_op_set_dir_depth(svn_wc__db_t *db,
-                                 const char *local_abspath,
-                                 svn_depth_t depth,
-                                 apr_pool_t *scratch_pool);
+svn_wc__db_op_set_base_depth(svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_depth_t depth,
+                             apr_pool_t *scratch_pool);
 
 /* ### temp function. return the FORMAT for the directory LOCAL_ABSPATH.  */
 svn_error_t *