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,