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/02/04 21:48:13 UTC

svn commit: r1442344 [23/39] - in /subversion/branches/fsfs-format7: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/fsfsfixer/fixer/ contrib/server-side/svncutter/ doc/...

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.h?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.h Mon Feb  4 20:48:05 2013
@@ -74,7 +74,7 @@ extern "C" {
    The pool that DB is allocated within (the "state" pool) is only used
    for a few, limited allocations to track each of the working copy roots
    that the DB is asked to operate upon. The memory usage on this pool
-   os O(# wcroots), which should normally be one or a few. Custom clients
+   is O(# wcroots), which should normally be one or a few. Custom clients
    which hold open structures over a significant period of time should
    pay particular attention to the number of roots touched, and the
    resulting impact on memory consumption (which should still be minimal).
@@ -213,7 +213,7 @@ typedef struct svn_wc__db_lock_t {
 
 
 /*
-  @defgroup svn_wc__db_admin  General administractive functions
+  @defgroup svn_wc__db_admin  General administrative functions
   @{
 */
 
@@ -229,11 +229,12 @@ typedef struct svn_wc__db_lock_t {
    the administrative operation. It should live at least as long as the
    RESULT_POOL parameter.
 
-   When AUTO_UPGRADE is TRUE, then the working copy databases will be
-   upgraded when possible (when an old database is found/detected during
-   the operation of a wc_db API). If it is detected that a manual upgrade is
-   required, then SVN_ERR_WC_UPGRADE_REQUIRED will be returned from that API.
-   Passing FALSE will allow a bare minimum of APIs to function (most notably,
+   When OPEN_WITHOUT_UPGRADE is TRUE, then the working copy databases will
+   be opened even when an old database format is found/detected during
+   the operation of a wc_db API). If open_without_upgrade is FALSE and an
+   upgrade is required, then SVN_ERR_WC_UPGRADE_REQUIRED will be returned
+   from that API.
+   Passing TRUE will allow a bare minimum of APIs to function (most notably,
    the temp_get_format() function will always return a value) since most of
    these APIs expect a current-format database to be present.
 
@@ -257,7 +258,7 @@ typedef struct svn_wc__db_lock_t {
 svn_error_t *
 svn_wc__db_open(svn_wc__db_t **db,
                 svn_config_t *config,
-                svn_boolean_t auto_upgrade,
+                svn_boolean_t open_without_upgrade,
                 svn_boolean_t enforce_empty_wq,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool);
@@ -315,6 +316,9 @@ svn_wc__db_init(svn_wc__db_t *db,
 
    LOCAL_RELPATH will be allocated in RESULT_POOL. All other (temporary)
    allocations will be made in SCRATCH_POOL.
+
+   This function is available when DB is opened with the OPEN_WITHOUT_UPGRADE
+   option.
 */
 svn_error_t *
 svn_wc__db_to_relpath(const char **local_relpath,
@@ -333,7 +337,10 @@ svn_wc__db_to_relpath(const char **local
 
    LOCAL_ABSPATH will be allocated in RESULT_POOL. All other (temporary)
    allocations will be made in SCRATCH_POOL.
-*/
+
+   This function is available when DB is opened with the OPEN_WITHOUT_UPGRADE
+   option.
+ */
 svn_error_t *
 svn_wc__db_from_relpath(const char **local_abspath,
                         svn_wc__db_t *db,
@@ -343,6 +350,9 @@ svn_wc__db_from_relpath(const char **loc
                         apr_pool_t *scratch_pool);
 
 /* Compute the working copy root WCROOT_ABSPATH for WRI_ABSPATH using DB.
+
+   This function is available when DB is opened with the OPEN_WITHOUT_UPGRADE
+   option.
  */
 svn_error_t *
 svn_wc__db_get_wcroot(const char **wcroot_abspath,
@@ -686,6 +696,12 @@ svn_wc__db_base_add_not_present_node(svn
    If KEEP_AS_WORKING is TRUE, then the base tree is copied to higher
    layers as a copy of itself before deleting the BASE nodes.
 
+   If KEEP_AS_WORKING is FALSE, and QUEUE_DELETES is TRUE, also queue
+   workqueue items to delete all in-wc representations that aren't
+   shadowed by higher layers.
+   (With KEEP_AS_WORKING TRUE, this is a no-op, as everything is
+    automatically shadowed by the created copy)
+
    If NOT_PRESENT_REVISION specifies a valid revision a not-present
    node is installed in BASE node with kind NOT_PRESENT_KIND after
    deleting.
@@ -698,6 +714,7 @@ svn_error_t *
 svn_wc__db_base_remove(svn_wc__db_t *db,
                        const char *local_abspath,
                        svn_boolean_t keep_as_working,
+                       svn_boolean_t queue_deletes,
                        svn_revnum_t not_present_revision,
                        svn_skel_t *conflict,
                        svn_skel_t *work_items,
@@ -729,6 +746,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
      LOCK               NULL
 
      HAD_PROPS          FALSE
+     PROPS              NULL
 
      UPDATE_ROOT        FALSE
 
@@ -744,6 +762,11 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
    If TARGET is requested, and the node is NOT a symlink, then it will
    be set to NULL.
 
+   *PROPS maps "const char *" names to "const svn_string_t *" values.  If
+   the base node is capable of having properties but has none, set
+   *PROPS to an empty hash.  If its status is such that it cannot have
+   properties, set *PROPS to NULL.
+
    If UPDATE_ROOT is requested, set it to TRUE if the node should only
    be updated when it is the root of an update (e.g. file externals).
 
@@ -765,6 +788,7 @@ svn_wc__db_base_get_info(svn_wc__db_stat
                          const char **target,
                          svn_wc__db_lock_t **lock,
                          svn_boolean_t *had_props,
+                         apr_hash_t **props,
                          svn_boolean_t *update_root,
                          svn_wc__db_t *db,
                          const char *local_abspath,
@@ -800,7 +824,8 @@ svn_wc__db_base_get_children_info(apr_ha
    *PROPS maps "const char *" names to "const svn_string_t *" values.
    If the node has no properties, set *PROPS to an empty hash.
    *PROPS will never be set to NULL.
-   If the node is not present in the BASE tree, return an error.
+   If the node is not present in the BASE tree (with presence 'normal'
+   or 'incomplete'), return an error.
    Allocate *PROPS and its keys and values in RESULT_POOL.
 */
 svn_error_t *
@@ -986,13 +1011,11 @@ svn_wc__db_pristine_get_sha1(const svn_c
                              apr_pool_t *scratch_pool);
 
 
-/* If necessary transfers the PRISTINE file of SRC_LOCAL_ABSPATH to the
-   working copy identified by DST_WRI_ABSPATH. If CHECKSUM is not NULL, use
-   CHECKSUM to identify which pristine file to transfer. */
+/* If necessary transfers the PRISTINE files of the tree rooted at
+   SRC_LOCAL_ABSPATH to the working copy identified by DST_WRI_ABSPATH. */
 svn_error_t *
 svn_wc__db_pristine_transfer(svn_wc__db_t *db,
                              const char *src_local_abspath,
-                             const svn_checksum_t *checksum,
                              const char *dst_wri_abspath,
                              svn_cancel_func_t cancel_func,
                              void *cancel_baton,
@@ -1150,7 +1173,7 @@ svn_wc__db_external_remove(svn_wc__db_t 
 
    When KIND is requested then the value will be set to the kind of external.
 
-   If DEFININING_ABSPATH is requested, then the value will be set to the
+   If DEFINING_ABSPATH is requested, then the value will be set to the
    absolute path of the directory which originally defined the external.
    (The path with the svn:externals property)
 
@@ -1284,7 +1307,7 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
  * of SRC_ABSPATH (so SRC_ABSPATH must be an op_root) to dst_abspaths
  * parents layer.
  *
- * This operation is recursive. It copies all the descandants at the lower
+ * This operation is recursive. It copies all the descendants at the lower
  * layer and adds base-deleted nodes on dst_abspath layer to mark these nodes
  * properly deleted.
  *
@@ -1370,31 +1393,37 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t 
 
 /* ### add a new versioned directory. a list of children is NOT passed
    ### since they are added in future, distinct calls to db_op_add_*.
-   ### this is freshly added, so it has no properties.  */
+   PROPS gives the properties; empty or NULL means none. */
 /* ### do we need a CONFLICTS param?  */
 svn_error_t *
 svn_wc__db_op_add_directory(svn_wc__db_t *db,
                             const char *local_abspath,
+                            const apr_hash_t *props,
                             const svn_skel_t *work_items,
                             apr_pool_t *scratch_pool);
 
 
-/* ### as a new file, there are no properties. this file has no "pristine"
+/* Add a file.
+   PROPS gives the properties; empty or NULL means none.
+   ### this file has no "pristine"
    ### contents, so a checksum [reference] is not required.  */
 /* ### do we need a CONFLICTS param?  */
 svn_error_t *
 svn_wc__db_op_add_file(svn_wc__db_t *db,
                        const char *local_abspath,
+                       const apr_hash_t *props,
                        const svn_skel_t *work_items,
                        apr_pool_t *scratch_pool);
 
 
-/* ### newly added symlinks have no properties.  */
+/* Add a symlink.
+   PROPS gives the properties; empty or NULL means none. */
 /* ### do we need a CONFLICTS param?  */
 svn_error_t *
 svn_wc__db_op_add_symlink(svn_wc__db_t *db,
                           const char *local_abspath,
                           const char *target,
+                          const apr_hash_t *props,
                           const svn_skel_t *work_items,
                           apr_pool_t *scratch_pool);
 
@@ -1409,8 +1438,8 @@ svn_wc__db_op_add_symlink(svn_wc__db_t *
    If PROPS is NULL, set the properties to be the same as the pristine
    properties.
 
-   CONFLICT is used to register a conflict on this node at the same time
-   the properties are changed.
+   If CONFLICT is not NULL, it is used to register a conflict on this
+   node at the same time the properties are changed.
 
    WORK_ITEMS are inserted into the work queue, as additional things that
    need to be completed before the working copy is stable.
@@ -1437,42 +1466,6 @@ svn_wc__db_op_set_props(svn_wc__db_t *db
                         const svn_skel_t *work_items,
                         apr_pool_t *scratch_pool);
 
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-/* ### Set the properties of the node LOCAL_ABSPATH in the BASE tree to PROPS.
-   ###
-   ### This function should not exist because properties should be stored
-   ### onto the BASE node at construction time, in a single atomic operation.
-   ###
-   ### PROPS maps "const char *" names to "const svn_string_t *" values.
-   ### To specify no properties, PROPS must be an empty hash, not NULL.
-   ### If the node is not present, SVN_ERR_WC_PATH_NOT_FOUND is returned.
-*/
-svn_error_t *
-svn_wc__db_temp_base_set_props(svn_wc__db_t *db,
-                               const char *local_abspath,
-                               const apr_hash_t *props,
-                               apr_pool_t *scratch_pool);
-
-
-/* ### Set the properties of the node LOCAL_ABSPATH in the WORKING tree
-   ### to PROPS.
-   ###
-   ### This function should not exist because properties should be stored
-   ### onto the WORKING node at construction time, in a single atomic
-   ### operation.
-   ###
-   ### PROPS maps "const char *" names to "const svn_string_t *" values.
-   ### To specify no properties, PROPS must be an empty hash, not NULL.
-   ### If the node is not present, SVN_ERR_WC_PATH_NOT_FOUND is returned.
-*/
-svn_error_t *
-svn_wc__db_temp_working_set_props(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  const apr_hash_t *props,
-                                  apr_pool_t *scratch_pool);
-#endif
-
 /* Mark LOCAL_ABSPATH, and all children, for deletion.
  *
  * This function removes the file externals (and if DELETE_DIR_EXTERNALS is
@@ -1723,7 +1716,7 @@ svn_wc__db_revert_list_done(svn_wc__db_t
      LOCK                    NULL
 
      RECORDED_SIZE           SVN_INVALID_FILESIZE
-     RECORDED_MOD_TIME       0
+     RECORDED_TIME       0
 
      CHANGELIST              NULL
      CONFLICTED              FALSE
@@ -1807,7 +1800,7 @@ svn_wc__db_revert_list_done(svn_wc__db_t
    If HAD_PROPS is requested and the node has pristine props, the value will
    be set to TRUE.
 
-   If PROP_MODS is requested and the node has property modification the value
+   If PROPS_MOD is requested and the node has property modification the value
    will be set to TRUE.
 
    ### add information about the need to scan upwards to get a complete
@@ -1818,7 +1811,7 @@ svn_wc__db_revert_list_done(svn_wc__db_t
    ### the TEXT_MOD may become an enumerated value at some point to
    ### indicate different states of knowledge about text modifications.
    ### for example, an "svn edit" command in the future might set a
-   ### flag indicating adminstratively-defined modification. and/or we
+   ### flag indicating administratively-defined modification. and/or we
    ### might have a status indicating that we saw it was modified while
    ### performing a filesystem traversal.
 
@@ -1875,7 +1868,7 @@ svn_wc__db_read_info(svn_wc__db_status_t
 
                      /* Recorded for files present in the working copy */
                      svn_filesize_t *recorded_size,
-                     apr_time_t *recorded_mod_time,
+                     apr_time_t *recorded_time,
 
                      /* From ACTUAL */
                      const char **changelist,
@@ -1911,7 +1904,7 @@ struct svn_wc__db_info_t {
   svn_depth_t depth;
 
   svn_filesize_t recorded_size;
-  apr_time_t recorded_mod_time;
+  apr_time_t recorded_time;
 
   const char *changelist;
   svn_boolean_t conflicted;
@@ -1975,6 +1968,11 @@ struct svn_wc__db_walker_info_t {
    calling svn_wc__db_read_info().
 
    (All other information (like original_*) can be obtained via other apis).
+
+   *PROPS maps "const char *" names to "const svn_string_t *" values.  If
+   the pristine node is capable of having properties but has none, set
+   *PROPS to an empty hash.  If its status is such that it cannot have
+   properties, set *PROPS to NULL.
  */
 svn_error_t *
 svn_wc__db_read_pristine_info(svn_wc__db_status_t *status,
@@ -1986,6 +1984,7 @@ svn_wc__db_read_pristine_info(svn_wc__db
                               const svn_checksum_t **checksum, /* files only */
                               const char **target, /* symlinks only */
                               svn_boolean_t *had_props,
+                              apr_hash_t **props,
                               svn_wc__db_t *db,
                               const char *local_abspath,
                               apr_pool_t *result_pool,
@@ -2013,7 +2012,7 @@ svn_wc__db_read_node_install_info(const 
                                   apr_pool_t *scratch_pool);
 
 /* Return in *NODES a hash mapping name->struct svn_wc__db_walker_info_t for
-   the children of DIR_ABSPATH. "name" is the child's name relatve to
+   the children of DIR_ABSPATH. "name" is the child's name relative to
    DIR_ABSPATH, not an absolute path. */
 svn_error_t *
 svn_wc__db_read_children_walker_info(apr_hash_t **nodes,
@@ -2057,11 +2056,8 @@ svn_wc__db_read_props(apr_hash_t **props
  * a hash table mapping <tt>char *</tt> names onto svn_string_t *
  * values for any properties of child nodes of LOCAL_ABSPATH (up to DEPTH).
  *
- * If BASE_PROPS is FALSE, read the properties from the WORKING layer (highest
- * op_depth).
- *
- * If BASE_PROPS is FALSE and, PRISTINE is TRUE, the local modifications will
- * be suppressed. If PRISTINE is FALSE, local modifications will be visible.
+ * If PRISTINE is FALSE, read the properties from the WORKING layer (highest
+ * op_depth); if PRISTINE is FALSE, local modifications will be visible.
  */
 svn_error_t *
 svn_wc__db_read_props_streamily(svn_wc__db_t *db,
@@ -2096,14 +2092,19 @@ svn_wc__db_read_pristine_props(apr_hash_
 
 
 /**
- * Set @a *inherited_props to a depth-first ordered array of
+ * Set @a *iprops to a depth-first ordered array of
  * #svn_prop_inherited_item_t * structures representing the properties
  * inherited by @a local_abspath from the ACTUAL tree above
  * @a local_abspath (looking through to the WORKING or BASE tree as
  * required), up to and including the root of the working copy and
  * any cached inherited properties inherited by the root.
  *
- * Allocate @a *inherited_props in @a result_pool.  Use @a scratch_pool
+ * The #svn_prop_inherited_item_t->path_or_url members of the
+ * #svn_prop_inherited_item_t * structures in @a *iprops are
+ * paths relative to the repository root URL for cached inherited
+ * properties and absolute working copy paths otherwise.
+ *
+ * Allocate @a *iprops in @a result_pool.  Use @a scratch_pool
  * for temporary allocations.
  */
 svn_error_t *
@@ -2171,7 +2172,7 @@ svn_wc__db_prop_retrieve_recursive(apr_h
    Return every path that refers to a child of the working node at
    LOCAL_ABSPATH.  Do not include a path just because it was a child of a
    deleted directory that existed at LOCAL_ABSPATH if that directory is now
-   sheduled to be replaced by the working node at LOCAL_ABSPATH.
+   scheduled to be replaced by the working node at LOCAL_ABSPATH.
 
    Allocate *CHILDREN in RESULT_POOL and do temporary allocations in
    SCRATCH_POOL.
@@ -2302,23 +2303,28 @@ svn_wc__db_node_check_replace(svn_boolea
    ### changelist usage -- we may already assume the list fits in memory.
 */
 
-/* Checks if LOCAL_ABSPATH has a parent directory that knows about its
- * existance. Set *IS_ROOT to FALSE if a parent is found, and to TRUE
- * if there is no such parent.
+/* The DB-private version of svn_wc__is_wcroot(), which see.
  */
 svn_error_t *
-svn_wc__db_is_wcroot(svn_boolean_t *is_root,
+svn_wc__db_is_wcroot(svn_boolean_t *is_wcroot,
                      svn_wc__db_t *db,
                      const char *local_abspath,
                      apr_pool_t *scratch_pool);
 
-/* Checks if LOCAL_ABSPATH is a working copy root, switched and a directory.
-   With these answers we can answer all 'is anchor' questions that we need for
-   the different ra operations with just a single sqlite transaction and
-   filestat.
+/* Check whether a node is a working copy root and/or switched.
+
+   If LOCAL_ABSPATH is the root of a working copy, set *IS_WC_ROOT to TRUE,
+   otherwise to FALSE.
+
+   If LOCAL_ABSPATH is switched against its parent in the same working copy
+   set *IS_SWITCHED to TRUE, otherwise to FALSE.
 
-   All output arguments can be null to specify that the result is not
-   interesting to the caller
+   If KIND is not null, set *KIND to the node type of LOCAL_ABSPATH.
+
+   Any of the output arguments can be null to specify that the result is not
+   interesting to the caller.
+
+   Use SCRATCH_POOL for temporary allocations.
  */
 svn_error_t *
 svn_wc__db_is_switched(svn_boolean_t *is_wcroot,
@@ -2373,7 +2379,7 @@ svn_wc__db_global_relocate(svn_wc__db_t 
 
    CHANGED_REVISION is the new 'last changed' revision. If the node is
    modified its value is equivalent to NEW_REVISION, but in case of a
-   decendant of a copy/move it can be an older revision.
+   descendant of a copy/move it can be an older revision.
 
    CHANGED_DATE is the (server-side) date of CHANGED_REVISION. It may be 0 if
    the revprop is missing on the revision.
@@ -2496,23 +2502,23 @@ svn_wc__db_op_bump_revisions_post_update
                                          apr_pool_t *scratch_pool);
 
 
-/* Record the TRANSLATED_SIZE and LAST_MOD_TIME for a versioned node.
+/* Record the RECORDED_SIZE and RECORDED_TIME for a versioned node.
 
    This function will record the information within the WORKING node,
    if present, or within the BASE tree. If neither node is present, then
    SVN_ERR_WC_PATH_NOT_FOUND will be returned.
 
-   TRANSLATED_SIZE may be SVN_INVALID_FILESIZE, which will be recorded
+   RECORDED_SIZE may be SVN_INVALID_FILESIZE, which will be recorded
    as such, implying "unknown size".
 
-   LAST_MOD_TIME may be 0, which will be recorded as such, implying
+   RECORDED_TIME may be 0, which will be recorded as such, implying
    "unknown last mod time".
 */
 svn_error_t *
 svn_wc__db_global_record_fileinfo(svn_wc__db_t *db,
                                   const char *local_abspath,
-                                  svn_filesize_t translated_size,
-                                  apr_time_t last_mod_time,
+                                  svn_filesize_t recorded_size,
+                                  apr_time_t recorded_time,
                                   apr_pool_t *scratch_pool);
 
 
@@ -2910,6 +2916,15 @@ svn_wc__db_wclock_obtain(svn_wc__db_t *d
                          svn_boolean_t steal_lock,
                          apr_pool_t *scratch_pool);
 
+/* Set LOCK_ABSPATH to the path of the the directory that owns the
+   lock on LOCAL_ABSPATH, or NULL, if LOCAL_ABSPATH is not locked. */
+svn_error_t*
+svn_wc__db_wclock_find_root(const char **lock_abspath,
+                            svn_wc__db_t *db,
+                            const char *local_abspath,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+
 /* Check if somebody has a wclock on LOCAL_ABSPATH */
 svn_error_t *
 svn_wc__db_wclocked(svn_boolean_t *locked,
@@ -3116,7 +3131,7 @@ svn_wc__db_get_not_present_descendants(c
  * Only nodes with op_depth zero and presence 'normal' or 'incomplete'
  * are considered, so that added, deleted or excluded nodes do not affect
  * the result.  If COMMITTED is TRUE, set *MIN_REVISION and *MAX_REVISION
- * to the lowest and highest comitted (i.e. "last changed") revision numbers,
+ * to the lowest and highest committed (i.e. "last changed") revision numbers,
  * respectively.
  *
  * Indicate in *IS_SPARSE_CHECKOUT whether any of the nodes within
@@ -3151,7 +3166,7 @@ svn_wc__db_revision_status(svn_revnum_t 
  * Only nodes with op_depth zero and presence 'normal' or 'incomplete'
  * are considered, so that added, deleted or excluded nodes do not affect
  * the result.  If COMMITTED is TRUE, set *MIN_REVISION and *MAX_REVISION
- * to the lowest and highest comitted (i.e. "last changed") revision numbers,
+ * to the lowest and highest committed (i.e. "last changed") revision numbers,
  * respectively. Use SCRATCH_POOL for temporary allocations.
  *
  * Either of MIN_REVISION and MAX_REVISION may be passed as NULL if
@@ -3247,8 +3262,8 @@ svn_wc__db_follow_moved_to(apr_array_hea
  * need to run as part of marking the conflict resolved. */
 svn_error_t *
 svn_wc__db_update_moved_away_conflict_victim(svn_skel_t **work_items,
-                                             const char *victim_abspath,
                                              svn_wc__db_t *db,
+                                             const char *victim_abspath,
                                              svn_wc_notify_func2_t notify_func,
                                              void *notify_baton,
                                              svn_cancel_func_t cancel_func,
@@ -3256,6 +3271,30 @@ svn_wc__db_update_moved_away_conflict_vi
                                              apr_pool_t *result_pool,
                                              apr_pool_t *scratch_pool);
 
+svn_error_t *
+svn_wc__db_base_moved_to(const char **moved_to_abspath,
+                         const char **moved_to_op_root_abspath,
+                         const char **op_root_abspath,
+                         svn_wc__db_t *db,
+                         const char *local_abspath,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool);
+                         
+/* Recover space from the database file for LOCAL_ABSPATH by running
+ * the "vacuum" command. */
+svn_error_t *
+svn_wc__db_vacuum(svn_wc__db_t *db,
+                  const char *local_abspath,
+                  apr_pool_t *scratch_pool);
+
+/* This raises move-edit tree-conflicts on any moves inside the
+   delete-edit conflict on LOCAL_ABSPATH. This is experimental: see
+   comment in resolve_conflict_on_node about combining with another
+   function. */
+svn_error_t *
+svn_wc__db_resolve_delete_raise_moved_away(svn_wc__db_t *db,
+                                           const char *local_abspath,
+                                           apr_pool_t *scratch_pool);
 /* @} */
 
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_pristine.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_pristine.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_pristine.c Mon Feb  4 20:48:05 2013
@@ -25,6 +25,7 @@
 
 #define SVN_WC__I_AM_WC_DB
 
+#include "svn_pools.h"
 #include "svn_dirent_uri.h"
 
 #include "wc.h"
@@ -143,43 +144,30 @@ svn_wc__db_pristine_get_future_path(cons
   return SVN_NO_ERROR;
 }
 
-/* Data for pristine_read_txn(). */
-typedef struct pristine_read_baton_t
-{
-  /* Where to put the result stream. */
-  svn_stream_t **contents;
-  /* The pristine text's SHA-1 checksum. */
-  const svn_checksum_t *sha1_checksum;
-  /* The path to the pristine file (within the pristine store). */
-  const char *pristine_abspath;
-
-  /* Pointer to where to place the size (if requested) */
-  svn_filesize_t *size;
-
-  /* The pool from which to allocate the result stream. */
-  apr_pool_t *result_pool;
-} pristine_read_baton_t;
-
-/* Set (*BATON->contents) to a readable stream from which the pristine text
- * identified by BATON->sha1_checksum can be read from the pristine store of
- * SDB.  If that text is not in the pristine store, return an error.
+/* Set *CONTENTS to a readable stream from which the pristine text
+ * identified by SHA1_CHECKSUM and PRISTINE_ABSPATH can be read from the
+ * pristine store of WCROOT.  If SIZE is not null, set *SIZE to the size
+ * in bytes of that text. If that text is not in the pristine store,
+ * return an error.
  *
  * Even if the pristine text is removed from the store while it is being
  * read, the stream will remain valid and readable until it is closed.
  *
- * Allocate the stream in BATON->result_pool.
+ * Allocate the stream in RESULT_POOL.
  *
  * This function expects to be executed inside a SQLite txn.
  *
  * Implements 'notes/wc-ng/pristine-store' section A-3(d).
- * Implements svn_sqlite__transaction_callback_t. */
+ */
 static svn_error_t *
-pristine_read_txn(void *baton,
+pristine_read_txn(svn_stream_t **contents,
+                  svn_filesize_t *size,
                   svn_wc__db_wcroot_t *wcroot,
-                  const char *local_relpath,
+                  const svn_checksum_t *sha1_checksum,
+                  const char *pristine_abspath,
+                  apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
 {
-  pristine_read_baton_t *b = baton;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
 
@@ -187,11 +175,11 @@ pristine_read_txn(void *baton,
    * of the file is not sufficient.) */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_SELECT_PRISTINE_SIZE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, b->sha1_checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
 
-  if (b->size)
-    *b->size = svn_sqlite__column_int64(stmt, 0);
+  if (size)
+    *size = svn_sqlite__column_int64(stmt, 0);
 
   SVN_ERR(svn_sqlite__reset(stmt));
   if (! have_row)
@@ -199,14 +187,14 @@ pristine_read_txn(void *baton,
       return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                                _("Pristine text '%s' not present"),
                                svn_checksum_to_cstring_display(
-                                 b->sha1_checksum, scratch_pool));
+                                 sha1_checksum, scratch_pool));
     }
 
   /* Open the file as a readable stream.  It will remain readable even when
    * deleted from disk; APR guarantees that on Windows as well as Unix. */
-  if (b->contents)
-    SVN_ERR(svn_stream_open_readonly(b->contents, b->pristine_abspath,
-                                     b->result_pool, scratch_pool));
+  if (contents)
+    SVN_ERR(svn_stream_open_readonly(contents, pristine_abspath,
+                                     result_pool, scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -221,7 +209,7 @@ svn_wc__db_pristine_read(svn_stream_t **
 {
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
-  pristine_read_baton_t b;
+  const char *pristine_abspath;
 
   SVN_ERR_ASSERT(contents != NULL);
   SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
@@ -240,15 +228,14 @@ svn_wc__db_pristine_read(svn_stream_t **
                               wri_abspath, scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
 
-  b.contents = contents;
-  b.sha1_checksum = sha1_checksum;
-  b.size = size;
-  b.result_pool = result_pool;
-  SVN_ERR(get_pristine_fname(&b.pristine_abspath, wcroot->abspath,
+  SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath,
                              sha1_checksum,
                              scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, pristine_read_txn, &b,
-                              scratch_pool));
+  SVN_WC__DB_WITH_TXN(
+    pristine_read_txn(contents, size,
+                      wcroot, sha1_checksum, pristine_abspath,
+                      result_pool, scratch_pool),
+    wcroot);
 
   return SVN_NO_ERROR;
 }
@@ -288,20 +275,6 @@ svn_wc__db_pristine_get_tempdir(const ch
 }
 
 
-/* Data for pristine_install_txn(). */
-typedef struct pristine_install_baton_t
-{
-  /* The path to the source file that is to be moved into place. */
-  const char *tempfile_abspath;
-  /* The target path for the file (within the pristine store). */
-  const char *pristine_abspath;
-  /* The pristine text's SHA-1 checksum. */
-  const svn_checksum_t *sha1_checksum;
-  /* The pristine text's MD-5 checksum. */
-  const svn_checksum_t *md5_checksum;
-} pristine_install_baton_t;
-
-
 /* Install the pristine text described by BATON into the pristine store of
  * SDB.  If it is already stored then just delete the new file
  * BATON->tempfile_abspath.
@@ -310,13 +283,19 @@ typedef struct pristine_install_baton_t
  * acquired a 'RESERVED' lock.
  *
  * Implements 'notes/wc-ng/pristine-store' section A-3(a).
- * Implements svn_sqlite__transaction_callback_t. */
+ */
 static svn_error_t *
-pristine_install_txn(void *baton,
-                     svn_sqlite__db_t *sdb,
+pristine_install_txn(svn_sqlite__db_t *sdb,
+                     /* The path to the source file that is to be moved into place. */
+                     const char *tempfile_abspath,
+                     /* The target path for the file (within the pristine store). */
+                     const char *pristine_abspath,
+                     /* The pristine text's SHA-1 checksum. */
+                     const svn_checksum_t *sha1_checksum,
+                     /* The pristine text's MD-5 checksum. */
+                     const svn_checksum_t *md5_checksum,
                      apr_pool_t *scratch_pool)
 {
-  pristine_install_baton_t *b = baton;
   apr_finfo_t finfo;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
@@ -325,7 +304,7 @@ pristine_install_txn(void *baton,
   /* If this pristine text is already present in the store, just keep it:
    * delete the new one and return. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, b->sha1_checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   SVN_ERR(svn_sqlite__reset(stmt));
   if (have_row)
@@ -335,30 +314,30 @@ pristine_install_txn(void *baton,
        * ### We could check much more. */
       {
         apr_finfo_t finfo1, finfo2;
-        SVN_ERR(svn_io_stat(&finfo1, b->tempfile_abspath, APR_FINFO_SIZE,
+        SVN_ERR(svn_io_stat(&finfo1, tempfile_abspath, APR_FINFO_SIZE,
                             scratch_pool));
-        SVN_ERR(svn_io_stat(&finfo2, b->pristine_abspath, APR_FINFO_SIZE,
+        SVN_ERR(svn_io_stat(&finfo2, pristine_abspath, APR_FINFO_SIZE,
                             scratch_pool));
         if (finfo1.size != finfo2.size)
           {
             return svn_error_createf(
               SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,
               _("New pristine text '%s' has different size: %ld versus %ld"),
-              svn_checksum_to_cstring_display(b->sha1_checksum, scratch_pool),
+              svn_checksum_to_cstring_display(sha1_checksum, scratch_pool),
               (long int)finfo1.size, (long int)finfo2.size);
           }
       }
 #endif
 
       /* Remove the temp file: it's already there */
-      SVN_ERR(svn_io_remove_file2(b->tempfile_abspath,
+      SVN_ERR(svn_io_remove_file2(tempfile_abspath,
                                   FALSE /* ignore_enoent */, scratch_pool));
       return SVN_NO_ERROR;
     }
 
   /* Move the file to its target location.  (If it is already there, it is
    * an orphan file and it doesn't matter if we overwrite it.) */
-  err = svn_io_file_rename(b->tempfile_abspath, b->pristine_abspath,
+  err = svn_io_file_rename(tempfile_abspath, pristine_abspath,
                            scratch_pool);
 
   /* Maybe the directory doesn't exist yet? */
@@ -366,7 +345,7 @@ pristine_install_txn(void *baton,
     {
       svn_error_t *err2;
 
-      err2 = svn_io_dir_make(svn_dirent_dirname(b->pristine_abspath,
+      err2 = svn_io_dir_make(svn_dirent_dirname(pristine_abspath,
                                                 scratch_pool),
                              APR_OS_DEFAULT, scratch_pool);
 
@@ -377,19 +356,19 @@ pristine_install_txn(void *baton,
         /* We could create a directory: retry install */
         svn_error_clear(err);
 
-      SVN_ERR(svn_io_file_rename(b->tempfile_abspath, b->pristine_abspath,
+      SVN_ERR(svn_io_file_rename(tempfile_abspath, pristine_abspath,
                            scratch_pool));
     }
   else
     SVN_ERR(err);
 
-  SVN_ERR(svn_io_stat(&finfo, b->pristine_abspath, APR_FINFO_SIZE,
+  SVN_ERR(svn_io_stat(&finfo, pristine_abspath, APR_FINFO_SIZE,
                       scratch_pool));
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                     STMT_INSERT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, b->sha1_checksum, scratch_pool));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, b->md5_checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
   SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size));
   SVN_ERR(svn_sqlite__insert(NULL, stmt));
 
@@ -407,7 +386,7 @@ svn_wc__db_pristine_install(svn_wc__db_t
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
   const char *wri_abspath;
-  struct pristine_install_baton_t b;
+  const char *pristine_abspath;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(tempfile_abspath));
   SVN_ERR_ASSERT(sha1_checksum != NULL);
@@ -429,19 +408,18 @@ svn_wc__db_pristine_install(svn_wc__db_t
                               wri_abspath, scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
 
-  b.tempfile_abspath = tempfile_abspath;
-  b.sha1_checksum = sha1_checksum;
-  b.md5_checksum = md5_checksum;
-
-  SVN_ERR(get_pristine_fname(&b.pristine_abspath, wcroot->abspath,
+  SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath,
                              sha1_checksum,
                              scratch_pool, scratch_pool));
 
   /* Ensure the SQL txn has at least a 'RESERVED' lock before we start looking
    * at the disk, to ensure no concurrent pristine install/delete txn. */
-  SVN_ERR(svn_sqlite__with_immediate_transaction(wcroot->sdb,
-                                                 pristine_install_txn, &b,
-                                                 scratch_pool));
+  SVN_SQLITE__WITH_IMMEDIATE_TXN(
+    pristine_install_txn(wcroot->sdb,
+                         tempfile_abspath, pristine_abspath,
+                         sha1_checksum, md5_checksum,
+                         scratch_pool),
+    wcroot->sdb);
 
   return SVN_NO_ERROR;
 }
@@ -523,172 +501,173 @@ svn_wc__db_pristine_get_sha1(const svn_c
   return svn_error_trace(svn_sqlite__reset(stmt));
 }
 
-/* Baton for pristine_transfer() */
-struct pristine_transfer_baton
-{
-  svn_wc__db_wcroot_t *src_wcroot;
-  svn_wc__db_wcroot_t *dst_wcroot;
-  svn_cancel_func_t cancel_func;
-  void * cancel_baton;
-
-  /* pristine install baton, filled from pristine_transfer() */
-  struct pristine_install_baton_t ib;
-};
-
-/* Transaction implementation of svn_wc__db_pristine_transfer().
-   Calls itself again to obtain locks in both working copies */
+/* Handle the moving of a pristine from SRC_WCROOT to DST_WCROOT. The existing
+   pristine in SRC_WCROOT is described by CHECKSUM, MD5_CHECKSUM and SIZE */
 static svn_error_t *
-pristine_transfer(void *baton, svn_wc__db_wcroot_t *wcroot,
-                  const char *local_relpath, apr_pool_t *scratch_pool)
+maybe_transfer_one_pristine(svn_wc__db_wcroot_t *src_wcroot,
+                            svn_wc__db_wcroot_t *dst_wcroot,
+                            const svn_checksum_t *checksum,
+                            const svn_checksum_t *md5_checksum,
+                            apr_int64_t size,
+                            svn_cancel_func_t cancel_func,
+                            void *cancel_baton,
+                            apr_pool_t *scratch_pool)
 {
-  struct pristine_transfer_baton *tb = baton;
+  const char *pristine_abspath;
   svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
+  svn_stream_t *src_stream;
+  svn_stream_t *dst_stream;
+  const char *tmp_abspath;
+  const char *src_abspath;
+  int affected_rows;
+  svn_error_t *err;
 
-  /* Is this the initial call or the recursive call? */
-  if (wcroot == tb->dst_wcroot)
-    {
-      /* The initial call: */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb,
+                                    STMT_INSERT_OR_IGNORE_PRISTINE));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 3, size));
 
-      /* Get all the info within a src wcroot lock */
-      SVN_ERR(svn_wc__db_with_txn(tb->src_wcroot, local_relpath,
-                                  pristine_transfer, tb, scratch_pool));
-
-      /* And do the final install, while we still have the dst lock */
-      if (tb->ib.tempfile_abspath)
-        SVN_ERR(pristine_install_txn(&(tb->ib), tb->dst_wcroot->sdb,
-                                     scratch_pool));
-      return SVN_NO_ERROR;
-    }
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
-  /* We have a lock on tb->dst_wcroot and tb->src_wcroot */
+  if (affected_rows == 0)
+    return SVN_NO_ERROR;
 
-  /* Get the right checksum if it wasn't passed */
-  if (!tb->ib.sha1_checksum)
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, tb->src_wcroot->sdb,
-                                        STMT_SELECT_NODE_INFO));
+  SVN_ERR(svn_stream_open_unique(&dst_stream, &tmp_abspath,
+                                 pristine_get_tempdir(dst_wcroot,
+                                                      scratch_pool,
+                                                      scratch_pool),
+                                 svn_io_file_del_on_pool_cleanup,
+                                 scratch_pool, scratch_pool));
 
-      SVN_ERR(svn_sqlite__bindf(stmt, "is",
-                                 tb->src_wcroot->wc_id, local_relpath));
+  SVN_ERR(get_pristine_fname(&src_abspath, src_wcroot->abspath, checksum,
+                             scratch_pool, scratch_pool));
 
-      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  SVN_ERR(svn_stream_open_readonly(&src_stream, src_abspath,
+                                   scratch_pool, scratch_pool));
 
-      if (have_row)
-        SVN_ERR(svn_sqlite__column_checksum(&(tb->ib.sha1_checksum), stmt, 6,
-                                            scratch_pool));
+  /* ### Should we verify the SHA1 or MD5 here, or is that too expensive? */
+  SVN_ERR(svn_stream_copy3(src_stream, dst_stream,
+                           cancel_func, cancel_baton,
+                           scratch_pool));
+
+  SVN_ERR(get_pristine_fname(&pristine_abspath, dst_wcroot->abspath, checksum,
+                             scratch_pool, scratch_pool));
+
+  /* Move the file to its target location.  (If it is already there, it is
+   * an orphan file and it doesn't matter if we overwrite it.) */
+  err = svn_io_file_rename(tmp_abspath, pristine_abspath, scratch_pool);
 
-      SVN_ERR(svn_sqlite__reset(stmt));
+  /* Maybe the directory doesn't exist yet? */
+  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+    {
+      svn_error_t *err2;
 
-      if (!tb->ib.sha1_checksum)
-        return SVN_NO_ERROR; /* Nothing to transfer */
+      err2 = svn_io_dir_make(svn_dirent_dirname(pristine_abspath,
+                                                scratch_pool),
+                             APR_OS_DEFAULT, scratch_pool);
+
+      if (err2)
+        /* Creating directory didn't work: Return all errors */
+        return svn_error_trace(svn_error_compose_create(err, err2));
+      else
+        /* We could create a directory: retry install */
+        svn_error_clear(err);
+
+      SVN_ERR(svn_io_file_rename(tmp_abspath, pristine_abspath, scratch_pool));
     }
+  else
+    SVN_ERR(err);
 
-  /* Check if we have the pristine in the destination wcroot */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, tb->dst_wcroot->sdb,
-                                    STMT_SELECT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, tb->ib.sha1_checksum,
-                                    scratch_pool));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  SVN_ERR(svn_sqlite__reset(stmt));
+  return SVN_NO_ERROR;
+}
 
-  /* Destination repository already has this pristine. We're done */
-  if (have_row)
-    return SVN_NO_ERROR;
+/* Transaction implementation of svn_wc__db_pristine_transfer().
+   We have a lock on DST_WCROOT.
+ */
+static svn_error_t *
+pristine_transfer_txn(svn_wc__db_wcroot_t *src_wcroot,
+                       svn_wc__db_wcroot_t *dst_wcroot,
+                       const char *src_relpath,
+                       svn_cancel_func_t cancel_func,
+                       void *cancel_baton,
+                       apr_pool_t *scratch_pool)
+{
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t got_row;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
-  /* Verify if the pristine actually exists and get the MD5 in one query */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, tb->src_wcroot->sdb,
-                                    STMT_SELECT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, tb->ib.sha1_checksum,
-                                    scratch_pool));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
+                                    STMT_SELECT_COPY_PRISTINES));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", src_wcroot->wc_id, src_relpath));
 
-  if (!have_row)
+  /* This obtains an sqlite read lock on src_wcroot */
+  SVN_ERR(svn_sqlite__step(&got_row, stmt));
+
+  while (got_row)
     {
-      return svn_error_createf(SVN_ERR_WC_DB_ERROR, svn_sqlite__reset(stmt),
-                               _("The pristine text with checksum '%s' was "
-                                 "not found"),
-                               svn_checksum_to_cstring_display(
-                                        tb->ib.sha1_checksum, scratch_pool));
+      const svn_checksum_t *checksum;
+      const svn_checksum_t *md5_checksum;
+      apr_int64_t size;
+      svn_error_t *err;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_sqlite__column_checksum(&checksum, stmt, 0, iterpool));
+      SVN_ERR(svn_sqlite__column_checksum(&md5_checksum, stmt, 1, iterpool));
+      size = svn_sqlite__column_int64(stmt, 2);
+
+      err = maybe_transfer_one_pristine(src_wcroot, dst_wcroot,
+                                        checksum, md5_checksum, size,
+                                        cancel_func, cancel_baton,
+                                        iterpool);
+
+      if (err)
+        return svn_error_trace(svn_error_compose_create(
+                                    err,
+                                    svn_sqlite__reset(stmt)));
+
+      SVN_ERR(svn_sqlite__step(&got_row, stmt));
     }
-  SVN_ERR(svn_sqlite__column_checksum(&(tb->ib.md5_checksum), stmt, 0,
-                                      scratch_pool));
   SVN_ERR(svn_sqlite__reset(stmt));
 
-  /* We now have read locks in both working copies, so we can safely copy the
-     file to the temp location of the destination working copy */
-  {
-    svn_stream_t *src_stream;
-    svn_stream_t *dst_stream;
-    const char *tmp_abspath;
-    const char *src_abspath;
-
-    SVN_ERR(svn_stream_open_unique(&dst_stream, &tmp_abspath,
-                                   pristine_get_tempdir(tb->dst_wcroot,
-                                                        scratch_pool,
-                                                        scratch_pool),
-                                   svn_io_file_del_on_pool_cleanup,
-                                   scratch_pool, scratch_pool));
+  svn_pool_destroy(iterpool);
 
-    SVN_ERR(get_pristine_fname(&src_abspath, tb->src_wcroot->abspath,
-                               tb->ib.sha1_checksum,
-                               scratch_pool, scratch_pool));
-
-    SVN_ERR(svn_stream_open_readonly(&src_stream, src_abspath,
-                                     scratch_pool, scratch_pool));
-
-    /* ### Should we verify the SHA1 or MD5 here, or is that too expensive? */
-    SVN_ERR(svn_stream_copy3(src_stream, dst_stream,
-                             tb->cancel_func, tb->cancel_baton,
-                             scratch_pool));
-
-    /* And now set the right information to install once we leave the
-       src transaction */
-
-    SVN_ERR(get_pristine_fname(&(tb->ib.pristine_abspath),
-                               tb->dst_wcroot->abspath,
-                               tb->ib.sha1_checksum,
-                               scratch_pool, scratch_pool));
-    tb->ib.tempfile_abspath = tmp_abspath;
-  }
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
 svn_wc__db_pristine_transfer(svn_wc__db_t *db,
                              const char *src_local_abspath,
-                             const svn_checksum_t *checksum,
                              const char *dst_wri_abspath,
                              svn_cancel_func_t cancel_func,
                              void *cancel_baton,
                              apr_pool_t *scratch_pool)
 {
-  const char *src_relpath;
-  const char *dst_relpath;
-  struct pristine_transfer_baton tb;
-  memset(&tb, 0, sizeof(tb));
+  svn_wc__db_wcroot_t *src_wcroot, *dst_wcroot;
+  const char *src_relpath, *dst_relpath;
 
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&tb.src_wcroot, &src_relpath,
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&src_wcroot, &src_relpath,
                                                 db, src_local_abspath,
                                                 scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(tb.src_wcroot);
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&tb.dst_wcroot, &dst_relpath,
+  VERIFY_USABLE_WCROOT(src_wcroot);
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&dst_wcroot, &dst_relpath,
                                                 db, dst_wri_abspath,
                                                 scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(tb.dst_wcroot);
+  VERIFY_USABLE_WCROOT(dst_wcroot);
 
-  if (tb.src_wcroot == tb.dst_wcroot
-      || tb.src_wcroot->sdb == tb.dst_wcroot->sdb)
+  if (src_wcroot == dst_wcroot
+      || src_wcroot->sdb == dst_wcroot->sdb)
     {
       return SVN_NO_ERROR; /* Nothing to transfer */
     }
 
-  tb.cancel_func = cancel_func;
-  tb.cancel_baton = cancel_baton;
+  SVN_WC__DB_WITH_TXN(
+    pristine_transfer_txn(src_wcroot, dst_wcroot, src_relpath,
+                          cancel_func, cancel_baton, scratch_pool),
+    dst_wcroot);
 
-  return svn_error_trace(svn_wc__db_with_txn(tb.dst_wcroot, src_relpath,
-                                             pristine_transfer, &tb,
-                                             scratch_pool));
+  return SVN_NO_ERROR;
 }
 
 
@@ -730,36 +709,27 @@ remove_file(const char *file_abspath,
   return SVN_NO_ERROR;
 }
 
-/* Data for pristine_remove_if_unreferenced_txn(). */
-typedef struct pristine_remove_baton_t
-{
-  svn_wc__db_wcroot_t *wcroot;
-  /* The pristine text's SHA-1 checksum. */
-  const svn_checksum_t *sha1_checksum;
-  /* The path to the pristine file (within the pristine store). */
-  const char *pristine_abspath;
-} pristine_remove_baton_t;
-
-/* If the pristine text referenced by BATON in SDB has a reference count of
+/* If the pristine text referenced by SHA1_CHECKSUM in WCROOT/SDB, whose path
+ * within the pristine store is PRISTINE_ABSPATH, has a reference count of
  * zero, delete it (both the database row and the disk file).
  *
  * This function expects to be executed inside a SQLite txn that has already
  * acquired a 'RESERVED' lock.
- *
- * Implements svn_sqlite__transaction_callback_t. */
+ */
 static svn_error_t *
-pristine_remove_if_unreferenced_txn(void *baton,
-                                    svn_sqlite__db_t *sdb,
+pristine_remove_if_unreferenced_txn(svn_sqlite__db_t *sdb,
+                                    svn_wc__db_wcroot_t *wcroot,
+                                    const svn_checksum_t *sha1_checksum,
+                                    const char *pristine_abspath,
                                     apr_pool_t *scratch_pool)
 {
-  pristine_remove_baton_t *b = baton;
   svn_sqlite__stmt_t *stmt;
   int affected_rows;
 
   /* Remove the DB row, if refcount is 0. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                     STMT_DELETE_PRISTINE_IF_UNREFERENCED));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, b->sha1_checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
   SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
   /* If we removed the DB row, then remove the file. */
@@ -774,7 +744,7 @@ pristine_remove_if_unreferenced_txn(void
       svn_boolean_t ignore_enoent = TRUE;
 #endif
 
-      SVN_ERR(remove_file(b->pristine_abspath, b->wcroot, ignore_enoent,
+      SVN_ERR(remove_file(pristine_abspath, wcroot, ignore_enoent,
                           scratch_pool));
     }
 
@@ -791,17 +761,17 @@ pristine_remove_if_unreferenced(svn_wc__
                                 const svn_checksum_t *sha1_checksum,
                                 apr_pool_t *scratch_pool)
 {
-  pristine_remove_baton_t b;
+  const char *pristine_abspath;
 
-  b.wcroot = wcroot;
-  b.sha1_checksum = sha1_checksum;
-  SVN_ERR(get_pristine_fname(&b.pristine_abspath, wcroot->abspath,
+  SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath,
                              sha1_checksum, scratch_pool, scratch_pool));
 
   /* Ensure the SQL txn has at least a 'RESERVED' lock before we start looking
    * at the disk, to ensure no concurrent pristine install/delete txn. */
-  SVN_ERR(svn_sqlite__with_immediate_transaction(
-    wcroot->sdb, pristine_remove_if_unreferenced_txn, &b, scratch_pool));
+  SVN_SQLITE__WITH_IMMEDIATE_TXN(
+    pristine_remove_if_unreferenced_txn(
+      wcroot->sdb, wcroot, sha1_checksum, pristine_abspath, scratch_pool),
+    wcroot->sdb);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_private.h?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_private.h Mon Feb  4 20:48:05 2013
@@ -38,13 +38,16 @@ struct svn_wc__db_t {
      to figure out where we should look for the corresponding datastore. */
   svn_config_t *config;
 
-  /* Should we attempt to automatically upgrade the database when it is
+  /* Should we fail with SVN_ERR_WC_UPGRADE_REQUIRED when it is
      opened, and found to be not-current?  */
-  svn_boolean_t auto_upgrade;
+  svn_boolean_t verify_format;
 
   /* Should we ensure the WORK_QUEUE is empty when a WCROOT is opened?  */
   svn_boolean_t enforce_empty_wq;
 
+  /* Should we open Sqlite databases EXCLUSIVE */
+  svn_boolean_t exclusive;
+
   /* Map a given working copy directory to its relevant data.
      const char *local_abspath -> svn_wc__db_wcroot_t *wcroot  */
   apr_hash_t *dir_data;
@@ -96,7 +99,7 @@ typedef struct svn_wc__db_wcroot_t {
      Typically just one or two locks maximum. */
   apr_array_header_t *owned_locks;
 
-  /* Map a working copy diretory to a cached adm_access baton.
+  /* Map a working copy directory to a cached adm_access baton.
      const char *local_abspath -> svn_wc_adm_access_t *adm_access */
   apr_hash_t *access_cache;
 
@@ -118,7 +121,7 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_
                              svn_sqlite__db_t *sdb,
                              apr_int64_t wc_id,
                              int format,
-                             svn_boolean_t auto_upgrade,
+                             svn_boolean_t verify_format,
                              svn_boolean_t enforce_empty_wq,
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool);
@@ -148,6 +151,19 @@ svn_wc__db_wcroot_parse_local_abspath(sv
 #define VERIFY_USABLE_WCROOT(wcroot)  SVN_ERR_ASSERT(               \
     (wcroot) != NULL && (wcroot)->format == SVN_WC__VERSION)
 
+/* Check if the WCROOT is usable for light db operations such as path
+   calculations */
+#define CHECK_MINIMAL_WCROOT(wcroot, abspath, scratch_pool)             \
+    do                                                                  \
+    {                                                                   \
+      if (wcroot == NULL)                                               \
+        return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,     \
+                    _("The node '%s' is not in a working copy."),       \
+                             svn_dirent_local_style(wri_abspath,        \
+                                                    scratch_pool));     \
+    }                                                                   \
+    while (0)
+
 /* Calculates the depth of the relpath below "" */
 APR_INLINE static int
 relpath_depth(const char *relpath)
@@ -226,18 +242,6 @@ svn_wc__db_read_info_internal(svn_wc__db
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool);
 
-/* Like svn_wc__db_scan_deletion(), but with WCROOT+LOCAL_RELPATH instead of
-   DB+LOCAL_ABSPATH, and outputting relpaths instead of abspaths. */
-svn_error_t *
-svn_wc__db_scan_deletion_internal(const char **base_del_relpath,
-                                  const char **moved_to_relpath,
-                                  const char **work_del_relpath,
-                                  const char **moved_to_op_root_relpath,
-                                  svn_wc__db_wcroot_t *wcroot,
-                                  const char *local_relpath,
-                                  apr_pool_t *result_pool,
-                                  apr_pool_t *scratch_pool);
-
 /* Like svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH instead of
    DB+LOCAL_ABSPATH and outputting REPOS_ID instead of URL+UUID. */
 svn_error_t *
@@ -254,6 +258,7 @@ svn_wc__db_base_get_info_internal(svn_wc
                                   const char **target,
                                   svn_wc__db_lock_t **lock,
                                   svn_boolean_t *had_props,
+                                  apr_hash_t **props,
                                   svn_boolean_t *update_root,
                                   svn_wc__db_wcroot_t *wcroot,
                                   const char *local_relpath,
@@ -262,7 +267,18 @@ svn_wc__db_base_get_info_internal(svn_wc
 
 /* Similar to svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH 
  * instead of DB+LOCAL_ABSPATH, an explicit op-depth of the node to get
- * information about, and outputting REPOS_ID instead of URL+UUID. */
+ * information about, and outputting REPOS_ID instead of URL+UUID, and
+ * without the LOCK or UPDATE_ROOT outputs.
+ *
+ * OR
+ *
+ * Similar to svn_wc__db_base_get_info_internal(), but taking an explicit
+ * op-depth OP_DEPTH of the node to get information about, and without the
+ * LOCK or UPDATE_ROOT outputs.
+ *
+ * ### [JAF] TODO: Harmonize svn_wc__db_base_get_info[_internal] with
+ * svn_wc__db_depth_get_info -- common API, common implementation.
+ */
 svn_error_t *
 svn_wc__db_depth_get_info(svn_wc__db_status_t *status,
                           svn_kind_t *kind,
@@ -276,6 +292,7 @@ svn_wc__db_depth_get_info(svn_wc__db_sta
                           const svn_checksum_t **checksum,
                           const char **target,
                           svn_boolean_t *had_props,
+                          apr_hash_t **props,
                           svn_wc__db_wcroot_t *wcroot,
                           const char *local_relpath,
                           int op_depth,
@@ -291,6 +308,14 @@ svn_wc__db_read_conflict_internal(svn_sk
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool);
 
+/* Like svn_wc__db_op_mark_conflict(), but with WCROOT+LOCAL_RELPATH instead of
+   DB+LOCAL_ABSPATH. */
+svn_error_t *
+svn_wc__db_mark_conflict_internal(svn_wc__db_wcroot_t *wcroot,
+                                  const char *local_relpath,
+                                  const svn_skel_t *conflict_skel,
+                                  apr_pool_t *scratch_pool);
+
 
 /* Transaction handling */
 
@@ -311,5 +336,97 @@ svn_wc__db_with_txn(svn_wc__db_wcroot_t 
                     void *cb_baton,
                     apr_pool_t *scratch_pool);
 
+/* Evaluate the expression EXPR within a transaction.
+ *
+ * Begin a transaction in WCROOT's DB; evaluate the expression EXPR, which would
+ * typically be a function call that does some work in DB; finally commit
+ * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
+ * the transaction.
+ */
+#define SVN_WC__DB_WITH_TXN(expr, wcroot) \
+  SVN_SQLITE__WITH_LOCK(expr, (wcroot)->sdb)
+
+
+/* Return CHILDREN mapping const char * names to svn_kind_t * for the
+   children of LOCAL_RELPATH at OP_DEPTH. */
+svn_error_t *
+svn_wc__db_get_children_op_depth(apr_hash_t **children,
+                                 svn_wc__db_wcroot_t *wcroot,
+                                 const char *local_relpath,
+                                 int op_depth,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool);
+
+
+/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH.
+
+   ### What about KIND and OP_DEPTH?  KIND ought to be redundant; I'm
+       discussing on dev@ whether we can let that be null for presence
+       == base-deleted.  OP_DEPTH is the op-depth of what, and why?
+       It is used to select the lowest working node higher than OP_DEPTH,
+       so, in terms of the API, OP_DEPTH means ...?
+
+   Given a wc:
+
+              0         1         2         3         4
+              normal
+   A          normal
+   A/B        normal              normal
+   A/B/C                          not-pres  normal
+   A/B/C/D                                            normal
+
+   That is checkout, delete A/B, copy a replacement A/B, delete copied
+   child A/B/C, add replacement A/B/C, add A/B/C/D.
+
+   Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
+   must extend the A/B deletion:
+
+              0         1         2         3         4
+              normal
+   A          normal
+   A/B        normal              normal
+   A/B/C      normal              not-pres  normal
+   A/B/C/D    normal              base-del            normal
+   A/B/C/D/E  normal              base-del
+
+   When adding a node if the parent has a higher working node then the
+   parent node is deleted (or replaced) and the delete must be extended
+   to cover new node.
+
+   In the example above A/B/C/D and A/B/C/D/E are the nodes that get
+   the extended delete, A/B/C is already deleted.
+ */
+svn_error_t *
+svn_wc__db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot,
+                                const char *local_relpath,
+                                svn_kind_t kind,
+                                int op_depth,
+                                apr_pool_t *scratch_pool);
+
+svn_error_t *
+svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
+                                 const char *local_relpath,
+                                 int op_depth,
+                                 apr_pool_t *scratch_pool);
+
+svn_error_t *
+svn_wc__db_op_depth_moved_to(const char **moved_to_relpath,
+                             const char **moved_to_op_root_relpath,
+                             const char **op_root_relpath,
+                             int op_depth,
+                             svn_wc__db_wcroot_t *wcroot,
+                             const char *local_relpath,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
+
+/* Do a post-drive revision bump for the moved-away destination for
+   any move sources under LOCAL_RELPATH.  This is called from within
+   the revision bump transaction after the tree at LOCAL_RELPATH has
+   been bumped. */
+svn_error_t *
+svn_wc__db_bump_moved_away(svn_wc__db_wcroot_t *wcroot,
+                           const char *local_relpath,
+                           svn_depth_t depth,
+                           apr_pool_t *scratch_pool);
 
 #endif /* WC_DB_PRIVATE_H */