Author: rhuijben
Date: Mon Mar 15 00:29:53 2010
New Revision: 923019

URL: http://svn.apache.org/viewvc?rev=923019&view=rev
Log:
Remove four more svn_wc__entry_modify2() calls by creating a wc_db
operation for making a copy from the current node state to WORKING_NODE.

This function provides the implementation for
schedule_existing_item_for_re_add() (update_editor.c) and
mark_tree_copied() (adm_ops.c, svn_wc_add4()).

This patch removes schedule_existing_item_for_re_add(), but doesn't touch
mark_tree_copied() yet as time is up for today.

* subversion/libsvn_wc/update_editor.c
  (set_copied_baton_t): Remove baton.
  (set_copied_callback): Remove function.
  (schedule_existing_item_for_re_add): Remove function.
  (do_entry_deletion): Update caller.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE,
   STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE,
   STMT_UPDATE_COPYFROM): New queries.

* subversion/libsvn_wc/wc_db.c
  (make_copy_baton): New struct.
  (make_copy_txn): New helper function.
  (svn_wc__db_temp_op_make_copy): New function.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_temp_op_make_copy): New function.

Modified:
    subversion/trunk/subversion/libsvn_wc/update_editor.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/update_editor.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=923019&r1=923018&r2=923019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Mon Mar 15 00:29:53 
2010
@@ -2055,217 +2055,6 @@ node_already_conflicted(svn_boolean_t *c
   return SVN_NO_ERROR;
 }
 
