Author: rhuijben
Date: Wed May 11 22:46:07 2011
New Revision: 1102121

URL: http://svn.apache.org/viewvc?rev=1102121&view=rev
Log:
Extend the EXTERNALS schema with a simple presence column for holding just
status normal and excluded. Also apply a few additional constraints and
define that the repository root must be available for dir externals.
Update the libsvn_wc api to allow access to the new data.

* subversion/libsvn_wc/externals.c
  (open_file,
   close_file,
   svn_wc__crawl_file_external,
   svn_wc__read_external_info): Update callers.

* subversion/libsvn_wc/wc-metadata.sql
  (STMT_CREATE_EXTERNALS): Add constraint to repos_id. Add presence.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_INSERT_EXTERNAL,
   STMT_SELECT_EXTERNAL_INFO,
   STMT_SELECT_EXTERNAL_INFO_WITH_LOCK): Add presence.

* subversion/libsvn_wc/wc_db.c
  (insert_external_baton_t): Documentation fix. Add presence.
  (insert_external_node): Add presence handling.
  (svn_wc__db_external_add_file): Update caller.
  (svn_wc__db_external_add_symlink): Update caller. Add missing call to
    blank_ieb().
  (svn_wc__db_external_add_dir): Add two arguments. Blank the ibb and
    update caller.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_external_add_dir): Add two arguments.
  (svn_wc__db_external_read): Extend documentation.

* subversion/tests/libsvn_wc/db-test.c
  (test_externals_store): Update caller.

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

Modified: subversion/trunk/subversion/libsvn_wc/externals.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/externals.c?rev=1102121&r1=1102120&r2=1102121&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/externals.c (original)
+++ subversion/trunk/subversion/libsvn_wc/externals.c Wed May 11 22:46:07 2011
@@ -442,7 +442,7 @@ open_file(const char *path,
                                                       file_pool));
 
   *file_baton = eb;
