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
};