-
-/* A walk baton for schedule_existing_item_for_re_add()'s call
-   to svn_wc__internal_walk_children(). */
-struct set_copied_baton_t
-{
-  svn_wc__db_t *db;
-
-  /* The PATH arg to schedule_existing_item_for_re_add(). */
-  const char *added_subtree_root_path;
-};
-
-/* An svn_wc__node_found_func_t callback function.
- * Set the 'copied' flag on the given ENTRY for every PATH
- * under ((set_copied_baton_t *)WALK_BATON)->ADDED_SUBTREE_ROOT_PATH
- * which has a normal schedule. */
-static svn_error_t *
-set_copied_callback(const char *local_abspath,
-                    void *walk_baton,
-                    apr_pool_t *scratch_pool)
-{
-  struct set_copied_baton_t *b = walk_baton;
-  svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
-
-  if (strcmp(local_abspath, b->added_subtree_root_path) == 0)
-    return SVN_NO_ERROR; /* Don't touch the root */
-
-  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL,
-                               b->db, local_abspath,
-                               scratch_pool, scratch_pool));
-
-  if (kind == svn_wc__db_kind_dir)
-    {
-      /* We don't want to mark a deleted PATH as copied.  If PATH
-         is added without history we don't want to make it look like
-         it has history.  If PATH is replaced we don't want to make
-         it look like it has history if it doesn't.  Only if PATH is
-         schedule normal do we need to mark it as copied. */
-      if (status == svn_wc__db_status_normal)
-        {
-          svn_wc_entry_t tmp_entry;
-
-          /* Set the 'copied' flag and write the entry out to disk. */
-          tmp_entry.copied = TRUE;
-          SVN_ERR(svn_wc__entry_modify2(b->db,
-                                        local_abspath,
-                                        svn_node_dir,
-                                        TRUE,
-                                        &tmp_entry,
-                                        SVN_WC__ENTRY_MODIFY_COPIED,
-                                        scratch_pool));
-        }
-    }
-
-  /* We don't want to mark a deleted PATH as copied.  If PATH
-     is added without history we don't want to make it look like
-     it has history.  If PATH is replaced we don't want to make
-     it look like it has history if it doesn't.  Only if PATH is
-     schedule normal do we need to mark it as copied. */
-  if (status == svn_wc__db_status_normal)
-    {
-      svn_wc_entry_t tmp_entry;
-      apr_hash_t *props;
-
-      /* We switch the node from BASE to WORKING.. We have to move the
-         properties with it */
-      SVN_ERR(svn_wc__db_read_pristine_props(&props, b->db, local_abspath,
-                                             scratch_pool, scratch_pool));
-
-      /* Set the 'copied' flag and write the entry out to disk. */
-      tmp_entry.copied = TRUE;
-      SVN_ERR(svn_wc__entry_modify2(b->db,
-                                    local_abspath,
-                                    kind == svn_wc__db_kind_dir
-                                      ? svn_node_dir
-                                      : svn_node_file,
-                                    FALSE,
-                                    &tmp_entry,
-                                    SVN_WC__ENTRY_MODIFY_COPIED,
-                                    scratch_pool));
-
-      SVN_ERR(svn_wc__db_temp_op_set_pristine_props(b->db, local_abspath, 
props,
-                                                    TRUE, scratch_pool));
-    }
-  return SVN_NO_ERROR;
-}
-
-/* Schedule the WC item LOCAL_ABSPATH for re-addition by copying its BASE_NODE
- * information to WORKING_NODE where necessary.
- *.
- * If MODIFY_COPYFROM is TRUE, re-add the item as a copy with history
- * of node-...@node-rev.
- * Assume that the item exists locally and is scheduled as still existing with
- * some local modifications relative to its (old) base, but does not exist in
- * the repository at the target revision.
- *
- * Use the local content of the item, even if it
- * If the item is a directory, recursively schedule its contents to be the
- * contents of the re-added tree, even if they are locally modified relative
- * to it.
- *
- * THEIR_REPOS_RELPATH is the deleted node's repos-relpath on the source-
- * right side, the side that the target should become after the update. In
- * other words, that's the new repos-relpath the node would have if it were
- * not deleted.
- *
- * Make changes immediately, not loggily, because that is easier to keep
- * track of when multiple directories are involved. */
-static svn_error_t *
-schedule_existing_item_for_re_add(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  const char *their_repos_relpath,
-                                  svn_boolean_t modify_copyfrom,
-                                  apr_pool_t *pool)
-{
-  svn_wc_entry_t tmp_entry;
-  apr_uint64_t flags = 0;
-  apr_hash_t *props;
-  const svn_wc_entry_t *entry;
-  const char *repos_root;
-  svn_error_t *err;
-
-  SVN_ERR(svn_wc__db_scan_base_repos(NULL, &repos_root, NULL, db, 
local_abspath,
-                                     pool, pool));
-
-  err = svn_wc__get_entry(&entry, db, local_abspath,
-                          FALSE /* allow_unversioned */, svn_node_unknown,
-                          TRUE /* need_parent_stub */, pool, pool);
-  if (err)
-    {
-      if (err->apr_err != SVN_ERR_NODE_UNEXPECTED_KIND)
-        return svn_error_return(err);
-
-      /* The node was a file, and we got the "real" entry, not the stub.
-         That is just what we'd like.  */
-      svn_error_clear(err);
-    }
-
-  SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
-                                         pool, pool));
-
-  /* Update the details of the base rev/url to reflect the incoming
-   * delete, while leaving the working version as it is, scheduling it
-   * for re-addition unless it was already non-existent. */
-  tmp_entry.url = svn_path_url_add_component2(repos_root,
-                                              their_repos_relpath, pool);
-  flags |= SVN_WC__ENTRY_MODIFY_URL;
-
-  /* Schedule the working version to be re-added. */
-  tmp_entry.schedule = svn_wc_schedule_add;
-  flags |= SVN_WC__ENTRY_MODIFY_SCHEDULE;
-  flags |= SVN_WC__ENTRY_MODIFY_FORCE;
-
-  if (modify_copyfrom)
-    {
-      tmp_entry.copyfrom_url = entry->url;
-      flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_URL;
-      tmp_entry.copyfrom_rev = entry->revision;
-      flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_REV;
-      tmp_entry.copied = TRUE;
-      flags |= SVN_WC__ENTRY_MODIFY_COPIED;
-    }
-
-  /* ### Need to change the "base" into a "revert-base" ? */
-
-  /* Determine which adm dir holds this node's entry */
-  SVN_ERR(svn_wc__entry_modify2(db,
-                                local_abspath,
-                                entry->kind,
-                                FALSE,
-                                &tmp_entry,
-                                flags, pool));
-
-  SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, local_abspath, props,
-                                                TRUE, pool));
-
-  /* If it's a directory, set the 'copied' flag recursively. The rest of the
-   * directory tree's state can stay exactly as it was before being
-   * scheduled for re-add. */
-  /* ### BH: I don't think this code handles switched subpaths, excluded
-         and absent items in any usefull way. Needs carefull redesign */
-  if (entry->kind == svn_node_dir)
-    {
-      struct set_copied_baton_t set_copied_baton;
-
-      /* Set the 'copied' flag recursively, to support the
-       * cases where this is a directory. */
-      set_copied_baton.db = db;
-      set_copied_baton.added_subtree_root_path = local_abspath;
-      SVN_ERR(svn_wc__internal_walk_children(db, local_abspath, FALSE,
-                                             set_copied_callback,
-                                             &set_copied_baton,
-                                             svn_depth_infinity,
-                                             NULL, NULL, pool));
-
-      /* If PATH is a directory then we must also record in PARENT_PATH's
-         entry that we are re-adding PATH. */
-      flags &= ~SVN_WC__ENTRY_MODIFY_URL;
-      SVN_ERR(svn_wc__entry_modify2(db, local_abspath, svn_node_dir, TRUE,
-                                   &tmp_entry, flags, pool));
-
-      /* ### Need to do something more, such as change 'base' into
-         ### 'revert-base'? */
-    }
-
-  return SVN_NO_ERROR;
-}
-
 /* Delete PATH from its immediate parent PARENT_PATH, in the edit
  * represented by EB. PATH is relative to EB->anchor.
  * PARENT_PATH is relative to the current working directory.
@@ -2368,9 +2157,9 @@ do_entry_deletion(struct edit_baton *eb,
           SVN_ERR(svn_wc__wq_add_loggy(eb->db, dir_abspath, log_item, pool));
           SVN_ERR(svn_wc__run_log2(eb->db, dir_abspath, pool));
 
-          SVN_ERR(schedule_existing_item_for_re_add(eb->db, local_abspath,
-                                                    their_relpath, TRUE,
-                                                    pool));
+          SVN_ERR(svn_wc__db_temp_op_make_copy(eb->db, local_abspath, TRUE,
+                                               pool));
+
           return SVN_NO_ERROR;
         }
       else if (tree_conflict->reason == svn_wc_conflict_reason_deleted)
@@ -2397,9 +2186,9 @@ do_entry_deletion(struct edit_baton *eb,
           SVN_ERR(svn_wc__wq_add_loggy(eb->db, dir_abspath, log_item, pool));
           SVN_ERR(svn_wc__run_log2(eb->db, dir_abspath, pool));
 
-          SVN_ERR(schedule_existing_item_for_re_add(eb->db, local_abspath,
-                                                    their_relpath, FALSE,
-                                                    pool));
+          SVN_ERR(svn_wc__db_temp_op_make_copy(eb->db, local_abspath, TRUE,
+                                               pool));
+
           return SVN_NO_ERROR;
         }
       else

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=923019&r1=923018&r2=923019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Mon Mar 15 00:29:53 
2010
@@ -329,6 +329,32 @@ SELECT wc_id, local_relpath, parent_relp
     symlink_target, last_mod_time FROM BASE_NODE
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
+-- STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE
+INSERT INTO WORKING_NODE (
+    wc_id, local_relpath, parent_relpath, presence, kind, checksum,
+    translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties, copyfrom_repos_id,
+    copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, local_relpath, parent_relpath, 'normal', kind, checksum,
+    translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties, repos_id,
+    repos_relpath, revnum FROM BASE_NODE
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE
+INSERT INTO WORKING_NODE (
+    wc_id, local_relpath, parent_relpath, presence, kind, changed_rev,
+    changed_date, changed_author, copyfrom_repos_id,
+    copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, local_relpath, parent_relpath, 'not-present', kind, changed_rev,
+    changed_date, changed_author, repos_id,
+    repos_relpath, revnum FROM BASE_NODE
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_COPYFROM (
+UPDATE WORKING_NODE set copyfrom_repos_id = ?3, copyfrom_repos_path = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 /* ------------------------------------------------------------------------- */
 
 /* 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=923019&r1=923018&r2=923019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon Mar 15 00:29:53 2010
@@ -6438,3 +6438,330 @@ svn_wc__db_temp_op_start_directory_updat
 
   return SVN_NO_ERROR;
 }
+
+/* Baton for make_copy_txn */
+struct make_copy_baton
+{
+  svn_wc__db_t *db;
+  const char *local_abspath;
+
+  svn_wc__db_pdh_t *pdh;
+  const char *local_relpath;
+  svn_boolean_t remove_base;
+  svn_boolean_t is_root;
+};
+
+/* Transaction callback for svn_wc__db_temp_op_make_copy */
+static svn_error_t *
+make_copy_txn(void *baton,
+              svn_sqlite__db_t *sdb,
+              apr_pool_t *scratch_pool)
+{
+  struct make_copy_baton *mcb = baton;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  svn_boolean_t remove_working = FALSE;
+  svn_boolean_t check_base = TRUE;
+  svn_boolean_t add_working_normal = FALSE;
+  svn_boolean_t add_working_not_present = FALSE;
+  const apr_array_header_t *children;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  int i;
+
+  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));
+
+  if (have_row)
+    {
+      svn_wc__db_status_t working_status;
+
+      working_status = svn_sqlite__column_token(stmt, 0, presence_map);
+      SVN_ERR(svn_sqlite__reset(stmt));
+
+      SVN_ERR_ASSERT(working_status == svn_wc__db_status_normal
+                     || working_status == svn_wc__db_status_base_deleted
+                     || working_status == svn_wc__db_status_not_present
+                     || working_status == svn_wc__db_status_incomplete);
+
+      /* Make existing deletions of BASE_NODEs remove WORKING_NODEs */
+      if (working_status == svn_wc__db_status_base_deleted)
+        {
+          remove_working = TRUE;
+          add_working_not_present = TRUE;
+        }
+
+      check_base = FALSE;
+    }
+  else
+    SVN_ERR(svn_sqlite__reset(stmt));
+
+  if (check_base)
+    {
+      svn_wc__db_status_t base_status;
+
+      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));
+
+      /* If there is no BASE_NODE, we don't have to copy anything */
+      if (!have_row)
+        return svn_error_return(svn_sqlite__reset(stmt));
+
+      base_status = svn_sqlite__column_token(stmt, 2, presence_map);
+
+      SVN_ERR(svn_sqlite__reset(stmt));
+
+      switch (base_status)
+        {
+          case svn_wc__db_status_normal:
+          case svn_wc__db_status_incomplete:
+            add_working_normal = TRUE;
+            break;
+          case svn_wc__db_status_not_present:
+            add_working_not_present = TRUE;
+            break;
+          case svn_wc__db_status_excluded:
+          case svn_wc__db_status_absent:
+            /* ### Make the copy match the WC or the repository? */
+            add_working_not_present = TRUE; /* ### Match WC */
+            break;
+          default:
+            SVN_ERR_MALFUNCTION();
+        }
+    }
+
+  /* Get the BASE children, as WORKING children don't need modifications */
+  SVN_ERR(svn_wc__db_base_get_children(&children, mcb->db, mcb->local_abspath,
+                                       scratch_pool, iterpool));
+
+  for (i = 0; i < children->nelts; i++)
+    {
+      const char *name = APR_ARRAY_IDX(children, i, const char *);
+      struct make_copy_baton cbt;
+
+      svn_pool_clear(iterpool);
+      cbt.local_abspath = svn_dirent_join(mcb->local_abspath, name, iterpool);
+
+      SVN_ERR(parse_local_abspath(&cbt.pdh, &cbt.local_relpath, mcb->db,
+                                  cbt.local_abspath,
+                                  svn_sqlite__mode_readwrite,
+                                  iterpool, iterpool));
+
+      VERIFY_USABLE_PDH(cbt.pdh);
+
+      cbt.db = mcb->db;
+      cbt.remove_base = mcb->remove_base;
+      cbt.is_root = FALSE;
+
+      SVN_ERR(make_copy_txn(&cbt, cbt.pdh->wcroot->sdb, iterpool));
+    }
+
+  if (remove_working)
+    {
+      /* Remove current WORKING_NODE record */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_DELETE_WORKING_NODE));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  if (add_working_normal)
+    {
+      /* Add a copy of the BASE_NODE to WORKING_NODE */
+
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, sdb,
+                        STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+  else if (add_working_not_present)
+    {
+      /* Add a not present WORKING_NODE */
+
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, sdb,
+                        STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  if (mcb->is_root && (add_working_normal || add_working_not_present))
+    {
+      const char *repos_relpath, *repos_root_url, *repos_uuid;
+      apr_int64_t repos_id;
+      /* Make sure the copy origin is set on the root even if the node
+         didn't have a local relpath */
+
+      SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
+                                         &repos_uuid, mcb->db,
+                                         mcb->local_abspath,
+                                         iterpool, iterpool));
+
+      SVN_ERR(create_repos_id(&repos_id, repos_root_url, repos_uuid, sdb,
+                              iterpool));
+
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPDATE_COPYFROM));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isis",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath,
+                                repos_id,
+                                repos_relpath));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  /* And now, do the same for the parent stub :( */
+  if (remove_working)
+    {
+      const char *local_relpath;
+      svn_wc__db_pdh_t *pdh;
+
+      /* Remove WORKING_NODE stub */
+      SVN_ERR(navigate_to_parent(&pdh, mcb->db, mcb->pdh,
+                                 svn_sqlite__mode_readwrite,
+                                 iterpool));
+      local_relpath = svn_dirent_basename(mcb->local_abspath, NULL);
+      VERIFY_USABLE_PDH(pdh);
+
+      SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                        STMT_DELETE_WORKING_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                pdh->wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  if (add_working_normal)
+    {
+      const char *local_relpath;
+      svn_wc__db_pdh_t *pdh;
+
+      /* Add a copy of the BASE_NODE to WORKING_NODE for the stub */
+      SVN_ERR(navigate_to_parent(&pdh, mcb->db, mcb->pdh,
+                                 svn_sqlite__mode_readwrite,
+                                 iterpool));
+      local_relpath = svn_dirent_basename(mcb->local_abspath, NULL);
+      VERIFY_USABLE_PDH(pdh);
+
+      /* Remove old data */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                        STMT_DELETE_WORKING_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                pdh->wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+
+      /* And insert the right data */
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, pdh->wcroot->sdb,
+                        STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                pdh->wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+  else if (add_working_not_present)
+    {
+      const char *local_relpath;
+      svn_wc__db_pdh_t *pdh;
+
+      /* Add a not present WORKING_NODE stub */
+      SVN_ERR(navigate_to_parent(&pdh, mcb->db, mcb->pdh,
+                                 svn_sqlite__mode_readwrite,
+                                 iterpool));
+      local_relpath = svn_dirent_basename(mcb->local_abspath, NULL);
+      VERIFY_USABLE_PDH(pdh);
+
+      /* Remove old data */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                        STMT_DELETE_WORKING_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                pdh->wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+
+      /* And insert the right data */
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, pdh->wcroot->sdb,
+                        STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                pdh->wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  /* Remove the BASE_NODE if the caller asked us to do that */
+  if (mcb->remove_base)
+    {
+      const char *local_relpath;
+      svn_wc__db_pdh_t *pdh;
+
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_DELETE_BASE_NODE));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
+
+      /* Remove BASE_NODE_STUB */
+      SVN_ERR(navigate_to_parent(&pdh, mcb->db, mcb->pdh,
+                                 svn_sqlite__mode_readwrite,
+                                 iterpool));
+      local_relpath = svn_dirent_basename(mcb->local_abspath, NULL);
+      VERIFY_USABLE_PDH(pdh);
+
+      SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                        STMT_DELETE_BASE_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                pdh->wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  svn_pool_destroy(iterpool);
+
+  flush_entries(mcb->pdh);
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__db_temp_op_make_copy(svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_boolean_t remove_base,
+                             apr_pool_t *scratch_pool)
+{
+  struct make_copy_baton mcb;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(parse_local_abspath(&mcb.pdh, &mcb.local_relpath, db, local_abspath,
+                              svn_sqlite__mode_readwrite,
+                              scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(mcb.pdh);
+
+  mcb.db = db;
+  mcb.local_abspath = local_abspath;
+  mcb.is_root = TRUE;
+
+  SVN_ERR(svn_sqlite__with_transaction(mcb.pdh->wcroot->sdb,
+                                       make_copy_txn, &mcb,
+                                       scratch_pool));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=923019&r1=923018&r2=923019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Mon Mar 15 00:29:53 2010
@@ -2057,6 +2057,18 @@ svn_wc__db_temp_op_start_directory_updat
                                           svn_revnum_t new_rev,
                                           apr_pool_t *scratch_pool);
 
+/* Update WORKING_NODE to make it represent a copy of the current working
+   copy. Leaving additions and copies as-is, but making a copy of all the
+   required BASE_NODE data to WORKING_NODE, to allow removing and/or
+   updating the BASE_NODE without changing the contents of the current
+   working copy */
+svn_error_t *
+svn_wc__db_temp_op_make_copy(svn_wc__db_t *db,
+                             const char *local_abspath,
+                             svn_boolean_t remove_base,
+                             apr_pool_t *scratch_pool);
+
+
 /** @} */
 
 


Reply via email to