-  SVN_ERR(svn_wc__db_external_read(&kind, &eb->original_revision,
+  SVN_ERR(svn_wc__db_external_read(NULL, &kind, &eb->original_revision,
                                    NULL, NULL, NULL, NULL, NULL, NULL,
                                    &eb->original_checksum, NULL, NULL, NULL,
                                    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -558,8 +558,9 @@ close_file(void *file_baton,
       if (actual_md5_checksum == NULL)
         {
           SVN_ERR(svn_wc__db_external_read(NULL, NULL, NULL, NULL, NULL, NULL,
-                                           NULL, NULL, &actual_md5_checksum, 
-                                           NULL, NULL, NULL, NULL, NULL, NULL,
+                                           NULL, NULL, NULL,
+                                           &actual_md5_checksum, NULL,
+                                           NULL, NULL, NULL, NULL, NULL,
                                            NULL, NULL, NULL, NULL, NULL,
                                            eb->db, eb->local_abspath,
                                            eb->wri_abspath,
@@ -618,7 +619,7 @@ close_file(void *file_baton,
         svn_boolean_t had_props;
         svn_boolean_t props_mod;
 
-        SVN_ERR(svn_wc__db_external_read(NULL, NULL, NULL, NULL, NULL,
+        SVN_ERR(svn_wc__db_external_read(NULL, NULL, NULL, NULL, NULL, NULL,
                                          &changed_rev, &changed_date,
                                          &changed_author, &original_checksum,
                                          NULL, NULL, NULL, NULL, NULL, NULL,
@@ -986,7 +987,7 @@ svn_wc__crawl_file_external(svn_wc_conte
   if (! wri_abspath)
     wri_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
-  err = svn_wc__db_external_read(&kind, &revision,
+  err = svn_wc__db_external_read(NULL, &kind, &revision,
                                  &repos_relpath, &repos_root_url, NULL, NULL,
                                  NULL, NULL, NULL, NULL, &lock, NULL, NULL,
                                  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1076,10 +1077,11 @@ svn_wc__read_external_info(svn_node_kind
                            apr_pool_t *scratch_pool)
 {
   const char *repos_root_url;
+  svn_wc__db_status_t status;
   svn_wc__db_kind_t kind;
   svn_error_t *err;
 
-  err = svn_wc__db_external_read(&kind, NULL, NULL,
+  err = svn_wc__db_external_read(&status, &kind, NULL, NULL,
                                  defining_url ? &repos_root_url : NULL,
                                  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                  NULL, NULL, defining_abspath, defining_url,
@@ -1136,18 +1138,23 @@ svn_wc__read_external_info(svn_node_kind
     }
 
   if (external_kind)
-    switch(kind)
-      {
-        case svn_wc__db_kind_file:
-        case svn_wc__db_kind_symlink:
-          *external_kind = svn_node_file;
-          break;
-        case svn_wc__db_kind_dir:
-          *external_kind = svn_node_dir;
-          break;
-        default:
-          *external_kind = svn_node_none;
-      }
+    {
+      if (status != svn_wc__db_status_normal)
+        *external_kind = svn_node_unknown;
+      else
+        switch(kind)
+          {
+            case svn_wc__db_kind_file:
+            case svn_wc__db_kind_symlink:
+              *external_kind = svn_node_file;
+              break;
+            case svn_wc__db_kind_dir:
+              *external_kind = svn_node_dir;
+              break;
+            default:
+              *external_kind = svn_node_none;
+          }
+    }
 
 #if SVN_WC__VERSION < SVN_WC__HAS_EXTERNALS_STORE
   if (defining_abspath && !*defining_abspath)

Modified: subversion/trunk/subversion/libsvn_wc/wc-metadata.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-metadata.sql?rev=1102121&r1=1102120&r2=1102121&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-metadata.sql Wed May 11 22:46:07 
2011
@@ -543,12 +543,15 @@ CREATE TABLE EXTERNALS (
   parent_relpath  TEXT NOT NULL,
 
   /* Repository location fields */
+  repos_id  INTEGER NOT NULL REFERENCES REPOSITORY (id),
 
   /* Always set for file and symlink externals. NULL for directory externals */
-  repos_id  INTEGER REFERENCES REPOSITORY (id),
   repos_path  TEXT,
   revision  INTEGER,
 
+  /* Either 'normal' or 'excluded' */
+  presence  TEXT NOT NULL,
+
   /* Content fields */
 
   /* the kind of the external. */

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1102121&r1=1102120&r2=1102121&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed May 11 22:46:07 
2011
@@ -813,17 +813,17 @@ SELECT 1 FROM actual_node WHERE wc_id = 
 -- 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,
-    def_local_relpath, def_repos_relpath, def_operational_revision,
-    def_revision, checksum, properties, dav_cache)
+    presence, kind, symlink_target, changed_revision, changed_date,
+    changed_author, def_local_relpath, def_repos_relpath,
+    def_operational_revision, def_revision, checksum, properties, dav_cache)
 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16,
-        ?17, ?18)
+        ?17, ?18, ?19)
 
 -- STMT_SELECT_EXTERNAL_INFO
 SELECT kind, revision, repos_id, repos_path, properties, checksum,
     symlink_target, changed_revision, changed_date, changed_author,
     recorded_size, recorded_mod_time, def_local_relpath, def_repos_relpath,
-    def_operational_revision, def_revision
+    def_operational_revision, def_revision, presence
 FROM externals WHERE wc_id = ?1 AND local_relpath = ?2
 LIMIT 1
 
@@ -831,7 +831,7 @@ LIMIT 1
 SELECT kind, revision, externals.repos_id, externals.repos_path, properties,
     checksum, symlink_target, changed_revision, changed_date, changed_author,
     recorded_size, recorded_mod_time, def_local_relpath, def_repos_relpath,
-    def_operational_revision, def_revision,
+    def_operational_revision, def_revision, presence,
     lock_token, lock_owner, lock_comment, lock_date
 FROM externals
 LEFT OUTER JOIN lock ON externals.repos_id = lock.repos_id

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1102121&r1=1102120&r2=1102121&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed May 11 22:46:07 2011
@@ -223,11 +223,13 @@ typedef struct insert_working_baton_t {
 } insert_working_baton_t;
 
 typedef struct insert_external_baton_t {
-  /* common to all insertions into BASE */
+  /* common to all insertions into EXTERNALS */
   svn_wc__db_kind_t kind;
-
-  /* for file and symlink externals */
+  svn_wc__db_status_t presence;
+  
+  /* The repository of the external */
   apr_int64_t repos_id;
+  /* for file and symlink externals */
   const char *repos_relpath;
   svn_revnum_t revision;
 
@@ -2625,6 +2627,10 @@ insert_external_node(void *baton,
   apr_int64_t repos_id;
   svn_sqlite__stmt_t *stmt;
 
+  /* Externals only support presence normal and excluded */
+  SVN_ERR_ASSERT(ieb->presence == svn_wc__db_status_normal
+                 || ieb->presence == svn_wc__db_status_excluded);
+
   if (ieb->repos_id != INVALID_REPOS_ID)
     repos_id = ieb->repos_id;
   else
@@ -2635,7 +2641,7 @@ insert_external_node(void *baton,
 
   if (ieb->kind != svn_wc__db_kind_dir)
     {
-      SVN_ERR(svn_sqlite__bindf(stmt, "issisrtsrisss",
+      SVN_ERR(svn_sqlite__bindf(stmt, "issisrttsrisss",
                                 wcroot->wc_id,
                                 local_relpath,
                                 svn_relpath_dirname(local_relpath,
@@ -2643,6 +2649,7 @@ insert_external_node(void *baton,
                                 repos_id,
                                 ieb->repos_relpath,
                                 ieb->revision,
+                                presence_map, ieb->presence,
                                 kind_map, ieb->kind,
                                 (ieb->kind == svn_wc__db_kind_symlink)
                                             ? ieb->target
@@ -2654,34 +2661,36 @@ insert_external_node(void *baton,
                                 ieb->recorded_repos_relpath));
 
       if (ieb->checksum)
-        SVN_ERR(svn_sqlite__bind_checksum(stmt, 16, ieb->checksum,
+        SVN_ERR(svn_sqlite__bind_checksum(stmt, 17, ieb->checksum,
                                           scratch_pool));
 
       if (ieb->props)
-        SVN_ERR(svn_sqlite__bind_properties(stmt, 17, ieb->props,
+        SVN_ERR(svn_sqlite__bind_properties(stmt, 18, ieb->props,
                                             scratch_pool));
 
       if (ieb->dav_cache)
-        SVN_ERR(svn_sqlite__bind_properties(stmt, 18, ieb->dav_cache,
+        SVN_ERR(svn_sqlite__bind_properties(stmt, 19, ieb->dav_cache,
                                             scratch_pool));
     }
   else
     {
-      SVN_ERR(svn_sqlite__bindf(stmt, "issnnntnnnnss",
+      SVN_ERR(svn_sqlite__bindf(stmt, "issinnttnnnnss",
                                 wcroot->wc_id,
                                 local_relpath,
                                 svn_relpath_dirname(local_relpath,
                                                     scratch_pool),
+                                repos_id,
+                                presence_map, ieb->presence,
                                 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));
+    SVN_ERR(svn_sqlite__bind_revnum(stmt, 15, 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__bind_revnum(stmt, 16, ieb->recorded_revision));
 
   SVN_ERR(svn_sqlite__insert(NULL, stmt));
   /* ### TODO: Implement keeping recorded info */
@@ -2747,10 +2756,12 @@ svn_wc__db_external_add_file(svn_wc__db_
   blank_ieb(&ieb);
 
   ieb.kind = svn_wc__db_kind_file;
-  ieb.repos_relpath = repos_relpath;
+  ieb.presence = svn_wc__db_status_normal;
 
   ieb.repos_root_url = repos_root_url;
   ieb.repos_uuid = repos_uuid;
+
+  ieb.repos_relpath = repos_relpath;
   ieb.revision = revision;
 
   ieb.props = props;
@@ -2826,11 +2837,15 @@ svn_wc__db_external_add_symlink(svn_wc__
 
   local_relpath = svn_dirent_skip_ancestor(wcroot->abspath, local_abspath);
 
+  blank_ieb(&ieb);
+
   ieb.kind = svn_wc__db_kind_symlink;
-  ieb.repos_relpath = repos_relpath;
+  ieb.presence = svn_wc__db_status_normal;
 
   ieb.repos_root_url = repos_root_url;
   ieb.repos_uuid = repos_uuid;
+
+  ieb.repos_relpath = repos_relpath;
   ieb.revision = revision;
 
   ieb.props = props;
@@ -2866,6 +2881,8 @@ svn_error_t *
 svn_wc__db_external_add_dir(svn_wc__db_t *db,
                             const char *local_abspath,
                             const char *wri_abspath,
+                            const char *repos_root_url,
+                            const char *repos_uuid,
                             const char *record_ancestor_abspath,
                             const char *recorded_repos_relpath,
                             svn_revnum_t recorded_peg_revision,
@@ -2893,7 +2910,13 @@ svn_wc__db_external_add_dir(svn_wc__db_t
 
   local_relpath = svn_dirent_skip_ancestor(wcroot->abspath, local_abspath);
 
+  blank_ieb(&ieb);
+
   ieb.kind = svn_wc__db_kind_dir;
+  ieb.presence = svn_wc__db_status_normal;
+
+  ieb.repos_root_url = repos_root_url;
+  ieb.repos_uuid = repos_uuid;
 
   ieb.record_ancestor_relpath = svn_dirent_skip_ancestor(
                                                 wcroot->abspath,
@@ -2992,7 +3015,8 @@ svn_wc__db_external_record_fileinfo(svn_
 }
 
 svn_error_t *
-svn_wc__db_external_read(svn_wc__db_kind_t *kind,
+svn_wc__db_external_read(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,
@@ -3062,6 +3086,9 @@ svn_wc__db_external_read(svn_wc__db_kind
                                                         scratch_pool));
       }
 
+    if (status)
+      *status = svn_wc__db_status_normal;
+
     if (kind)
       *kind = base_kind;
 
@@ -3122,6 +3149,10 @@ svn_wc__db_external_read(svn_wc__db_kind
   if (have_info)
     {
       apr_int64_t repos_id;
+
+      if (status)
+        *status = svn_sqlite__column_token(stmt, 16, presence_map);
+
       if (kind)
         *kind = svn_sqlite__column_token(stmt, 0, kind_map);
 
@@ -3154,7 +3185,7 @@ svn_wc__db_external_read(svn_wc__db_kind
         *target = svn_sqlite__column_text(stmt, 6, result_pool);
 
       if (lock)
-        *lock = lock_from_columns(stmt, 16, 17, 18, 19, result_pool);
+        *lock = lock_from_columns(stmt, 17, 18, 19, 20, result_pool);
 
       if (recorded_size)
         *recorded_size = get_recorded_size(stmt, 10);

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1102121&r1=1102120&r2=1102121&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed May 11 22:46:07 2011
@@ -1100,6 +1100,9 @@ svn_wc__db_external_add_dir(svn_wc__db_t
                             const char *local_abspath,
                             const char *wri_abspath,
 
+                            const char *repos_root_url,
+                            const char *repos_uuid,
+
                             const char *record_ancestor_abspath,
                             const char *recorded_repos_relpath,
                             svn_revnum_t recorded_peg_revision,
@@ -1135,10 +1138,49 @@ svn_wc__db_external_remove(svn_wc__db_t 
    LOCAL_ABSPATH).
 
    Return SVN_ERR_WC_PATH_NOT_FOUND if LOCAL_ABSPATH is not an external in
-   this working copy
+   this working copy.
+
+   When STATUS is requested it has one of these values
+      svn_wc__db_status_normal           The external is available
+      svn_wc__db_status_excluded         The external is user excluded
+
+   When KIND is requested it has the kind of external
+
+   If REVISION is requested, and the node is NOT a directory, then
+   the value will be set to the revision of the file external.
+
+   If REPOS_RELPATH is requested, and the node is NOT a directory, then
+   the value will be set to the repository relative path of the file external.
+
+   If REPOS_ROOT_URL is requested, then the value will be set to the
+   repository root of the external.
+
+   If REPOS_UUID is requested, then the value will be set to the
+   repository uuid of the external.
+
+   When any of CHANGED_REV, CHANGED_DATE, CHANGED_AUTHOR, CHECKSUM, TARGET,
+   LOCK, RECORDED_SIZE, RECORDED_MOD_TIME, CONFLICTED, HAD_PROPS or PROPS_MOD
+   is requested,  and the node is NOT a directory, their value will set like
+   how svn_wc__db_read_info() would handle the value.
+
+   If RECORD_ANCESTOR_ABSPATH is requested, then the value will be set to the
+   absolute path of the directory which originally defined the external.
+
+   If RECORDED_REPOS_RELPATH is requested, then the value will be set to the
+   original repository relative path inside REPOS_ROOT_URL of the external.
+
+   If RECORDED_PEG_REVISION is requested, then the value will be set to the
+   original recorded operational (peg) revision of the external.
+
+   If RECORDED_REVISION is requested, then the value will be set to the
+   original recorded revision of the external.
+
+   Allocate the result in RESULT_POOL and perform temporary allocations in
+   SCRATCH_POOL.
  */
 svn_error_t *
-svn_wc__db_external_read(svn_wc__db_kind_t *kind,
+svn_wc__db_external_read(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,

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=1102121&r1=1102120&r2=1102121&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/db-test.c Wed May 11 22:46:07 
2011
@@ -1447,6 +1447,8 @@ test_externals_store(apr_pool_t *pool)
   SVN_ERR(svn_wc__db_external_add_dir(db,
                                       dir_external_path,
                                       local_abspath /* wri_abspath */,
+                                      "svn://other-repos/nsv",
+                                      "no-uuid-either",
                                       subdir,
                                       "some/other-location",
                                       70,
@@ -1456,6 +1458,7 @@ test_externals_store(apr_pool_t *pool)
 #endif
 
   {
+    svn_wc__db_status_t status;
     svn_wc__db_kind_t kind;
     svn_revnum_t revision;
     const char *repos_relpath;
@@ -1477,7 +1480,7 @@ test_externals_store(apr_pool_t *pool)
     svn_boolean_t had_props;
     svn_boolean_t props_mod;
 
-    SVN_ERR(svn_wc__db_external_read(&kind, &revision, &repos_relpath,
+    SVN_ERR(svn_wc__db_external_read(&status, &kind, &revision, &repos_relpath,
                                      &repos_root_url, &repos_uuid,
                                      &changed_rev, &changed_date,
                                      &changed_author, &checksum, &target,
@@ -1490,6 +1493,7 @@ test_externals_store(apr_pool_t *pool)
                                      db, file_external_path, local_abspath,
                                      pool, pool));
 
+    SVN_TEST_ASSERT(status == svn_wc__db_status_normal);
     SVN_TEST_ASSERT(kind == svn_wc__db_kind_file);
     SVN_TEST_ASSERT(revision == 12);
     SVN_TEST_STRING_ASSERT(repos_relpath, "some/location");
@@ -1516,7 +1520,7 @@ test_externals_store(apr_pool_t *pool)
     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,
+    SVN_ERR(svn_wc__db_external_read(&status, &kind, &revision, &repos_relpath,
                                      &repos_root_url, &repos_uuid,
                                      &changed_rev, &changed_date,
                                      &changed_author, &checksum, &target,
@@ -1529,11 +1533,12 @@ test_externals_store(apr_pool_t *pool)
                                      db, dir_external_path, local_abspath,
                                      pool, pool));
 
+    SVN_TEST_ASSERT(status == svn_wc__db_status_normal);
     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_STRING_ASSERT(repos_root_url, "svn://other-repos/nsv");
+    SVN_TEST_STRING_ASSERT(repos_uuid, "no-uuid-either");
     SVN_TEST_ASSERT(changed_rev == SVN_INVALID_REVNUM);
     SVN_TEST_ASSERT(changed_date == 0);
     SVN_TEST_ASSERT(changed_author == NULL);


Reply via email to