Author: rhuijben
Date: Mon May  9 19:49:44 2011
New Revision: 1101171

URL: http://svn.apache.org/viewvc?rev=1101171&view=rev
Log:
Implement the insertion and reading of nodes in the EXTERNALS table.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_INSERT_EXTERNAL): New query.
  (STMT_SELECT_EXTERNAL_INFO,
   STMT_SELECT_EXTERNAL_INFO_WITH_LOCK): New queries for external_read()
  (STMT_SELECT_EXTERNAL_CHILDREN,
   STMT_SELECT_EXTERNALS_DEFINED): New queries for fetching file externals
     in a directory and defined on a parent dir.

* subversion/libsvn_wc/wc_db.c
  (insert_external_node): Implement for format 29.
  (svn_wc__db_external_read): Implement for format 29. Make sure old error text
    matches the new one.

* subversion/tests/libsvn_wc/db-test.c
  (create_fake_wc): Insert externals table.
  (test_externals_store): New function to test the new (or the old) file
    externals storage.
  (test_funcs): Add test_externals_store.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/tests/libsvn_wc/db-test.c

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1101171&r1=1101170&r2=1101171&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Mon May  9 19:49:44 
2011
@@ -814,6 +814,43 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 -- STMT_SELECT_ACTUAL_CHILDREN
 SELECT 1 FROM actual_node WHERE wc_id = ?1 AND parent_relpath = ?2
 
+-- STMT_INSERT_EXTERNAL
+INSERT OR REPLACE INTO externals (
+    wc_id, local_relpath, parent_relpath, repos_id, repos_path, revision,
+    kind, symlink_target, changed_revision, changed_date, changed_author,
+    record_relpath, recorded_url, recorded_operational_revision,
+    recorded_revision, checksum, properties, dav_cache)
+VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16,
+        ?17, ?18)
+
+-- STMT_SELECT_EXTERNAL_INFO
+SELECT kind, revision, repos_id, repos_path, properties, checksum,
+    symlink_target, changed_revision, changed_date, changed_author,
+    translated_size, last_mod_time, record_relpath, recorded_url,
+    recorded_operational_revision, recorded_revision,
+FROM externals WHERE wc_id = ?1 AND local_relpath = ?2
+LIMIT 1
+
+-- STMT_SELECT_EXTERNAL_INFO_WITH_LOCK
+SELECT kind, revision, externals.repos_id, externals.repos_path, properties,
+    checksum, symlink_target, changed_revision, changed_date, changed_author,
+    translated_size, last_mod_time, record_relpath, recorded_url,
+    recorded_operational_revision, recorded_revision,
+    lock_token, lock_owner, lock_comment, lock_date
+FROM externals
+LEFT OUTER JOIN lock ON externals.repos_id = lock.repos_id
+  AND externals.repos_path = lock.repos_relpath
+ WHERE wc_id = ?1 AND local_relpath = ?2
+LIMIT 1
+
+-- STMT_SELECT_EXTERNAL_CHILDREN
+SELECT local_relpath
+FROM externals WHERE wc_id = ?1 AND parent_relpath = ?2
+
+-- STMT_SELECT_EXTERNALS_DEFINED
+SELECT local_relpath
+FROM externals WHERE wc_id = ?1 AND record_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=1101171&r1=1101170&r2=1101171&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon May  9 19:49:44 2011
@@ -2613,7 +2613,70 @@ insert_external_node(void *baton,
   }
   return SVN_NO_ERROR;
 #else
