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 2010/09/26 13:59:01 UTC
svn commit: r1001417 [4/7] - in /subversion/branches/performance: ./ build/
notes/ notes/http-and-webdav/ subversion/bindings/javahl/native/
subversion/bindings/javahl/tests/org/apache/subversion/javahl/
subversion/bindings/javahl/tests/org/tigris/subv...
Modified: subversion/branches/performance/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/wc_db.c?rev=1001417&r1=1001416&r2=1001417&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/wc_db.c Sun Sep 26 11:58:58 2010
@@ -111,7 +111,7 @@
#define LIKE_ESCAPE_CHAR "#"
/* Calculates the depth of the relpath below "" */
-APR_INLINE static int relpath_op_depth(const char *relpath)
+APR_INLINE static int relpath_depth(const char *relpath)
{
int n = 1;
if (*relpath == '\0')
@@ -274,6 +274,18 @@ escape_sqlite_like(const char * const st
return result;
}
+static const char *construct_like_arg(const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ if (local_relpath[0] == '\0')
+ return "%";
+
+ return apr_pstrcat(scratch_pool,
+ escape_sqlite_like(local_relpath, scratch_pool),
+ "/%", NULL);
+}
+
+
/* Returns in PRISTINE_ABSPATH a new string allocated from RESULT_POOL,
holding the local absolute path to the file location that is dedicated
@@ -608,6 +620,10 @@ scan_upwards_for_repos(apr_int64_t *repo
stmt, data_stmt,
current_relpath,
scratch_pool));
+ SVN_ERR(svn_sqlite__reset(data_stmt));
+#else
+ have_row = have_data_row;
+ stmt = data_stmt;
#endif
#endif
@@ -632,9 +648,6 @@ scan_upwards_for_repos(apr_int64_t *repo
svn_dirent_local_style(local_abspath, scratch_pool));
}
-#ifdef SVN_WC__NODES
- SVN_ERR(svn_sqlite__reset(data_stmt));
-#endif
return svn_error_compose_create(err, svn_sqlite__reset(stmt));
}
@@ -654,17 +667,11 @@ scan_upwards_for_repos(apr_int64_t *repo
NULL),
relpath_suffix,
result_pool);
-#ifdef SVN_WC__NODES
- SVN_ERR(svn_sqlite__reset(data_stmt));
-#endif
return svn_sqlite__reset(stmt);
}
-#ifdef SVN_WC__NODES
- SVN_ERR(svn_sqlite__reset(data_stmt));
-#endif
-#ifndef SVN_WC__NODES_ONLY
+
SVN_ERR(svn_sqlite__reset(stmt));
-#endif
+
if (*current_relpath == '\0')
{
/* We scanned all the way up, and did not find the information.
@@ -937,7 +944,14 @@ blank_iwb(insert_working_baton_t *piwb)
value, but... meh. We'll avoid them if ORIGINAL_REPOS_RELPATH==NULL. */
}
-/* */
+
+struct relpath_op_depth_t {
+ const char *local_relpath;
+ apr_int64_t op_depth;
+};
+
+/* Copy the row specified by BATON->(wc_id,local_relpath) from BASE to
+ * WORKING, changing its 'presence' and 'op_depth' to the values in BATON. */
static svn_error_t *
copy_working_from_base(void *baton,
svn_sqlite__db_t *sdb,
@@ -947,6 +961,10 @@ copy_working_from_base(void *baton,
svn_sqlite__stmt_t *stmt;
#ifdef SVN_WC__NODES
+ const char *like_arg;
+ svn_boolean_t have_row;
+ apr_array_header_t *nodes;
+ int i;
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
STMT_INSERT_WORKING_NODE_FROM_BASE));
@@ -956,6 +974,35 @@ copy_working_from_base(void *baton,
presence_map, piwb->presence));
SVN_ERR(svn_sqlite__insert(NULL, stmt));
+ /* Need to update the op_depth of all deleted children. A single
+ query can locate all the rows, but not update them, so we fall
+ back on one update per row. */
+ like_arg = construct_like_arg(piwb->local_relpath, scratch_pool);
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_SELECT_CHILDREN_OP_DEPTH_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", piwb->wc_id, like_arg));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ nodes = apr_array_make(scratch_pool, 10, sizeof(struct relpath_op_depth_t *));
+ while (have_row)
+ {
+ struct relpath_op_depth_t *rod = apr_palloc(scratch_pool, sizeof(*rod));
+ rod->local_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
+ rod->op_depth = svn_sqlite__column_int64(stmt, 1);
+ APR_ARRAY_PUSH(nodes, struct relpath_op_depth_t *) = rod;
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+ for (i = 0; i < nodes->nelts; ++i)
+ {
+ struct relpath_op_depth_t *rod
+ = APR_ARRAY_IDX(nodes, i, struct relpath_op_depth_t *);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPDATE_OP_DEPTH));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isii",
+ piwb->wc_id, rod->local_relpath, rod->op_depth,
+ piwb->op_depth));
+ SVN_ERR(svn_sqlite__update(NULL, stmt));
+ }
#endif
#ifndef SVN_WC__NODES_ONLY
@@ -973,12 +1020,15 @@ copy_working_from_base(void *baton,
}
-
+/* Insert WORKING rows for each (const char *) child name in CHILDREN,
+ whose parent directory is LOCAL_RELPATH. For each child, set
+ presence='incomplete', kind='unknown', op_depth=OP_DEPTH. */
static svn_error_t *
insert_incomplete_working_children(svn_sqlite__db_t *sdb,
apr_int64_t wc_id,
const char *local_relpath,
const apr_array_header_t *children,
+ apr_int64_t op_depth,
apr_pool_t *scratch_pool)
{
#ifndef SVN_WC__NODES_ONLY
@@ -1016,8 +1066,7 @@ insert_incomplete_working_children(svn_s
wc_id,
svn_relpath_join(local_relpath, name,
scratch_pool),
- (apr_int64_t) 2, /* ### op_depth
- non-THIS_DIR working */
+ op_depth,
local_relpath,
"incomplete", /* 8, presence */
"unknown")); /* 10, kind */
@@ -1042,7 +1091,6 @@ insert_working_node(void *baton,
#endif
#ifdef SVN_WC__NODES
svn_sqlite__stmt_t *stmt_node;
- apr_int64_t op_depth;
#endif
/* We cannot insert a WORKING_NODE row at the wcroot. */
@@ -1112,14 +1160,12 @@ insert_working_node(void *baton,
#endif
#ifdef SVN_WC__NODES
- op_depth = (parent_relpath == NULL) ? 1 /* THIS_DIR */
- : 2; /* immediate children */
SVN_ERR(svn_sqlite__get_statement(&stmt_node, sdb, STMT_INSERT_NODE));
SVN_ERR(svn_sqlite__bindf(stmt_node, "isisnnntstrisn"
"nnnn" /* properties translated_size last_mod_time dav_cache */
"s",
piwb->wc_id, piwb->local_relpath,
- op_depth,
+ piwb->op_depth,
parent_relpath,
presence_map, piwb->presence,
(piwb->kind == svn_wc__db_kind_dir)
@@ -1160,10 +1206,15 @@ insert_working_node(void *baton,
#endif
+ /* Insert incomplete children, if specified.
+ The children are part of the same op and so have the same op_depth.
+ (The only time we'd want a different depth is during a recursive
+ simple add, but we never insert children here during a simple add.) */
if (piwb->kind == svn_wc__db_kind_dir && piwb->children)
SVN_ERR(insert_incomplete_working_children(sdb, piwb->wc_id,
piwb->local_relpath,
piwb->children,
+ piwb->op_depth,
scratch_pool));
SVN_ERR(add_work_items(sdb, piwb->work_items, scratch_pool));
@@ -1234,6 +1285,9 @@ union_children(const apr_array_header_t
{
/* ### it would be nice to pre-size this hash table. */
apr_hash_t *names = apr_hash_make(scratch_pool);
+#ifdef SVN_WC__NODES
+ apr_hash_t *names_nodes = apr_hash_make(scratch_pool);
+#endif
apr_array_header_t *names_array;
/* All of the names get allocated in RESULT_POOL. */
@@ -1241,6 +1295,17 @@ union_children(const apr_array_header_t
sdb, wc_id, parent_relpath, result_pool));
SVN_ERR(add_children_to_hash(names, STMT_SELECT_WORKING_NODE_CHILDREN,
sdb, wc_id, parent_relpath, result_pool));
+#ifdef SVN_WC__NODES
+ SVN_ERR(add_children_to_hash(names_nodes, STMT_SELECT_BASE_NODE_CHILDREN_1,
+ sdb, wc_id, parent_relpath, result_pool));
+ SVN_ERR(add_children_to_hash(names_nodes, STMT_SELECT_WORKING_NODE_CHILDREN_1,
+ sdb, wc_id, parent_relpath, result_pool));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT(apr_hash_count(names) == apr_hash_count(names_nodes));
+#else
+ names = names_nodes;
+#endif
+#endif
SVN_ERR(svn_hash_keys(&names_array, names, result_pool));
*children = names_array;
@@ -1309,6 +1374,10 @@ gather_children(const apr_array_header_t
const char *local_relpath;
int base_count;
int working_count;
+#ifdef SVN_WC__NODES
+ int base_count_nodes, working_count_nodes;
+ const apr_array_header_t *children_nodes;
+#endif
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1324,17 +1393,47 @@ gather_children(const apr_array_header_t
directory in its repository.
### note "files". should redo count with subdirs included */
- return svn_error_return(single_table_children(
- children, STMT_SELECT_BASE_NODE_CHILDREN,
- 10 /* start_size */,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(single_table_children(children, STMT_SELECT_BASE_NODE_CHILDREN,
+ 10 /* start_size */,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(single_table_children(&children_nodes,
+ STMT_SELECT_BASE_NODE_CHILDREN_1,
+ 10 /* start_size */,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT((*children)->nelts == children_nodes->nelts);
+#else
+ *children = children_nodes;
+#endif
+#endif
+ return SVN_NO_ERROR;
}
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(count_children(&base_count, STMT_COUNT_BASE_NODE_CHILDREN,
pdh->wcroot->sdb, pdh->wcroot->wc_id, local_relpath));
SVN_ERR(count_children(&working_count, STMT_COUNT_WORKING_NODE_CHILDREN,
pdh->wcroot->sdb, pdh->wcroot->wc_id, local_relpath));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(count_children(&base_count_nodes, STMT_COUNT_BASE_NODE_CHILDREN_1,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(count_children(&working_count_nodes,
+ STMT_COUNT_WORKING_NODE_CHILDREN_1,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id, local_relpath));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT(base_count == base_count_nodes);
+ SVN_ERR_ASSERT(working_count == working_count_nodes);
+#else
+ base_count = base_count_nodes;
+ working_count = working_count_nodes;
+#endif
+#endif
if (base_count == 0)
{
@@ -1344,18 +1443,48 @@ gather_children(const apr_array_header_t
return SVN_NO_ERROR;
}
- return svn_error_return(single_table_children(
- children, STMT_SELECT_WORKING_NODE_CHILDREN,
- working_count,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(single_table_children(children, STMT_SELECT_WORKING_NODE_CHILDREN,
+ working_count,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(single_table_children(&children_nodes,
+ STMT_SELECT_WORKING_NODE_CHILDREN_1,
+ working_count,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT((*children)->nelts == children_nodes->nelts);
+#else
+ *children = children_nodes;
+#endif
+#endif
+ return SVN_NO_ERROR;
}
if (working_count == 0)
- return svn_error_return(single_table_children(
- children, STMT_SELECT_BASE_NODE_CHILDREN,
- base_count,
- pdh->wcroot->sdb, pdh->wcroot->wc_id,
- local_relpath, result_pool));
+ {
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(single_table_children(children, STMT_SELECT_BASE_NODE_CHILDREN,
+ base_count,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(single_table_children(&children_nodes,
+ STMT_SELECT_BASE_NODE_CHILDREN_1,
+ base_count,
+ pdh->wcroot->sdb, pdh->wcroot->wc_id,
+ local_relpath, result_pool));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT((*children)->nelts == children_nodes->nelts);
+#else
+ *children = children_nodes;
+#endif
+#endif
+ return SVN_NO_ERROR;
+ }
/* ### it would be nice to pass BASE_COUNT and WORKING_COUNT, but there is
### nothing union_children() can do with those. */
@@ -1460,15 +1589,34 @@ which_trees_exist(svn_boolean_t *base_ex
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
*base_exists = FALSE;
*working_exists = FALSE;
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
STMT_DETERMINE_TREE_FOR_RECORDING));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
-
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+ STMT_DETERMINE_TREE_FOR_RECORDING_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is", wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
+
if (have_row)
{
int value = svn_sqlite__column_int(stmt, 0);
@@ -1507,15 +1655,32 @@ prop_upgrade_trees(svn_boolean_t *base_e
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
*base_exists = FALSE;
*working_exists = FALSE;
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_PLAN_PROP_UPGRADE));
SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
-
SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+ STMT_PLAN_PROP_UPGRADE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "s", local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT(have_row == have_nodes_row);
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
/* During a property upgrade, there better be a row corresponding to
the provided LOCAL_RELPATH. We shouldn't even be here without a
query for available rows. */
@@ -2367,95 +2532,6 @@ svn_wc__db_base_get_info(svn_wc__db_stat
return svn_error_compose_create(err, svn_sqlite__reset(stmt));
}
-svn_error_t *
-svn_wc__db_base_get_info_from_parent(svn_wc__db_status_t *status,
- svn_wc__db_kind_t *kind,
- svn_revnum_t *revision,
- const char **repos_relpath,
- const char **repos_root_url,
- const char **repos_uuid,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_wc__db_pdh_t *pdh;
- const char *local_relpath;
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
- svn_error_t *err = SVN_NO_ERROR;
- const char *parent_abspath;
-
- SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
- parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-
- SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
- parent_abspath, svn_sqlite__mode_readonly,
- scratch_pool, scratch_pool));
- VERIFY_USABLE_PDH(pdh);
-
- local_relpath = svn_relpath_join(local_relpath,
- svn_dirent_basename(local_abspath, NULL),
- scratch_pool);
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
- STMT_SELECT_BASE_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
- if (have_row)
- {
- svn_wc__db_kind_t node_kind = svn_sqlite__column_token(stmt, 3,
- kind_map);
-
- if (kind)
- {
- *kind = node_kind;
- }
- if (status)
- {
- *status = svn_sqlite__column_token(stmt, 2, presence_map);
- }
- if (revision)
- {
- *revision = svn_sqlite__column_revnum(stmt, 4);
- }
- if (repos_relpath)
- {
- *repos_relpath = svn_sqlite__column_text(stmt, 1, result_pool);
- }
- if (repos_root_url || repos_uuid)
- {
- /* Fetch repository information via REPOS_ID. */
- if (svn_sqlite__column_is_null(stmt, 0))
- {
- if (repos_root_url)
- *repos_root_url = NULL;
- if (repos_uuid)
- *repos_uuid = NULL;
- }
- else
- {
- err = fetch_repos_info(repos_root_url, repos_uuid,
- pdh->wcroot->sdb,
- svn_sqlite__column_int64(stmt, 0),
- result_pool);
- }
- }
- }
- else
- {
- err = svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
- _("The node '%s' was not found."),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
- }
-
- /* Note: given the composition, no need to wrap for tracing. */
- return svn_error_compose_create(err, svn_sqlite__reset(stmt));
-}
-
svn_error_t *
svn_wc__db_base_get_prop(const svn_string_t **propval,
@@ -2633,12 +2709,7 @@ svn_wc__db_base_clear_dav_cache_recursiv
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
- if (local_relpath[0] == 0)
- like_arg = "%";
- else
- like_arg = apr_pstrcat(scratch_pool,
- escape_sqlite_like(local_relpath, scratch_pool),
- "/%", NULL);
+ like_arg = construct_like_arg(local_relpath, scratch_pool);
#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
@@ -3001,17 +3072,39 @@ svn_wc__db_pristine_remove(svn_wc__db_t
{
const svn_checksum_t *md5_checksum;
svn_sqlite__stmt_t *stmt;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t is_referenced_nodes;
+#endif
/* ### Transitional: look for references to its MD-5 as well. */
SVN_ERR(svn_wc__db_pristine_get_md5(&md5_checksum, db, wri_abspath,
sha1_checksum, scratch_pool,
scratch_pool));
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_SELECT_ANY_PRISTINE_REFERENCE));
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__step(&is_referenced, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+ STMT_SELECT_ANY_PRISTINE_REFERENCE_1));
+ SVN_ERR(svn_sqlite__bind_checksum(stmt_nodes, 1, sha1_checksum,
+ scratch_pool));
+ SVN_ERR(svn_sqlite__bind_checksum(stmt_nodes, 2, md5_checksum,
+ scratch_pool));
+ SVN_ERR(svn_sqlite__step(&is_referenced_nodes, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT(is_referenced == is_referenced_nodes);
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ is_referenced = is_referenced_nodes;
+ stmt = stmt_nodes;
+#endif
+#endif
SVN_ERR(svn_sqlite__reset(stmt));
}
@@ -3229,6 +3322,8 @@ temp_cross_db_copy(svn_wc__db_t *db,
iwb.original_revnum = copyfrom_rev;
iwb.moved_here = FALSE;
+ iwb.op_depth = (*dst_relpath == '\0') ? 1 : 2; /* ### temporary op_depth */
+
iwb.checksum = checksum;
iwb.children = children;
iwb.depth = depth;
@@ -3450,6 +3545,7 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
apr_int64_t copyfrom_id;
svn_wc__db_kind_t kind;
const apr_array_header_t *children;
+ apr_int64_t op_depth;
SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
@@ -3511,6 +3607,10 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
else
children = NULL;
+ /* ### temporary op_depth */
+ op_depth = (children == NULL) ? (apr_int64_t)2 :
+ (apr_int64_t)1; /* no directory or stub */
+
if (!strcmp(src_pdh->local_abspath, dst_pdh->local_abspath))
{
svn_sqlite__stmt_t *stmt;
@@ -3551,8 +3651,7 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
SVN_ERR(svn_sqlite__bindf(stmt, "issisnnnt",
src_pdh->wcroot->wc_id, src_relpath,
dst_relpath,
- (children == NULL) ? (apr_int64_t)2 :
- (apr_int64_t)1, /* no directory or stub */
+ op_depth,
dst_parent_relpath,
presence_map, dst_status));
@@ -3579,6 +3678,7 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
dst_pdh->wcroot->wc_id,
dst_relpath,
children,
+ op_depth,
scratch_pool));
}
else
@@ -3656,6 +3756,8 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
iwb.original_revnum = original_revision;
}
+ iwb.op_depth = (*local_relpath == '\0') ? 1 : 2; /* ### temporary op_depth */
+
iwb.children = children;
iwb.depth = depth;
@@ -3728,6 +3830,8 @@ svn_wc__db_op_copy_file(svn_wc__db_t *db
iwb.original_revnum = original_revision;
}
+ iwb.op_depth = (*local_relpath == '\0') ? 1 : 2; /* ### temporary op_depth */
+
iwb.checksum = checksum;
iwb.work_items = work_items;
@@ -3795,6 +3899,8 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t
iwb.original_revnum = original_revision;
}
+ iwb.op_depth = (*local_relpath == '\0') ? 1 : 2; /* ### temporary op_depth */
+
iwb.target = target;
iwb.work_items = work_items;
@@ -3831,6 +3937,7 @@ svn_wc__db_op_add_directory(svn_wc__db_t
iwb.kind = svn_wc__db_kind_dir;
iwb.wc_id = pdh->wcroot->wc_id;
iwb.local_relpath = local_relpath;
+ iwb.op_depth = relpath_depth(local_relpath);
iwb.work_items = work_items;
@@ -3866,6 +3973,7 @@ svn_wc__db_op_add_file(svn_wc__db_t *db,
iwb.kind = svn_wc__db_kind_file;
iwb.wc_id = pdh->wcroot->wc_id;
iwb.local_relpath = local_relpath;
+ iwb.op_depth = relpath_depth(local_relpath);
iwb.work_items = work_items;
@@ -3903,6 +4011,7 @@ svn_wc__db_op_add_symlink(svn_wc__db_t *
iwb.kind = svn_wc__db_kind_symlink;
iwb.wc_id = pdh->wcroot->wc_id;
iwb.local_relpath = local_relpath;
+ iwb.op_depth = relpath_depth(local_relpath);
iwb.target = target;
@@ -4746,8 +4855,7 @@ db_working_insert(svn_wc__db_status_t st
iwb.wc_id = pdh->wcroot->wc_id;
iwb.local_relpath = local_relpath;
iwb.presence = status;
- /* ### NODE_DATA we temporary store 1 or 2 */
- iwb.op_depth = (*local_relpath == '\0') ? 1 : 2;
+ iwb.op_depth = relpath_depth(local_relpath);
SVN_ERR(svn_sqlite__with_transaction(pdh->wcroot->sdb,
copy_working_from_base, &iwb,
@@ -5034,6 +5142,7 @@ svn_wc__db_read_info(svn_wc__db_status_t
if (!have_work)
have_work = &local_have_work;
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt_base, pdh->wcroot->sdb,
lock ? STMT_SELECT_BASE_NODE_WITH_LOCK
: STMT_SELECT_BASE_NODE));
@@ -5046,6 +5155,7 @@ svn_wc__db_read_info(svn_wc__db_status_t
SVN_ERR(svn_sqlite__bindf(stmt_work, "is",
pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(have_work, stmt_work));
+#endif
SVN_ERR(svn_sqlite__get_statement(&stmt_act, pdh->wcroot->sdb,
STMT_SELECT_ACTUAL_NODE));
@@ -5076,6 +5186,8 @@ svn_wc__db_read_info(svn_wc__db_status_t
SVN_ERR(assert_working_rows_match(*have_work, local_have_nodes_work,
stmt_work, stmt_nodes_work,
local_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes_base));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes_work));
#else
/* Lets assume the queries return compatible data */
*have_base = local_have_nodes_base;
@@ -5386,13 +5498,6 @@ svn_wc__db_read_info(svn_wc__db_status_t
scratch_pool));
}
-#ifdef SVN_WC__NODES
-#ifndef SVN_WC__NODES_ONLY
- err = svn_error_compose_create(err, svn_sqlite__reset(stmt_nodes_base));
- err = svn_error_compose_create(err, svn_sqlite__reset(stmt_nodes_work));
-#endif
-#endif
-
err = svn_error_compose_create(err, svn_sqlite__reset(stmt_base));
err = svn_error_compose_create(err, svn_sqlite__reset(stmt_work));
SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt_act)));
@@ -5609,12 +5714,7 @@ relocate_txn(void *baton, svn_sqlite__db
SVN_ERR(create_repos_id(&new_repos_id, rb->repos_root_url, rb->repos_uuid,
sdb, scratch_pool));
- if (rb->local_relpath[0] == 0)
- like_arg = "%";
- else
- like_arg = apr_pstrcat(scratch_pool,
- escape_sqlite_like(rb->local_relpath, scratch_pool),
- "/%", NULL);
+ like_arg = construct_like_arg(rb->local_relpath, scratch_pool);
#ifndef SVN_WC__NODES_ONLY
/* Update non-NULL WORKING_NODE.copyfrom_repos_id. */
@@ -5657,12 +5757,7 @@ relocate_txn(void *baton, svn_sqlite__db
#endif
/* Update any locks for the root or its children. */
- if (rb->repos_relpath[0] == 0)
- like_arg = "%";
- else
- like_arg = apr_pstrcat(scratch_pool,
- escape_sqlite_like(rb->repos_relpath, scratch_pool),
- "/%", NULL);
+ like_arg = construct_like_arg(rb->repos_relpath, scratch_pool);
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
STMT_UPDATE_LOCK_REPOS_ID));
@@ -5835,24 +5930,55 @@ commit_node(void *baton, svn_sqlite__db_
svn_wc__db_kind_t new_kind;
const char *new_depth_str = NULL;
svn_sqlite__stmt_t *stmt;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes_base, *stmt_nodes_work;
+ svn_boolean_t have_nodes_base, have_nodes_work;
+#endif
/* ### is it better to select only the data needed? */
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt_base, cb->pdh->wcroot->sdb,
STMT_SELECT_BASE_NODE));
SVN_ERR(svn_sqlite__get_statement(&stmt_work, cb->pdh->wcroot->sdb,
STMT_SELECT_WORKING_NODE));
- SVN_ERR(svn_sqlite__get_statement(&stmt_act, cb->pdh->wcroot->sdb,
- STMT_SELECT_ACTUAL_NODE));
-
SVN_ERR(svn_sqlite__bindf(stmt_base, "is",
cb->pdh->wcroot->wc_id, cb->local_relpath));
SVN_ERR(svn_sqlite__bindf(stmt_work, "is",
cb->pdh->wcroot->wc_id, cb->local_relpath));
- SVN_ERR(svn_sqlite__bindf(stmt_act, "is",
- cb->pdh->wcroot->wc_id, cb->local_relpath));
-
SVN_ERR(svn_sqlite__step(&have_base, stmt_base));
SVN_ERR(svn_sqlite__step(&have_work, stmt_work));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes_base, cb->pdh->wcroot->sdb,
+ STMT_SELECT_BASE_NODE_1));
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes_work, cb->pdh->wcroot->sdb,
+ STMT_SELECT_WORKING_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes_base, "is",
+ cb->pdh->wcroot->wc_id, cb->local_relpath));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes_work, "is",
+ cb->pdh->wcroot->wc_id, cb->local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_base, stmt_nodes_base));
+ SVN_ERR(svn_sqlite__step(&have_nodes_work, stmt_nodes_work));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_base_rows_match(have_base, have_nodes_base,
+ stmt_base, stmt_nodes_base,
+ cb->local_relpath, scratch_pool));
+ SVN_ERR(assert_working_rows_match(have_work, have_nodes_work,
+ stmt_work, stmt_nodes_work,
+ cb->local_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes_base));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes_work));
+#else
+ stmt_base = stmt_nodes_base;
+ stmt_work = stmt_nodes_work;
+ have_base = have_nodes_base;
+ have_work = have_nodes_work;
+#endif
+#endif
+ SVN_ERR(svn_sqlite__get_statement(&stmt_act, cb->pdh->wcroot->sdb,
+ STMT_SELECT_ACTUAL_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt_act, "is",
+ cb->pdh->wcroot->wc_id, cb->local_relpath));
SVN_ERR(svn_sqlite__step(&have_act, stmt_act));
/* There should be something to commit! */
@@ -6076,14 +6202,36 @@ determine_repos_info(apr_int64_t *repos_
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
const char *repos_parent_relpath;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
/* ### is it faster to fetch fewer columns? */
/* Prefer the current node's repository information. */
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_SELECT_BASE_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+ STMT_SELECT_BASE_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_base_rows_match(have_row, have_nodes_row,
+ stmt, stmt_nodes,
+ local_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
if (have_row && !svn_sqlite__column_is_null(stmt, 0))
{
@@ -6550,12 +6698,34 @@ svn_wc__db_scan_addition(svn_wc__db_stat
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
svn_wc__db_status_t presence;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
/* ### is it faster to fetch fewer columns? */
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_WORKING_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, current_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, wcroot->sdb,
+ STMT_SELECT_WORKING_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+ wcroot->wc_id, current_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_working_rows_match(have_row, have_nodes_row,
+ stmt, stmt_nodes,
+ current_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
if (!have_row)
{
@@ -6735,11 +6905,34 @@ svn_wc__db_scan_deletion(const char **ba
svn_boolean_t have_row;
svn_boolean_t have_base;
svn_wc__db_status_t work_presence;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_DELETION_INFO));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, current_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, wcroot->sdb,
+ STMT_SELECT_DELETION_INFO_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+ wcroot->wc_id, current_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt, 0)
+ == svn_sqlite__column_int64(stmt_nodes, 0));
+ SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt, 1)
+ == svn_sqlite__column_int64(stmt_nodes, 1));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
if (!have_row)
{
@@ -7785,6 +7978,10 @@ svn_wc__db_node_hidden(svn_boolean_t *hi
svn_wc__db_status_t work_status, base_status;
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
/* This uses an optimisation that first reads the working node and
then may read the base node. It could call svn_wc__db_read_info
@@ -7798,10 +7995,27 @@ svn_wc__db_node_hidden(svn_boolean_t *hi
VERIFY_USABLE_PDH(pdh);
/* First check the working node. */
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_SELECT_WORKING_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+ STMT_SELECT_WORKING_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_working_rows_match(have_row, have_nodes_row, stmt, stmt_nodes,
+ local_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
if (have_row)
{
@@ -7958,7 +8172,7 @@ wclock_obtain_cb(void *baton,
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_FIND_WC_LOCK));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, filter));
- lock_depth = relpath_op_depth(bt->local_relpath);
+ lock_depth = relpath_depth(bt->local_relpath);
max_depth = lock_depth + bt->levels_to_lock;
SVN_ERR(svn_sqlite__step(&got_row, stmt));
@@ -7973,7 +8187,7 @@ wclock_obtain_cb(void *baton,
/* If we are not locking with depth infinity, check if this lock
voids our lock request */
if (bt->levels_to_lock >= 0
- && relpath_op_depth(lock_relpath) > max_depth)
+ && relpath_depth(lock_relpath) > max_depth)
{
SVN_ERR(svn_sqlite__step(&got_row, stmt));
continue;
@@ -8031,7 +8245,7 @@ wclock_obtain_cb(void *baton,
{
int levels = svn_sqlite__column_int(stmt, 0);
if (levels >= 0)
- levels += relpath_op_depth(lock_relpath);
+ levels += relpath_depth(lock_relpath);
SVN_ERR(svn_sqlite__reset(stmt));
@@ -8107,7 +8321,7 @@ svn_wc__db_wclock_obtain(svn_wc__db_t *d
{
int i;
svn_wc__db_wcroot_t *wcroot = baton.pdh->wcroot;
- int depth = relpath_op_depth(baton.local_relpath);
+ int depth = relpath_depth(baton.local_relpath);
for (i = 0; i < wcroot->owned_locks->nelts; i++)
{
@@ -8116,7 +8330,7 @@ svn_wc__db_wclock_obtain(svn_wc__db_t *d
if (svn_relpath_is_ancestor(lock->local_relpath, baton.local_relpath)
&& (lock->levels == -1
- || (lock->levels + relpath_op_depth(lock->local_relpath))
+ || (lock->levels + relpath_depth(lock->local_relpath))
>= depth))
{
const char *lock_abspath
@@ -8289,7 +8503,7 @@ svn_wc__db_wclock_owns_lock(svn_boolean_
VERIFY_USABLE_PDH(pdh);
*own_lock = FALSE;
owned_locks = pdh->wcroot->owned_locks;
- lock_level = relpath_op_depth(local_relpath);
+ lock_level = relpath_depth(local_relpath);
if (exact)
for (i = 0; i < owned_locks->nelts; i++)
@@ -8311,7 +8525,7 @@ svn_wc__db_wclock_owns_lock(svn_boolean_
if (svn_relpath_is_ancestor(lock->local_relpath, local_relpath)
&& (lock->levels == -1
- || ((relpath_op_depth(lock->local_relpath) + lock->levels)
+ || ((relpath_depth(lock->local_relpath) + lock->levels)
>= lock_level)))
{
*own_lock = TRUE;
@@ -8358,7 +8572,11 @@ svn_wc__db_temp_op_set_base_incomplete(s
SVN_ERR(svn_sqlite__bind_text(stmt, 3, incomplete ? "incomplete" : "normal"));
SVN_ERR(svn_sqlite__update(&affected_node_rows, stmt));
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR_ASSERT(affected_rows == affected_node_rows);
+#else
+ affected_rows = affected_node_rows;
+#endif
#endif
if (affected_rows > 0)
@@ -8521,12 +8739,33 @@ make_copy_txn(void *baton,
const apr_array_header_t *children;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
int i;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_WORKING_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", mcb->pdh->wcroot->wc_id,
mcb->local_relpath));
-
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+ STMT_SELECT_WORKING_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is", mcb->pdh->wcroot->wc_id,
+ mcb->local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_working_rows_match(have_row, have_nodes_row,
+ stmt, stmt_nodes,
+ mcb->local_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
if (have_row)
{
@@ -8556,11 +8795,28 @@ make_copy_txn(void *baton,
{
svn_wc__db_status_t base_status;
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_BASE_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", mcb->pdh->wcroot->wc_id,
mcb->local_relpath));
-
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+ STMT_SELECT_BASE_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is", mcb->pdh->wcroot->wc_id,
+ mcb->local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_base_rows_match(have_row, have_nodes_row,
+ stmt, stmt_nodes,
+ mcb->local_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
/* If there is no BASE_NODE, we don't have to copy anything */
if (!have_row)
@@ -8663,7 +8919,8 @@ make_copy_txn(void *baton,
SVN_ERR(svn_sqlite__bindf(stmt, "isi",
mcb->pdh->wcroot->wc_id,
mcb->local_relpath,
- (*mcb->local_relpath == '\0') ? 1 : 2));
+ (*mcb->local_relpath == '\0' /* ### op_depth */
+ ? (apr_int64_t)1 : (apr_int64_t)2)));
SVN_ERR(svn_sqlite__step_done(stmt));
#endif
@@ -8693,7 +8950,8 @@ make_copy_txn(void *baton,
SVN_ERR(svn_sqlite__bindf(stmt, "isi",
mcb->pdh->wcroot->wc_id,
mcb->local_relpath,
- (*mcb->local_relpath == '\0') ? 1 : 2));
+ (*mcb->local_relpath == '\0' /* ### op_depth */
+ ? (apr_int64_t)1 : (apr_int64_t)2)));
SVN_ERR(svn_sqlite__step_done(stmt));
#endif
@@ -8798,6 +9056,10 @@ get_copyfrom(apr_int64_t *copyfrom_repos
const char *local_relpath;
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -8807,10 +9069,27 @@ get_copyfrom(apr_int64_t *copyfrom_repos
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_SELECT_WORKING_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+ STMT_SELECT_WORKING_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_working_rows_match(have_row, have_nodes_row, stmt, stmt_nodes,
+ local_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
if (!have_row)
{
*copyfrom_repos_id = 0; /* What's a good value to return? */
@@ -8980,10 +9259,28 @@ svn_wc__db_temp_get_file_external(const
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t have_nodes_row;
+#endif
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
STMT_SELECT_FILE_EXTERNAL, scratch_pool));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(get_statement_for_path(&stmt_nodes, db, local_abspath,
+ STMT_SELECT_FILE_EXTERNAL_1, scratch_pool));
+ SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_text_columns_equal(stmt, stmt_nodes, 0, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ have_row = have_nodes_row;
+#endif
+#endif
/* ### file externals are pretty bogus right now. they have just a
### WORKING_NODE for a while, eventually settling into just a BASE_NODE.
@@ -9020,6 +9317,10 @@ svn_wc__db_temp_op_set_file_external(svn
const char *local_relpath;
svn_sqlite__stmt_t *stmt;
svn_boolean_t got_row;
+#ifdef SVN_WC__NODES
+ svn_sqlite__stmt_t *stmt_nodes;
+ svn_boolean_t got_nodes_row;
+#endif
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
SVN_ERR_ASSERT(!repos_relpath
@@ -9031,12 +9332,27 @@ svn_wc__db_temp_op_set_file_external(svn
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_SELECT_BASE_NODE));
-
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
-
SVN_ERR(svn_sqlite__step(&got_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+ STMT_SELECT_BASE_NODE_1));
+ SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&got_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+ SVN_ERR(assert_base_rows_match(got_row, got_nodes_row, stmt, stmt_nodes,
+ local_relpath, scratch_pool));
+ SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+ stmt = stmt_nodes;
+ got_row = got_nodes_row;
+#endif
+#endif
SVN_ERR(svn_sqlite__reset(stmt));
if (!got_row)
@@ -9094,12 +9410,30 @@ svn_wc__db_temp_op_set_file_external(svn
#endif
}
+#ifndef SVN_WC__NODES_ONLY
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
STMT_UPDATE_FILE_EXTERNAL));
-
SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id,
- local_relpath));
+ local_relpath));
+ if (repos_relpath)
+ {
+ const char *str;
+ SVN_ERR(svn_wc__serialize_file_external(&str,
+ repos_relpath,
+ peg_rev,
+ rev,
+ scratch_pool));
+
+ SVN_ERR(svn_sqlite__bind_text(stmt, 3, str));
+ }
+ SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_UPDATE_FILE_EXTERNAL_1));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id,
+ local_relpath));
if (repos_relpath)
{
const char *str;
@@ -9112,10 +9446,12 @@ svn_wc__db_temp_op_set_file_external(svn
SVN_ERR(svn_sqlite__bind_text(stmt, 3, str));
}
+ SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
SVN_ERR(flush_entries(db, pdh, local_abspath, scratch_pool));
- return svn_error_return(svn_sqlite__step_done(stmt));
+ return SVN_NO_ERROR;
}
svn_error_t *
Modified: subversion/branches/performance/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/wc_db.h?rev=1001417&r1=1001416&r2=1001417&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/performance/subversion/libsvn_wc/wc_db.h Sun Sep 26 11:58:58 2010
@@ -757,27 +757,6 @@ svn_wc__db_base_get_info(svn_wc__db_stat
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* Just like svn_wc__db_base_get_info, but always reads information
- from inside the parent of LOCAL_ABSPATH, to allow reading the
- information of a node that is obstructed by a separate working
- copy.
-
- ### BH: This information is necessary for svn_wc_add3()'s
- ### checkout integration support. Even after we switch to
- ### a single db.
- */
-svn_error_t *
-svn_wc__db_base_get_info_from_parent(svn_wc__db_status_t *status,
- svn_wc__db_kind_t *kind,
- svn_revnum_t *revision,
- const char **repos_relpath,
- const char **repos_root_url,
- const char **repos_uuid,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
/* Set *PROPVAL to the value of the property named PROPNAME of the node
LOCAL_ABSPATH in the BASE tree.
Modified: subversion/branches/performance/subversion/mod_dav_svn/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/authz.c?rev=1001417&r1=1001416&r2=1001417&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/authz.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/authz.c Sun Sep 26 11:58:58 2010
@@ -60,7 +60,7 @@ dav_svn__allow_read(request_rec *r,
allow_read_bypass = dav_svn__get_pathauthz_bypass(r);
if (allow_read_bypass != NULL)
{
- if (allow_read_bypass(r,path, repos->repo_name) == OK)
+ if (allow_read_bypass(r, path, repos->repo_basename) == OK)
return TRUE;
else
return FALSE;
Modified: subversion/branches/performance/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/deadprops.c?rev=1001417&r1=1001416&r2=1001417&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/deadprops.c Sun Sep 26 11:58:58 2010
@@ -161,7 +161,9 @@ get_value(dav_db *db, const dav_prop_nam
static dav_error *
-save_value(dav_db *db, const dav_prop_name *name, const svn_string_t *value)
+save_value(dav_db *db, const dav_prop_name *name,
+ const svn_string_t *const *old_value_p,
+ const svn_string_t *value)
{
const char *propname;
svn_error_t *serr;
@@ -210,10 +212,11 @@ save_value(dav_db *db, const dav_prop_na
}
else
{
- serr = svn_repos_fs_change_rev_prop3(resource->info->repos->repos,
+ serr = svn_repos_fs_change_rev_prop4(resource->info->repos->repos,
resource->info->root.rev,
resource->info->repos->username,
- propname, value, TRUE, TRUE,
+ propname, old_value_p, value,
+ TRUE, TRUE,
db->authz_read_func,
db->authz_read_baton,
resource->pool);
@@ -425,6 +428,7 @@ db_map_namespaces(dav_db *db,
static dav_error *
decode_property_value(const svn_string_t **out_propval_p,
+ svn_boolean_t *absent,
const svn_string_t *maybe_encoded_propval,
const apr_xml_elem *elem,
apr_pool_t *pool)
@@ -432,6 +436,7 @@ decode_property_value(const svn_string_t
apr_xml_attr *attr = elem->attr;
/* Default: no "encoding" attribute. */
+ *absent = FALSE;
*out_propval_p = maybe_encoded_propval;
/* Check for special encodings of the property value. */
@@ -443,12 +448,21 @@ decode_property_value(const svn_string_t
/* Handle known encodings here. */
if (enc_type && (strcmp(enc_type, "base64") == 0))
- *out_propval_p = svn_base64_decode_string(maybe_encoded_propval, pool);
+ *out_propval_p = svn_base64_decode_string(maybe_encoded_propval,
+ pool);
else
return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
"Unknown property encoding");
break;
}
+
+ if (strcmp(attr->name, SVN_DAV__OLD_VALUE__ABSENT) == 0)
+ {
+ /* ### parse attr->value */
+ *absent = TRUE;
+ *out_propval_p = NULL;
+ }
+
/* Next attribute, please. */
attr = attr->next;
}
@@ -462,7 +476,10 @@ db_store(dav_db *db,
const apr_xml_elem *elem,
dav_namespace_map *mapping)
{
+ const svn_string_t *const *old_propval_p;
+ const svn_string_t *old_propval;
const svn_string_t *propval;
+ svn_boolean_t absent;
apr_pool_t *pool = db->p;
dav_error *derr;
@@ -475,11 +492,41 @@ db_store(dav_db *db,
propval = svn_string_create
(dav_xml_get_cdata(elem, pool, 0 /* strip_white */), pool);
- derr = decode_property_value(&propval, propval, elem, pool);
+ derr = decode_property_value(&propval, &absent, propval, elem, pool);
if (derr)
return derr;
- return save_value(db, name, propval);
+ if (absent && ! elem->first_child)
+ /* ### better error check */
+ return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ apr_psprintf(pool,
+ "'%s' cannot be specified on the value "
+ "without specifying an expectation",
+ SVN_DAV__OLD_VALUE__ABSENT));
+
+ /* ### namespace check? */
+ if (elem->first_child && !strcmp(elem->first_child->name, SVN_DAV__OLD_VALUE))
+ {
+ const char *propname;
+
+ get_repos_propname(db, name, &propname);
+
+ /* Parse OLD_PROPVAL. */
+ old_propval = svn_string_create(dav_xml_get_cdata(elem->first_child, pool,
+ 0 /* strip_white */),
+ pool);
+ derr = decode_property_value(&old_propval, &absent,
+ old_propval, elem->first_child, pool);
+ if (derr)
+ return derr;
+
+ old_propval_p = (const svn_string_t *const *) &old_propval;
+ }
+ else
+ old_propval_p = NULL;
+
+
+ return save_value(db, name, old_propval_p, propval);
}
@@ -506,10 +553,10 @@ db_remove(dav_db *db, const dav_prop_nam
not a working resource! But this is how we currently
(hackily) allow the svn client to change unversioned rev
props. See issue #916. */
- serr = svn_repos_fs_change_rev_prop3(db->resource->info->repos->repos,
+ serr = svn_repos_fs_change_rev_prop4(db->resource->info->repos->repos,
db->resource->info->root.rev,
db->resource->info->repos->username,
- propname, NULL, TRUE, TRUE,
+ propname, NULL, NULL, TRUE, TRUE,
db->authz_read_func,
db->authz_read_baton,
db->resource->pool);
Modified: subversion/branches/performance/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/mod_dav_svn.c?rev=1001417&r1=1001416&r2=1001417&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/mod_dav_svn.c Sun Sep 26 11:58:58 2010
@@ -311,18 +311,24 @@ SVNPathAuthz_cmd(cmd_parms *cmd, void *c
dir_conf_t *conf = config;
if (apr_strnatcasecmp("off", arg1) == 0)
- conf->path_authz_method = CONF_PATHAUTHZ_OFF;
- else if (apr_strnatcasecmp(PATHAUTHZ_BYPASS_ARG,arg1) == 0)
+ {
+ conf->path_authz_method = CONF_PATHAUTHZ_OFF;
+ }
+ else if (apr_strnatcasecmp(PATHAUTHZ_BYPASS_ARG, arg1) == 0)
{
conf->path_authz_method = CONF_PATHAUTHZ_BYPASS;
if (pathauthz_bypass_func == NULL)
- pathauthz_bypass_func=ap_lookup_provider(
- AUTHZ_SVN__SUBREQ_BYPASS_PROV_GRP,
- AUTHZ_SVN__SUBREQ_BYPASS_PROV_NAME,
- AUTHZ_SVN__SUBREQ_BYPASS_PROV_VER);
+ {
+ pathauthz_bypass_func =
+ ap_lookup_provider(AUTHZ_SVN__SUBREQ_BYPASS_PROV_GRP,
+ AUTHZ_SVN__SUBREQ_BYPASS_PROV_NAME,
+ AUTHZ_SVN__SUBREQ_BYPASS_PROV_VER);
+ }
}
else
- conf->path_authz_method = CONF_PATHAUTHZ_ON;
+ {
+ conf->path_authz_method = CONF_PATHAUTHZ_ON;
+ }
return NULL;
}
@@ -608,7 +614,7 @@ dav_svn__get_pathauthz_bypass(request_re
conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
- if (conf->path_authz_method==CONF_PATHAUTHZ_BYPASS)
+ if (conf->path_authz_method == CONF_PATHAUTHZ_BYPASS)
return pathauthz_bypass_func;
return NULL;
}
Modified: subversion/branches/performance/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/repos.c?rev=1001417&r1=1001416&r2=1001417&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/repos.c Sun Sep 26 11:58:58 2010
@@ -1140,7 +1140,7 @@ dav_svn_split_uri(request_rec *r,
const char *root_path,
const char **cleaned_uri,
int *trailing_slash,
- const char **repos_name,
+ const char **repos_basename,
const char **relative_path,
const char **repos_path)
{
@@ -1216,14 +1216,14 @@ dav_svn_split_uri(request_rec *r,
### slash. something about SVN-private-path */
/* Depending on whether SVNPath or SVNParentPath was used, we need
- to compute 'relative' and 'repos_name' differently. */
+ to compute 'relative' and 'repos_basename' differently. */
/* Normal case: the SVNPath command was used to specify a
particular repository. */
if (fs_path != NULL)
{
- /* the repos_name is the last component of root_path. */
- *repos_name = svn_dirent_basename(root_path, r->pool);
+ /* the repos_basename is the last component of root_path. */
+ *repos_basename = svn_dirent_basename(root_path, r->pool);
/* 'relative' is already correct for SVNPath; the root_path
already contains the name of the repository, so relative is
@@ -1264,7 +1264,7 @@ dav_svn_split_uri(request_rec *r,
}
/* return answer */
- *repos_name = magic_component;
+ *repos_basename = magic_component;
}
/* We can return 'relative' at this point too. */
@@ -1882,7 +1882,7 @@ get_resource(request_rec *r,
dav_resource_combined *comb;
dav_svn_repos *repos;
const char *cleaned_uri;
- const char *repos_name;
+ const char *repo_basename;
const char *relative;
const char *repos_path;
const char *repos_key;
@@ -1925,7 +1925,7 @@ get_resource(request_rec *r,
/* This does all the work of interpreting/splitting the request uri. */
err = dav_svn_split_uri(r, r->uri, root_path,
&cleaned_uri, &had_slash,
- &repos_name, &relative, &repos_path);
+ &repo_basename, &relative, &repos_path);
if (err)
return err;
@@ -1938,9 +1938,9 @@ get_resource(request_rec *r,
{
/* ...then the URL to the repository is actually one implicit
component longer... */
- root_path = svn_uri_join(root_path, repos_name, r->pool);
+ root_path = svn_uri_join(root_path, repo_basename, r->pool);
/* ...and we need to specify exactly what repository to open. */
- fs_path = svn_dirent_join(fs_parent_path, repos_name, r->pool);
+ fs_path = svn_dirent_join(fs_parent_path, repo_basename, r->pool);
}
/* Start building and filling a 'combination' object. */
@@ -2011,7 +2011,7 @@ get_resource(request_rec *r,
repos->repo_name = repo_name;
/* The repository filesystem basename */
- repos->repo_basename = repos_name;
+ repos->repo_basename = repo_basename;
/* An XSL transformation */
repos->xslt_uri = xslt_uri;
Modified: subversion/branches/performance/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/util.c?rev=1001417&r1=1001416&r2=1001417&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/util.c Sun Sep 26 11:58:58 2010
@@ -107,6 +107,9 @@ dav_svn__convert_err(svn_error_t *serr,
case SVN_ERR_FS_PATH_ALREADY_LOCKED:
status = HTTP_LOCKED;
break;
+ case SVN_ERR_FS_PROP_BASEVALUE_MISMATCH:
+ status = HTTP_PRECONDITION_FAILED;
+ break;
/* add other mappings here */
}
Modified: subversion/branches/performance/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/mod_dav_svn/version.c?rev=1001417&r1=1001416&r2=1001417&view=diff
==============================================================================
--- subversion/branches/performance/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/performance/subversion/mod_dav_svn/version.c Sun Sep 26 11:58:58 2010
@@ -41,7 +41,6 @@
#include "private/svn_log.h"
#include "dav_svn.h"
-#include "mod_dav_svn.h"
svn_error_t *
@@ -143,6 +142,7 @@ get_vsn_options(apr_pool_t *p, apr_text_
/* Send SVN_RA_CAPABILITY_* capabilities. */
apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_DEPTH);
apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_LOG_REVPROPS);
+ apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS);
apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY);
/* Mergeinfo is a special case: here we merely say that the server
* knows how to handle mergeinfo -- whether the repository does too
@@ -1015,22 +1015,6 @@ deliver_report(request_rec *r,
if (doc->root->ns == ns)
{
- const char *cleaned_uri, *relative_path, *repos_path;
- int trailing_slash;
- /* During SVNPathAuthz short_circuit
- * resource->info->repos->repo_name becomes NULL.*/
- if (resource->info->repos->repo_name == NULL)
- {
- dav_error *err;
- err = dav_svn_split_uri(r, r->uri, dav_svn__get_root_dir(r),
- &cleaned_uri, &trailing_slash,
- &(resource->info->repos->repo_name),
- &relative_path, &repos_path);
- if (err)
- {
- return err;
- }
- }
/* ### note that these report names should have symbols... */
if (strcmp(doc->root->name, "update-report") == 0)