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/29 16:32:09 UTC
svn commit: r1128881 - in /subversion/trunk/subversion: include/private/
libsvn_client/ libsvn_wc/
Author: rhuijben
Date: Sun May 29 14:32:09 2011
New Revision: 1128881
URL: http://svn.apache.org/viewvc?rev=1128881&view=rev
Log:
Add a new wc_db api which gathers all svn:externals properties and relevant
depths for an update/switch in a single transaction.
* subversion/include/private/svn_wc_private.h
(svn_wc__externals_gather_definitions): New function.
* subversion/libsvn_client/client.h
(svn_client__crawl_for_externals): Remove function.
(svn_client__gather_local_external_changes): Remove function.
* subversion/libsvn_client/externals.c
(externals_crawl_proplist_receiver,
svn_client__crawl_for_externals,
svn_client__gather_local_external_changes): Remove functions.
* subversion/libsvn_client/relocate.c
(includes): Add svn_wc_private.h
(svn_client_relocate2): Update caller.
* subversion/libsvn_client/switch.c
(switch_internal): Update caller.
* subversion/libsvn_client/update.c
(update_internal): Update caller.
* subversion/libsvn_wc/externals.c
(svn_wc__externals_gather_definitions): New function.
* subversion/libsvn_wc/wc-queries.sql
(STMT_SELECT_EXTERNAL_PROPERTIES): New query.
* subversion/libsvn_wc/wc_db.c
(svn_wc__db_externals_gather_definitions): New function.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_externals_gather_definitions): New function.
Modified:
subversion/trunk/subversion/include/private/svn_wc_private.h
subversion/trunk/subversion/libsvn_client/client.h
subversion/trunk/subversion/libsvn_client/externals.c
subversion/trunk/subversion/libsvn_client/relocate.c
subversion/trunk/subversion/libsvn_client/switch.c
subversion/trunk/subversion/libsvn_client/update.c
subversion/trunk/subversion/libsvn_wc/externals.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/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_wc_private.h?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_wc_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_wc_private.h Sun May 29 14:32:09 2011
@@ -184,6 +184,27 @@ svn_wc__external_remove(svn_wc_context_t
void *cancel_baton,
apr_pool_t *scratch_pool);
+/* Gather all svn:externals property values from the actual properties on
+ directories below LOCAL_ABSPATH as a mapping of const char *local_abspath
+ to const char * values.
+
+ Use DEPTH as how it would be used to limit the externals property results
+ on update. (So any depth < infinity will only read svn:externals on
+ LOCAL_ABSPATH itself)
+
+ If DEPTHS is not NULL, set *depths to an apr_hash_t* mapping the same
+ local_abspaths to the const char * ambient depth of the node.
+
+ Allocate the result in RESULT_POOL and perform temporary allocations in
+ SCRATCH_POOL. */
+svn_error_t *
+svn_wc__externals_gather_definitions(apr_hash_t **externals,
+ apr_hash_t **ambient_depths,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ svn_depth_t depth,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/** Set @a *tree_conflict to a newly allocated @c
* svn_wc_conflict_description_t structure describing the tree
Modified: subversion/trunk/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/client.h?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/client.h (original)
+++ subversion/trunk/subversion/libsvn_client/client.h Sun May 29 14:32:09 2011
@@ -970,36 +970,6 @@ svn_client__do_external_status(svn_clien
void *status_baton,
apr_pool_t *pool);
-/* Set *EXTERNALS_P to a hash mapping const char * local absolute
- paths to const svn_string_t * svn:externals property values, those
- found by crawling LOCAL_ABSPATH to DEPTH. */
-svn_error_t *
-svn_client__crawl_for_externals(apr_hash_t **externals_p,
- const char *local_abspath,
- svn_depth_t depth,
- svn_client_ctx_t *ctx,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
-/* Helper function to fix issue #2267,
- * "support svn:externals on locally added directories".
- *
- * Crawl all externals beneath ANCHOR_ABSPATH (this is cheap because we're
- * only crawling the WC DB itself). If there are externals within the
- * REQUESTED_DEPTH that weren't already picked up while we were crawling
- * the BASE tree, add them to the EXTERNALS_NEW hash with ambient depth
- * infinity. Facilitates populating externals in locally added directories.
- *
- * ### This is a bit of a hack. We should try to find a better solution
- * ### to this problem. */
-svn_error_t *
-svn_client__gather_local_external_changes(apr_hash_t *externals_new,
- apr_hash_t *ambient_depths,
- const char *anchor_abspath,
- svn_depth_t requested_depth,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool);
-
/* Baton type for svn_wc__external_info_gatherer(). */
typedef struct svn_client__external_func_baton_t
{
Modified: subversion/trunk/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/externals.c?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/externals.c (original)
+++ subversion/trunk/subversion/libsvn_client/externals.c Sun May 29 14:32:09 2011
@@ -1517,100 +1517,3 @@ svn_client__external_info_gatherer(void
}
-/* An implementation of svn_wc__proplist_receiver_t. Just squirrels away an
- svn:externals property value into BATON (which is an apr_hash_t *
- keyed on local absolute path). */
-static svn_error_t *
-externals_crawl_proplist_receiver(void *baton,
- const char *local_abspath,
- apr_hash_t *props,
- apr_pool_t *scratch_pool)
-{
- apr_hash_t *externals_hash = baton;
- const svn_string_t *propval;
-
- propval = apr_hash_get(props, SVN_PROP_EXTERNALS, APR_HASH_KEY_STRING);
-
- if (propval)
- {
- apr_pool_t *hash_pool = apr_hash_pool_get(externals_hash);
-
- apr_hash_set(externals_hash, apr_pstrdup(hash_pool, local_abspath),
- APR_HASH_KEY_STRING, svn_string_dup(propval, hash_pool));
- }
-
- return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_client__crawl_for_externals(apr_hash_t **externals_p,
- const char *local_abspath,
- svn_depth_t depth,
- svn_client_ctx_t *ctx,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- apr_hash_t *externals_hash = apr_hash_make(result_pool);
-
- SVN_ERR(svn_wc__prop_list_recursive(ctx->wc_ctx, local_abspath, NULL, depth,
- FALSE /* base_props */,
- FALSE /* pristine */,
- externals_crawl_proplist_receiver,
- externals_hash,
- ctx->cancel_func,
- ctx->cancel_baton,
- scratch_pool));
-
- *externals_p = externals_hash;
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_client__gather_local_external_changes(apr_hash_t *externals_new,
- apr_hash_t *ambient_depths,
- const char *anchor_abspath,
- svn_depth_t requested_depth,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
-{
- apr_hash_t *all_externals;
- apr_hash_index_t *hi;
-
- /* If there was no requested depth for this operation, use infinity.
- * svn_client__crawl_for_externals() doesn't like depth 'unknown'. */
- if (requested_depth == svn_depth_unknown)
- requested_depth = svn_depth_infinity;
-
- SVN_ERR(svn_client__crawl_for_externals(&all_externals, anchor_abspath,
- requested_depth, ctx, scratch_pool,
- scratch_pool));
-
- for (hi = apr_hash_first(scratch_pool, all_externals);
- hi;
- hi = apr_hash_next(hi))
- {
- const char *local_abspath = svn__apr_hash_index_key(hi);
- svn_string_t *propval = svn__apr_hash_index_val(hi);
- apr_pool_t *hash_pool = apr_hash_pool_get(externals_new);
-
- local_abspath = apr_pstrdup(hash_pool, local_abspath);
-
- /* Override existing pristine definitions */
- apr_hash_set(externals_new, local_abspath, APR_HASH_KEY_STRING,
- apr_pstrdup(hash_pool, propval->data));
-
- /* Make sure that when using ambient depths, there is a depth for
- every path */
- if (ambient_depths
- && !apr_hash_get(ambient_depths, local_abspath, APR_HASH_KEY_STRING))
- {
- apr_hash_set(ambient_depths, local_abspath, APR_HASH_KEY_STRING,
- svn_depth_to_word(svn_depth_infinity));
- }
- }
-
- return SVN_NO_ERROR;
-}
-
-
Modified: subversion/trunk/subversion/libsvn_client/relocate.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/relocate.c?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/relocate.c (original)
+++ subversion/trunk/subversion/libsvn_client/relocate.c Sun May 29 14:32:09 2011
@@ -35,6 +35,8 @@
#include "svn_path.h"
#include "client.h"
+#include "private/svn_wc_private.h"
+
#include "svn_private_config.h"
@@ -258,8 +260,10 @@ svn_client_relocate2(const char *wcroot_
/* Relocate externals, too (if any). */
- SVN_ERR(svn_client__crawl_for_externals(&externals_hash, local_abspath,
- svn_depth_infinity, ctx, pool, pool));
+ SVN_ERR(svn_wc__externals_gather_definitions(&externals_hash, NULL,
+ ctx->wc_ctx, local_abspath,
+ svn_depth_infinity,
+ pool, pool));
if (! apr_hash_count(externals_hash))
return SVN_NO_ERROR;
Modified: subversion/trunk/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/switch.c?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/switch.c (original)
+++ subversion/trunk/subversion/libsvn_client/switch.c Sun May 29 14:32:09 2011
@@ -287,14 +287,20 @@ switch_internal(svn_revnum_t *result_rev
the primary operation. */
if (SVN_DEPTH_IS_RECURSIVE(depth) && (! ignore_externals))
{
- SVN_ERR(svn_client__gather_local_external_changes(
- efb.externals_new, efb.ambient_depths, local_abspath,
- depth, ctx, pool));
-
- err = svn_client__handle_externals(efb.externals_old,
- efb.externals_new, efb.ambient_depths,
- source_root, local_abspath,
- depth, use_sleep, ctx, pool);
+ apr_hash_t *new_externals;
+ apr_hash_t *new_depths;
+ SVN_ERR(svn_wc__externals_gather_definitions(&new_externals,
+ &new_depths,
+ ctx->wc_ctx, local_abspath,
+ depth, pool, pool));
+
+ new_depths = apr_hash_overlay(pool, new_depths, efb.ambient_depths);
+ SVN_ERR(svn_client__handle_externals(efb.externals_old,
+ new_externals,
+ new_depths,
+ source_root, local_abspath,
+ depth, use_sleep,
+ ctx, pool));
}
/* Sleep to ensure timestamp integrity (we do this regardless of
Modified: subversion/trunk/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/update.c?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/update.c (original)
+++ subversion/trunk/subversion/libsvn_client/update.c Sun May 29 14:32:09 2011
@@ -432,12 +432,17 @@ update_internal(svn_revnum_t *result_rev
the primary operation. */
if (SVN_DEPTH_IS_RECURSIVE(depth) && (! ignore_externals))
{
- SVN_ERR(svn_client__gather_local_external_changes(
- efb.externals_new, efb.ambient_depths, local_abspath,
- depth, ctx, pool));
+ apr_hash_t *new_externals;
+ apr_hash_t *new_depths;
+ SVN_ERR(svn_wc__externals_gather_definitions(&new_externals,
+ &new_depths,
+ ctx->wc_ctx, local_abspath,
+ depth, pool, pool));
+
+ new_depths = apr_hash_overlay(pool, new_depths, efb.ambient_depths);
SVN_ERR(svn_client__handle_externals(efb.externals_old,
- efb.externals_new,
- efb.ambient_depths,
+ new_externals,
+ new_depths,
repos_root, local_abspath,
depth, use_sleep,
ctx, pool));
Modified: subversion/trunk/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/externals.c?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/externals.c (original)
+++ subversion/trunk/subversion/libsvn_wc/externals.c Sun May 29 14:32:09 2011
@@ -1225,3 +1225,54 @@ svn_wc__external_remove(svn_wc_context_t
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_wc__externals_gather_definitions(apr_hash_t **externals,
+ apr_hash_t **depths,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ svn_depth_t depth,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ if (depth == svn_depth_infinity
+ || depth == svn_depth_unknown)
+ {
+ return svn_error_return(
+ svn_wc__db_externals_gather_definitions(externals, depths,
+ wc_ctx->db, local_abspath,
+ result_pool, scratch_pool));
+ }
+ else
+ {
+ const svn_string_t *value;
+ *externals = apr_hash_make(result_pool);
+
+ local_abspath = apr_pstrdup(result_pool, local_abspath);
+
+ SVN_ERR(svn_wc_prop_get2(&value, wc_ctx, local_abspath,
+ SVN_PROP_EXTERNALS, result_pool, scratch_pool));
+
+ if (value)
+ apr_hash_set(*externals, local_abspath, APR_HASH_KEY_STRING,
+ value->data);
+
+ if (depths)
+ {
+ svn_depth_t node_depth;
+ *depths = apr_hash_make(result_pool);
+
+ SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, &node_depth, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ wc_ctx->db, local_abspath,
+ scratch_pool, scratch_pool));
+
+ apr_hash_set(*depths, local_abspath, APR_HASH_KEY_STRING,
+ svn_depth_to_word(node_depth));
+ }
+
+ return SVN_NO_ERROR;
+ }
+}
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Sun May 29 14:32:09 2011
@@ -919,6 +919,20 @@ WHERE wc_id = ?1 AND local_relpath = ?2
DELETE FROM externals
WHERE wc_id = ?1 AND local_relpath = ?2
+-- STMT_SELECT_EXTERNAL_PROPERTIES
+SELECT IFNULL((SELECT properties FROM actual_node a
+ WHERE a.wc_id = ?1 AND A.local_relpath = n.local_relpath),
+ properties),
+ local_relpath, depth
+FROM nodes n
+WHERE wc_id = ?1
+ AND (?2 = ''
+ OR local_relpath = ?2
+ OR (local_relpath > ?2 || '/' AND local_relpath < ?2 || '0'))
+ AND kind = 'dir' AND presence='normal'
+ AND op_depth=(SELECT MAX(op_depth) FROM nodes o
+ WHERE o.wc_id = ?1 AND o.local_relpath = n.local_relpath)
+
/* ------------------------------------------------------------------------- */
/* these are used in entries.c */
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Sun May 29 14:32:09 2011
@@ -3220,6 +3220,90 @@ svn_wc__db_externals_defined_below(apr_h
return svn_error_return(svn_sqlite__reset(stmt));
}
+svn_error_t *
+svn_wc__db_externals_gather_definitions(apr_hash_t **externals,
+ apr_hash_t **depths,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_wcroot_t *wcroot;
+ svn_sqlite__stmt_t *stmt;
+ const char *local_relpath;
+ svn_boolean_t have_row;
+ svn_error_t *err = NULL;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ 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, iterpool));
+ VERIFY_USABLE_WCROOT(wcroot);
+
+ *externals = apr_hash_make(result_pool);
+ if (depths != NULL)
+ *depths = apr_hash_make(result_pool);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_EXTERNAL_PROPERTIES));
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ while (have_row)
+ {
+ apr_hash_t *node_props;
+ const svn_string_t *external_value;
+
+ svn_pool_clear(iterpool);
+ err = svn_sqlite__column_properties(&node_props, stmt, 0, iterpool,
+ iterpool);
+
+ if (err)
+ break;
+
+ external_value = node_props
+ ? apr_hash_get(node_props, SVN_PROP_EXTERNALS,
+ APR_HASH_KEY_STRING)
+ : NULL;
+
+ if (external_value)
+ {
+ const char *node_abspath;
+ const char *node_relpath = svn_sqlite__column_text(stmt, 1, NULL);
+
+ node_abspath = svn_dirent_join(wcroot->abspath, node_relpath,
+ result_pool);
+
+ apr_hash_set(*externals, node_abspath,
+ APR_HASH_KEY_STRING,
+ apr_pstrdup(result_pool, external_value->data));
+
+ if (depths)
+ {
+ const char *depth_word = svn_sqlite__column_text(stmt, 2, NULL);
+ svn_depth_t depth = svn_depth_unknown;
+
+ if (depth_word)
+ depth = svn_depth_from_word(depth_word);
+
+ apr_hash_set(*depths, node_abspath,
+ APR_HASH_KEY_STRING,
+ svn_depth_to_word(depth)); /* Use static string */
+ }
+ }
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+
+ svn_pool_destroy(iterpool);
+
+ return svn_error_return(svn_error_compose_create(err,
+ svn_sqlite__reset(stmt)));
+}
+
/* Helper for svn_wc__db_op_copy to handle copying from one db to
another */
static svn_error_t *
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1128881&r1=1128880&r2=1128881&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Sun May 29 14:32:09 2011
@@ -1185,6 +1185,23 @@ svn_wc__db_externals_defined_below(apr_h
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Gather all svn:externals property values from the actual properties on
+ directories below LOCAL_ABSPATH as a mapping of const char *local_abspath
+ to const char * property values.
+
+ If DEPTHS is not NULL, set *depths to an apr_hash_t* mapping the same
+ local_abspaths to the const char * ambient depth of the node.
+
+ Allocate the result in RESULT_POOL and perform temporary allocations in
+ SCRATCH_POOL. */
+svn_error_t *
+svn_wc__db_externals_gather_definitions(apr_hash_t **externals,
+ apr_hash_t **depths,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* @} */
/* @defgroup svn_wc__db_op Operations on WORKING tree