You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gs...@apache.org on 2010/04/18 23:00:22 UTC
svn commit: r935408 - in /subversion/trunk/subversion/libsvn_wc: entries.c
wc-queries.sql wc_db.c wc_db.h
Author: gstein
Date: Sun Apr 18 21:00:22 2010
New Revision: 935408
URL: http://svn.apache.org/viewvc?rev=935408&view=rev
Log:
Implement svn_wc__db_op_add_*. These functions add nodes to the WORKING
tree, corresponding to the "svn add FOO" command.
* subversion/wc_db.h:
(svn_wc__db_op_add_directory, svn_wc__db_op_add_file,
svn_wc__db_op_add_symlink): add a WORK_ITEMS parameter
(svn_wc__db_temp_wcroot_tempdir): add docstring
* subversion/wc_db.c:
(insert_working_baton_t): new baton for inserting rows into
WORKING_NODE, similar to insert_base_baton_t.
(insert_base_node): use svn_relpath_dirname instead of dirent_dirname
(blank_iwb): new helper function
(insert_working_node): new function to insert a WORKING_NODE row
(svn_wc__db_op_add_directory, svn_wc__db_op_add_file,
svn_wc__db_op_add_symlink): add a WORK_ITEMS parameter, and
implement the node addition.
* subversion/libsvn_wc/entries.c:
(insert_working_node): add a comment that we are not binding the
symlink_target parameter, but may want to do so
* subversion/libsvn_wc/wc-queries.sql:
(STMT_INSERT_WORKING_NODE_INCOMPLETE): new statement to add incomplete
nodes into the WORKING_NODE table
(STMT_INSERT_WORKING_NODE): add an insertion column for symlink_target
Modified:
subversion/trunk/subversion/libsvn_wc/entries.c
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/wc_db.h
Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=935408&r1=935407&r2=935408&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Sun Apr 18 21:00:22 2010
@@ -1757,6 +1757,8 @@ insert_working_node(svn_sqlite__db_t *sd
SVN_ERR(svn_sqlite__bind_int64(stmt, 19, working_node->keep_local));
+ /* ### we should bind 'symlink_target' (20) as appropriate. */
+
/* Execute and reset the insert clause. */
return svn_error_return(svn_sqlite__insert(NULL, stmt));
}
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=935408&r1=935407&r2=935408&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Sun Apr 18 21:00:22 2010
@@ -82,6 +82,11 @@ insert or ignore into base_node (
wc_id, local_relpath, parent_relpath, presence, kind, revnum)
values (?1, ?2, ?3, 'incomplete', 'unknown', ?5);
+-- STMT_INSERT_WORKING_NODE_INCOMPLETE
+INSERT OR IGNORE INTO BASE_NODE (
+ wc_id, local_relpath, parent_relpath, presence, kind)
+VALUES (?1, ?2, ?3, 'incomplete', 'unknown');
+
-- STMT_SELECT_BASE_NODE_CHILDREN
select local_relpath from base_node
where wc_id = ?1 and parent_relpath = ?2;
@@ -405,9 +410,9 @@ insert or replace into working_node (
copyfrom_repos_id,
copyfrom_repos_path, copyfrom_revnum, moved_here, moved_to, checksum,
translated_size, changed_rev, changed_date, changed_author, depth,
- last_mod_time, properties, keep_local)
+ last_mod_time, properties, keep_local, symlink_target)
values (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
- ?15, ?16, ?17, ?18, ?19);
+ ?15, ?16, ?17, ?18, ?19, ?20);
-- STMT_INSERT_ACTUAL_NODE
insert or replace into actual_node (
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=935408&r1=935407&r2=935408&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Sun Apr 18 21:00:22 2010
@@ -248,6 +248,39 @@ typedef struct {
} insert_base_baton_t;
+typedef struct {
+ /* common to all insertions into WORKING */
+ svn_wc__db_status_t presence;
+ svn_wc__db_kind_t kind;
+ apr_int64_t wc_id;
+ const char *local_relpath;
+
+ /* common to all "normal" presence insertions */
+ const apr_hash_t *props;
+ svn_revnum_t changed_rev;
+ apr_time_t changed_date;
+ const char *changed_author;
+ apr_int64_t original_repos_id;
+ const char *original_repos_relpath;
+ svn_revnum_t original_revnum;
+ svn_boolean_t moved_here;
+
+ /* for inserting directories */
+ const apr_array_header_t *children;
+ svn_depth_t depth;
+
+ /* for inserting (copied/moved-here) files */
+ const svn_checksum_t *checksum;
+
+ /* for inserting symlinks */
+ const char *target;
+
+ /* may have work items to queue in this transaction */
+ const svn_skel_t *work_items;
+
+} insert_working_baton_t;
+
+
static const svn_token_map_t kind_map[] = {
{ "file", svn_wc__db_kind_file },
{ "dir", svn_wc__db_kind_dir },
@@ -1381,8 +1414,8 @@ insert_base_node(void *baton, svn_sqlite
bind the appropriate parent_relpath. */
if (*pibb->local_relpath != '\0')
SVN_ERR(svn_sqlite__bind_text(stmt, 5,
- svn_dirent_dirname(pibb->local_relpath,
- scratch_pool)));
+ svn_relpath_dirname(pibb->local_relpath,
+ scratch_pool)));
SVN_ERR(svn_sqlite__bind_token(stmt, 6, presence_map, pibb->status));
SVN_ERR(svn_sqlite__bind_token(stmt, 7, kind_map, pibb->kind));
@@ -1410,6 +1443,7 @@ insert_base_node(void *baton, svn_sqlite
}
else if (pibb->kind == svn_wc__db_kind_symlink)
{
+ /* Note: incomplete nodes may have a NULL target. */
if (pibb->target)
SVN_ERR(svn_sqlite__bind_text(stmt, 16, pibb->target));
}
@@ -1444,6 +1478,119 @@ insert_base_node(void *baton, svn_sqlite
}
+static void
+blank_iwb(insert_working_baton_t *piwb)
+{
+ memset(piwb, 0, sizeof(*piwb));
+ piwb->changed_rev = SVN_INVALID_REVNUM;
+ piwb->depth = svn_depth_infinity;
+
+ /* ORIGINAL_REPOS_ID and ORIGINAL_REVNUM could use some kind of "nil"
+ value, but... meh. We'll avoid them if ORIGINAL_REPOS_RELPATH==NULL. */
+}
+
+
+/* */
+static svn_error_t *
+insert_working_node(void *baton,
+ svn_sqlite__db_t *sdb,
+ apr_pool_t *scratch_pool)
+{
+ const insert_working_baton_t *piwb = baton;
+ const char *parent_relpath;
+ svn_sqlite__stmt_t *stmt;
+
+ /* We cannot insert a WORKING_NODE row at the wcroot. */
+ /* ### actually, with per-dir DB, we can... */
+#if 0
+ SVN_ERR_ASSERT(*piwb->local_relpath != '\0');
+#endif
+ if (*piwb->local_relpath == '\0')
+ parent_relpath = NULL;
+ else
+ parent_relpath = svn_relpath_dirname(piwb->local_relpath, scratch_pool);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isstt",
+ piwb->wc_id, piwb->local_relpath,
+ parent_relpath,
+ presence_map, piwb->presence,
+ kind_map, piwb->kind));
+
+ if (piwb->original_repos_relpath != NULL)
+ {
+ SVN_ERR_ASSERT(piwb->original_repos_id > 0);
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(piwb->original_revnum));
+
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 6, piwb->original_repos_id));
+ SVN_ERR(svn_sqlite__bind_text(stmt, 7, piwb->original_repos_relpath));
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 8, piwb->original_revnum));
+ }
+
+ /* Do not bind 'moved_here' (9), nor 'moved_to' (10). */
+
+ /* 'checksum' (11) is bound below. */
+
+ /* Do not bind 'translated_size' (12). */
+
+ if (SVN_IS_VALID_REVNUM(piwb->changed_rev))
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 13, piwb->changed_rev));
+ if (piwb->changed_date)
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 14, piwb->changed_date));
+ if (piwb->changed_author)
+ SVN_ERR(svn_sqlite__bind_text(stmt, 15, piwb->changed_author));
+
+ if (piwb->kind == svn_wc__db_kind_dir)
+ {
+ SVN_ERR(svn_sqlite__bind_text(stmt, 16, svn_depth_to_word(piwb->depth)));
+ }
+ else if (piwb->kind == svn_wc__db_kind_file)
+ {
+ SVN_ERR(svn_sqlite__bind_checksum(stmt, 11, piwb->checksum,
+ scratch_pool));
+ }
+ else if (piwb->kind == svn_wc__db_kind_symlink)
+ {
+ SVN_ERR_ASSERT(piwb->target != NULL);
+
+ SVN_ERR(svn_sqlite__bind_text(stmt, 20, piwb->target));
+ }
+
+ /* Do not bind 'last_mod_time' (17). */
+
+ SVN_ERR(svn_sqlite__bind_properties(stmt, 18, piwb->props, scratch_pool));
+
+ /* Do not bind 'keep_local' (19). */
+
+ SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+ if (piwb->kind == svn_wc__db_kind_dir && piwb->children)
+ {
+ int i;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_INSERT_WORKING_NODE_INCOMPLETE));
+
+ for (i = piwb->children->nelts; i--; )
+ {
+ const char *name = APR_ARRAY_IDX(piwb->children, i, const char *);
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "iss",
+ piwb->wc_id,
+ svn_relpath_join(piwb->local_relpath,
+ name,
+ scratch_pool),
+ piwb->local_relpath));
+ SVN_ERR(svn_sqlite__insert(NULL, stmt));
+ }
+ }
+
+ SVN_ERR(add_work_items(sdb, piwb->work_items, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+
/* */
static svn_error_t *
gather_children(const apr_array_header_t **children,
@@ -2715,22 +2862,95 @@ svn_wc__db_op_copy_url(svn_wc__db_t *db,
svn_error_t *
svn_wc__db_op_add_directory(svn_wc__db_t *db,
const char *local_abspath,
+ const svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
+ svn_wc__db_pdh_t *pdh;
+ const char *local_relpath;
+ insert_working_baton_t iwb;
+
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- NOT_IMPLEMENTED();
+ SVN_ERR(parse_local_abspath(&pdh, &local_relpath, db, local_abspath,
+ svn_sqlite__mode_readwrite,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_PDH(pdh);
+
+ blank_iwb(&iwb);
+
+ iwb.presence = svn_wc__db_status_normal;
+ iwb.kind = svn_wc__db_kind_dir;
+ iwb.wc_id = pdh->wcroot->wc_id;
+ iwb.local_relpath = local_relpath;
+
+ iwb.work_items = work_items;
+
+ SVN_ERR(svn_sqlite__with_transaction(pdh->wcroot->sdb,
+ insert_working_node, &iwb,
+ scratch_pool));
+ flush_entries(pdh);
+
+ /* Add a parent stub. */
+ {
+ svn_error_t *err;
+
+ err = navigate_to_parent(&pdh, db, pdh, svn_sqlite__mode_readwrite,
+ scratch_pool);
+ if (err)
+ {
+ /* Prolly fell off teh top of the wcroot. Just call it a day. */
+ svn_error_clear(err);
+ return SVN_NO_ERROR;
+ }
+
+ blank_iwb(&iwb);
+
+ iwb.presence = svn_wc__db_status_normal;
+ iwb.kind = svn_wc__db_kind_subdir;
+ iwb.wc_id = pdh->wcroot->wc_id;
+ iwb.local_relpath = svn_dirent_basename(local_abspath, scratch_pool);
+
+ /* No children or work items, so a txn is not needed. */
+ SVN_ERR(insert_working_node(&iwb, pdh->wcroot->sdb, scratch_pool));
+ flush_entries(pdh);
+ }
+
+ return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__db_op_add_file(svn_wc__db_t *db,
const char *local_abspath,
+ const svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
+ svn_wc__db_pdh_t *pdh;
+ const char *local_relpath;
+ insert_working_baton_t iwb;
+
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- NOT_IMPLEMENTED();
+ SVN_ERR(parse_local_abspath(&pdh, &local_relpath, db, local_abspath,
+ svn_sqlite__mode_readwrite,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_PDH(pdh);
+
+ blank_iwb(&iwb);
+
+ iwb.presence = svn_wc__db_status_normal;
+ iwb.kind = svn_wc__db_kind_file;
+ iwb.wc_id = pdh->wcroot->wc_id;
+ iwb.local_relpath = local_relpath;
+
+ iwb.work_items = work_items;
+
+ SVN_ERR(svn_sqlite__with_transaction(pdh->wcroot->sdb,
+ insert_working_node, &iwb,
+ scratch_pool));
+ flush_entries(pdh);
+
+ return SVN_NO_ERROR;
}
@@ -2738,14 +2958,41 @@ svn_error_t *
svn_wc__db_op_add_symlink(svn_wc__db_t *db,
const char *local_abspath,
const char *target,
+ const svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
+ svn_wc__db_pdh_t *pdh;
+ const char *local_relpath;
+ insert_working_baton_t iwb;
+
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
SVN_ERR_ASSERT(target != NULL);
- NOT_IMPLEMENTED();
+ SVN_ERR(parse_local_abspath(&pdh, &local_relpath, db, local_abspath,
+ svn_sqlite__mode_readwrite,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_PDH(pdh);
+
+ blank_iwb(&iwb);
+
+ iwb.presence = svn_wc__db_status_normal;
+ iwb.kind = svn_wc__db_kind_symlink;
+ iwb.wc_id = pdh->wcroot->wc_id;
+ iwb.local_relpath = local_relpath;
+
+ iwb.target = target;
+
+ iwb.work_items = work_items;
+
+ SVN_ERR(svn_sqlite__with_transaction(pdh->wcroot->sdb,
+ insert_working_node, &iwb,
+ scratch_pool));
+ flush_entries(pdh);
+
+ return SVN_NO_ERROR;
}
+
struct set_props_baton
{
apr_hash_t *props;
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=935408&r1=935407&r2=935408&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Sun Apr 18 21:00:22 2010
@@ -952,25 +952,31 @@ svn_wc__db_op_copy_url(svn_wc__db_t *db,
/* ### 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. */
+/* ### 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 svn_skel_t *work_items,
apr_pool_t *scratch_pool);
/* ### as a new file, there are no properties. 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 svn_skel_t *work_items,
apr_pool_t *scratch_pool);
/* ### newly added symlinks have no properties. */
+/* ### 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 svn_skel_t *work_items,
apr_pool_t *scratch_pool);
@@ -2095,6 +2101,9 @@ svn_wc__db_temp_get_sdb(svn_sqlite__db_t
apr_pool_t *scratch_pool);
+/* Return a directory in *TEMP_DIR_ABSPATH that is suitable for temporary
+ files which may need to be moved (atomically and same-device) into the
+ working copy indicated by WRI_ABSPATH. */
svn_error_t *
svn_wc__db_temp_wcroot_tempdir(const char **temp_dir_abspath,
svn_wc__db_t *db,