-  NOT_IMPLEMENTED();
+  apr_int64_t repos_id;
+  svn_sqlite__stmt_t *stmt;
+
+  if (ieb->repos_id != INVALID_REPOS_ID)
+    repos_id = ieb->repos_id;
+  else
+    SVN_ERR(create_repos_id(&repos_id, ieb->repos_root_url, ieb->repos_uuid,
+                            wcroot->sdb, scratch_pool));
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_EXTERNAL));
+
+  if (ieb->kind != svn_wc__db_kind_dir)
+    {
+      SVN_ERR(svn_sqlite__bindf(stmt, "issisrtsrisss",
+                                wcroot->wc_id,
+                                local_relpath,
+                                svn_relpath_dirname(local_relpath,
+                                                    scratch_pool),
+                                repos_id,
+                                ieb->repos_relpath,
+                                ieb->revision,
+                                kind_map, ieb->kind,
+                                (ieb->kind == svn_wc__db_kind_symlink)
+                                            ? ieb->target
+                                            : NULL,
+                                ieb->changed_rev,
+                                ieb->changed_date,
+                                ieb->changed_author,
+                                ieb->record_ancestor_relpath,
+                                ieb->recorded_repos_relpath));
+
+      if (ieb->checksum)
+        SVN_ERR(svn_sqlite__bind_checksum(stmt, 16, ieb->checksum,
+                                          scratch_pool));
+
+      if (ieb->props)
+        SVN_ERR(svn_sqlite__bind_properties(stmt, 17, ieb->props,
+                                            scratch_pool));
+
+      if (ieb->dav_cache)
+        SVN_ERR(svn_sqlite__bind_properties(stmt, 18, ieb->dav_cache,
+                                            scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(svn_sqlite__bindf(stmt, "issnnntnnnnss",
+                                wcroot->wc_id,
+                                local_relpath,
+                                svn_relpath_dirname(local_relpath,
+                                                    scratch_pool),
+                                kind_map, ieb->kind,
+                                ieb->record_ancestor_relpath,
+                                ieb->recorded_repos_relpath));
+    }
+
+  if (SVN_IS_VALID_REVNUM(ieb->recorded_peg_revision))
+    SVN_ERR(svn_sqlite__bind_revnum(stmt, 14, ieb->recorded_peg_revision));
+
+  if (SVN_IS_VALID_REVNUM(ieb->recorded_revision))
+    SVN_ERR(svn_sqlite__bind_revnum(stmt, 15, ieb->recorded_revision));
+
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+  return SVN_NO_ERROR;
 #endif
 }
 
@@ -2895,7 +2958,11 @@ svn_wc__db_external_read(svn_wc__db_kind
 {
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
-
+#if SVN_WC__VERSION >= SVN_WC__HAS_EXTERNALS_STORE
+  svn_sqlite__stmt_t *stmt, *stmt_act = NULL;
+  svn_boolean_t have_info, have_act;
+  svn_error_t *err;
+#endif
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
   if (! wri_abspath)
@@ -2928,7 +2995,7 @@ svn_wc__db_external_read(svn_wc__db_kind
         || base_kind == svn_wc__db_kind_dir)
       {
         return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
-                                 _("Node '%s' is not an external"),
+                                 _("The node '%s' is not an external"),
                                  svn_dirent_local_style(local_abspath,
                                                         scratch_pool));
       }
@@ -2976,7 +3043,116 @@ svn_wc__db_external_read(svn_wc__db_kind
     return SVN_NO_ERROR;
   }
 #else
-  NOT_IMPLEMENTED();
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    lock ? STMT_SELECT_EXTERNAL_INFO_WITH_LOCK
+                                         : STMT_SELECT_EXTERNAL_INFO));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_info, stmt));
+
+  if (conflicted || props_mod)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt_act, wcroot->sdb,
+                                        STMT_SELECT_ACTUAL_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt_act, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step(&have_act, stmt_act));
+    }
+
+  if (have_info)
+    {
+      apr_int64_t repos_id;
+      if (kind)
+        *kind = svn_sqlite__column_token(stmt, 0, kind_map);
+
+      err = repos_location_from_columns(&repos_id, revision, repos_relpath,
+                                        stmt, 2, 1, 3, result_pool);
+
+      if (repos_root_url || repos_uuid)
+        {
+          err = svn_error_compose_create(
+                        err,
+                        fetch_repos_info(repos_root_url, repos_uuid,
+                                         wcroot->sdb, repos_id, result_pool));
+        }
+
+      if (changed_rev)
+        *changed_rev = svn_sqlite__column_revnum(stmt, 7);
+      if (changed_author)
+        *changed_author = svn_sqlite__column_text(stmt, 9, result_pool);
+      if (changed_date)
+        *changed_date = svn_sqlite__column_int64(stmt, 8);
+
+      if (checksum)
+        {
+          err = svn_error_compose_create(
+                        err,
+                        svn_sqlite__column_checksum(checksum, stmt, 5,
+                                                    result_pool));
+        }
+      if (target)
+        *target = svn_sqlite__column_text(stmt, 6, result_pool);
+
+      if (lock)
+        *lock = lock_from_columns(stmt, 16, 17, 18, 19, result_pool);
+
+      if (recorded_size)
+        *recorded_size = get_recorded_size(stmt, 10);
+      if (recorded_mod_time)
+        *recorded_mod_time = svn_sqlite__column_int64(stmt, 11);
+
+      if (record_ancestor_abspath)
+        {
+          const char *record_relpath = svn_sqlite__column_text(stmt, 12, NULL);
+
+          *record_ancestor_abspath = svn_dirent_join(wcroot->abspath,
+                                                     record_relpath,
+                                                     result_pool);
+        }
+
+      if (recorded_repos_relpath)
+        *recorded_repos_relpath = svn_sqlite__column_text(stmt, 13,
+                                                          result_pool);
+
+      if (recorded_peg_revision)
+        *recorded_peg_revision = svn_sqlite__column_revnum(stmt, 14);
+
+      if (recorded_revision)
+        *recorded_revision = svn_sqlite__column_revnum(stmt, 15);
+
+      if (had_props)
+        *had_props = SQLITE_PROPERTIES_AVAILABLE(stmt, 4);
+
+      if (props_mod)
+        {
+          *props_mod = have_act && !svn_sqlite__column_is_null(stmt_act, 6);
+        }
+      if (conflicted)
+        {
+          if (have_act)
+            {
+              *conflicted =
+                 !svn_sqlite__column_is_null(stmt_act, 2) || /* old */
+                 !svn_sqlite__column_is_null(stmt_act, 3) || /* new */
+                 !svn_sqlite__column_is_null(stmt_act, 4) || /* working */
+                 !svn_sqlite__column_is_null(stmt_act, 0) || /* prop_reject */
+                 !svn_sqlite__column_is_null(stmt_act, 5); /* 
tree_conflict_data */
+            }
+          else
+            *conflicted = FALSE;
+        }
+    }
+  else
+    {
+      err = svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                              _("The node '%s' is not an external."),
+                              svn_dirent_local_style(local_abspath,
+                                                     scratch_pool));
+    }
+
+  if (stmt_act != NULL)
+    err = svn_error_compose_create(err, svn_sqlite__reset(stmt_act));
+
+  return svn_error_return(
+                svn_error_compose_create(err, svn_sqlite__reset(stmt)));
 #endif
 }
 

