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