Modified: subversion/trunk/subversion/tests/libsvn_wc/db-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/db-test.c?rev=1101171&r1=1101170&r2=1101171&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/db-test.c Mon May  9 19:49:44 
2011
@@ -330,6 +330,7 @@ create_fake_wc(const char *subdir, int f
     statements[STMT_CREATE_SCHEMA],
     statements[STMT_CREATE_NODES],
     statements[STMT_CREATE_NODES_TRIGGERS],
+    statements[STMT_CREATE_EXTERNALS],
     TESTING_DATA,
     NULL
   };
@@ -1398,6 +1399,163 @@ test_work_queue(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_externals_store(apr_pool_t *pool)
+{
+  svn_wc__db_t *db;
+  const char *local_abspath;
+  svn_checksum_t *orig_checksum;
+  const char *file_external_path;
+  const char *dir_external_path;
+  const char *subdir;
+
+  SVN_ERR(create_open(&db, &local_abspath,
+                      "test_externals_store", SVN_WC__VERSION, pool));
+
+  /* Directory I exists in the standard test db */
+  subdir = svn_dirent_join(local_abspath, "I", pool);
+
+  SVN_ERR(svn_checksum_parse_hex(&orig_checksum, svn_checksum_sha1, SHA1_1,
+                                 pool));
+
+  file_external_path = svn_dirent_join(subdir, "file-external", pool);
+  dir_external_path = svn_dirent_join(subdir, "dir-external", pool);
+
+  SVN_ERR(svn_wc__db_external_add_file(db,
+                                       file_external_path,
+                                       local_abspath /* wri_abspath */,
+                                       "some/location",
+                                       "svn://some-repos/svn",
+                                       "not-a-uuid",
+                                       12,
+                                       apr_hash_make(pool),
+                                       10,
+                                       987654,
+                                       "somebody",
+                                       orig_checksum,
+                                       NULL,
+                                       subdir,
+                                       "some/new-location",
+                                       90,
+                                       12,
+                                       FALSE, NULL,
+                                       FALSE,
+                                       NULL,
+                                       pool));
+
+#if SVN_WC__VERSION >= SVN_WC__HAS_EXTERNALS_STORE
+  SVN_ERR(svn_wc__db_external_add_dir(db,
+                                      dir_external_path,
+                                      local_abspath /* wri_abspath */,
+                                      subdir,
+                                      "some/other-location",
+                                      70,
+                                      32,
+                                      NULL,
+                                      pool));
+#endif
+
+  {
+    svn_wc__db_kind_t kind;
+    svn_revnum_t revision;
+    const char *repos_relpath;
+    const char *repos_root_url;
+    const char *repos_uuid;
+    svn_revnum_t changed_rev;
+    apr_time_t changed_date;
+    const char *changed_author;
+    const svn_checksum_t *checksum;
+    const char *target;
+    svn_wc__db_lock_t *lock;
+    svn_filesize_t recorded_size;
+    apr_time_t recorded_mod_time;
+    const char *record_ancestor_abspath;
+    const char *recorded_repos_relpath;
+    svn_revnum_t recorded_peg_revision;
+    svn_revnum_t recorded_revision;
+    svn_boolean_t conflicted;
+    svn_boolean_t had_props;
+    svn_boolean_t props_mod;
+
+    SVN_ERR(svn_wc__db_external_read(&kind, &revision, &repos_relpath,
+                                     &repos_root_url, &repos_uuid,
+                                     &changed_rev, &changed_date,
+                                     &changed_author, &checksum, &target,
+                                     &lock, &recorded_size, &recorded_mod_time,
+                                     &record_ancestor_abspath,
+                                     &recorded_repos_relpath,
+                                     &recorded_peg_revision,
+                                     &recorded_revision, &conflicted,
+                                     &had_props, &props_mod,
+                                     db, file_external_path, local_abspath,
+                                     pool, pool));
+
+    SVN_DBG(("Revision: %d (%s)\n", (int)revision, local_abspath));
+
+    SVN_TEST_ASSERT(kind == svn_wc__db_kind_file);
+    SVN_TEST_ASSERT(revision == 12);
+    SVN_TEST_STRING_ASSERT(repos_relpath, "some/location");
+    SVN_TEST_STRING_ASSERT(repos_root_url, "svn://some-repos/svn");
+    SVN_TEST_STRING_ASSERT(repos_uuid, "not-a-uuid");
+    SVN_TEST_ASSERT(changed_rev == 10);
+    SVN_TEST_ASSERT(changed_date == 987654);
+    SVN_TEST_STRING_ASSERT(changed_author, "somebody");
+    SVN_TEST_ASSERT(svn_checksum_match(orig_checksum, checksum));
+    SVN_TEST_ASSERT(target == NULL);
+    SVN_TEST_ASSERT(lock == NULL);
+    SVN_TEST_ASSERT(recorded_size == SVN_INVALID_FILESIZE);
+    SVN_TEST_ASSERT(recorded_mod_time == 0);
+#if SVN_WC__VERSION >= SVN_WC__HAS_EXTERNALS_STORE
+    SVN_TEST_STRING_ASSERT(record_ancestor_abspath, subdir);
+#else
+    SVN_TEST_ASSERT(record_ancestor_abspath == NULL);
+#endif
+    SVN_TEST_STRING_ASSERT(recorded_repos_relpath, "some/new-location");
+    SVN_TEST_ASSERT(recorded_peg_revision == 90);
+    SVN_TEST_ASSERT(recorded_revision == 12);
+    SVN_TEST_ASSERT(!conflicted);
+    SVN_TEST_ASSERT(!had_props);
+    SVN_TEST_ASSERT(!props_mod);
+
+#if SVN_WC__VERSION >= SVN_WC__HAS_EXTERNALS_STORE
+    SVN_ERR(svn_wc__db_external_read(&kind, &revision, &repos_relpath,
+                                     &repos_root_url, &repos_uuid,
+                                     &changed_rev, &changed_date,
+                                     &changed_author, &checksum, &target,
+                                     &lock, &recorded_size, &recorded_mod_time,
+                                     &record_ancestor_abspath,
+                                     &recorded_repos_relpath,
+                                     &recorded_peg_revision,
+                                     &recorded_revision, &conflicted,
+                                     &had_props, &props_mod,
+                                     db, dir_external_path, local_abspath,
+                                     pool, pool));
+
+    SVN_TEST_ASSERT(kind == svn_wc__db_kind_dir);
+    SVN_TEST_ASSERT(revision == SVN_INVALID_REVNUM);
+    SVN_TEST_ASSERT(repos_relpath == NULL);
+    SVN_TEST_ASSERT(repos_root_url == NULL);
+    SVN_TEST_ASSERT(repos_uuid == NULL);
+    SVN_TEST_ASSERT(changed_rev == SVN_INVALID_REVNUM);
+    SVN_TEST_ASSERT(changed_date == 0);
+    SVN_TEST_ASSERT(changed_author == NULL);
+    SVN_TEST_ASSERT(checksum == NULL);
+    SVN_TEST_ASSERT(target == NULL);
+    SVN_TEST_ASSERT(lock == NULL);
+    SVN_TEST_ASSERT(recorded_size == SVN_INVALID_FILESIZE);
+    SVN_TEST_ASSERT(recorded_mod_time == 0);
+    SVN_TEST_STRING_ASSERT(record_ancestor_abspath, subdir);
+    SVN_TEST_STRING_ASSERT(recorded_repos_relpath, "some/other-location");
+    SVN_TEST_ASSERT(recorded_peg_revision == 70);
+    SVN_TEST_ASSERT(recorded_revision == 32);
+    SVN_TEST_ASSERT(!conflicted);
+    SVN_TEST_ASSERT(!had_props);
+    SVN_TEST_ASSERT(!props_mod);
+#endif
+  }
+
+  return SVN_NO_ERROR;
+}
 
 struct svn_test_descriptor_t test_funcs[] =
   {
@@ -1422,5 +1580,7 @@ struct svn_test_descriptor_t test_funcs[
                    "upgrading to format 15"),
     SVN_TEST_PASS2(test_work_queue,
                    "work queue processing"),
+    SVN_TEST_PASS2(test_externals_store,
+                   "externals store"),
     SVN_TEST_NULL
   };


Reply via email to