Author: brane Date: Mon Sep 4 13:58:26 2017 New Revision: 1807225 URL: http://svn.apache.org/viewvc?rev=1807225&view=rev Log: Begin adding support for multiple working copy formats.
Instead of supporting just one format, introduce a current formaat (the default for new working copies) and a lowest supported format, and change the way new working copies are created: instead of the base schema defining the current format, it defines the lowest supporting format and a series of format updates are performed to bring it to the current shape. * subversion/libsvn_wc/wc.h (SVN_WC__VERSION): Bump to 32. (SVN_WC__SUPPORTED_VERSION): New; set to 31, the 1.8/1.9 format. (SVN_WC__COMPRESSED_PRISTINES): NEw; set to 32. (svn_wc__upgrade_sdb): Add parameter target_format. (svn_wc__update_schema): New prototype. * subversion/libsvn_wc/wc_db_private.h (VERIFY_USABLE_WCROOT): Check the range of supported formats. * subversion/libsvn_wc/wc_db.c (init_db): Add parameter wcroot_abspath. Update the schema to the current format. (create_db): Update the call to init_db. (svn_wc__db_bump_format): Update the call to svn_wc__upgrade_sdb. * subversion/libsvn_wc/wc_db_wcroot.c (svn_wc__db_pdh_create_wcroot): Allow the range of supported formats. * subversion/libsvn_wc/lock.c (open_single): Allow the range of supported formats. * subversion/libsvn_wc/upgrade.c: Include svn_version.h. (bump_to_32): New private function. (svn_wc__version_string_from_format): Add new mappings. (svn_wc__upgrade_sdb): Extract the schema-update part into ... (svn_wc__update_schema): ... here. (svn_wc__update_schema): Implement. * subversion/libsvn_wc/wc-metadata.sql (STMT_CREATE_SCHEMA): Set base format to SVN_WC__SUPPORTED_FORMAT. (STMT_BUMP_TO_32): Update the user_version. Modified: subversion/branches/better-pristines/subversion/libsvn_wc/lock.c subversion/branches/better-pristines/subversion/libsvn_wc/upgrade.c subversion/branches/better-pristines/subversion/libsvn_wc/wc-metadata.sql subversion/branches/better-pristines/subversion/libsvn_wc/wc.h subversion/branches/better-pristines/subversion/libsvn_wc/wc_db.c subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_private.h subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_wcroot.c Modified: subversion/branches/better-pristines/subversion/libsvn_wc/lock.c URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/libsvn_wc/lock.c?rev=1807225&r1=1807224&r2=1807225&view=diff ============================================================================== --- subversion/branches/better-pristines/subversion/libsvn_wc/lock.c (original) +++ subversion/branches/better-pristines/subversion/libsvn_wc/lock.c Mon Sep 4 13:58:26 2017 @@ -566,10 +566,12 @@ open_single(svn_wc_adm_access_t **adm_ac } SVN_ERR(err); - /* The format version must match exactly. Note that wc_db will perform - an auto-upgrade if allowed. If it does *not*, then it has decided a - manual upgrade is required and it should have raised an error. */ - SVN_ERR_ASSERT(wc_format == SVN_WC__VERSION); + /* The format version must be in the supported version range. Note + that wc_db will perform an auto-upgrade if allowed. If it does + *not*, then it has decided a manual upgrade is required and it + should have raised an error. */ + SVN_ERR_ASSERT(SVN_WC__SUPPORTED_VERSION <= wc_format + && wc_format <= SVN_WC__VERSION); /* Need to create a new lock */ SVN_ERR(adm_access_alloc(&lock, path, db, db_provided, write_lock, Modified: subversion/branches/better-pristines/subversion/libsvn_wc/upgrade.c URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/libsvn_wc/upgrade.c?rev=1807225&r1=1807224&r2=1807225&view=diff ============================================================================== --- subversion/branches/better-pristines/subversion/libsvn_wc/upgrade.c (original) +++ subversion/branches/better-pristines/subversion/libsvn_wc/upgrade.c Mon Sep 4 13:58:26 2017 @@ -28,6 +28,7 @@ #include "svn_dirent_uri.h" #include "svn_path.h" #include "svn_hash.h" +#include "svn_version.h" #include "wc.h" #include "adm_files.h" @@ -1857,6 +1858,15 @@ bump_to_31(void *baton, } static svn_error_t * +bump_to_32(void *baton, + svn_sqlite__db_t *sdb, + apr_pool_t *scratch_pool) +{ + SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_32)); + return SVN_NO_ERROR; +} + +static svn_error_t * upgrade_apply_dav_cache(svn_sqlite__db_t *sdb, const char *dir_relpath, apr_int64_t wc_id, @@ -2055,21 +2065,22 @@ svn_wc__version_string_from_format(int w case 9: return "1.5"; case 10: return "1.6"; case SVN_WC__WC_NG_VERSION: return "1.7"; + case 29: return "1.7"; + case 31: return "1.8"; + case 32: return "1.10"; } return _("(unreleased development version)"); } + svn_error_t * svn_wc__upgrade_sdb(int *result_format, const char *wcroot_abspath, svn_sqlite__db_t *sdb, int start_format, + int target_format, apr_pool_t *scratch_pool) { - struct bump_baton bb; - - bb.wcroot_abspath = wcroot_abspath; - if (start_format < SVN_WC__WC_NG_VERSION /* 12 */) return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL, _("Working copy '%s' is too old (format %d, " @@ -2091,100 +2102,42 @@ svn_wc__upgrade_sdb(int *result_format, scratch_pool), start_format); - /* ### need lock-out. only one upgrade at a time. note that other code - ### cannot use this un-upgraded database until we finish the upgrade. */ + if (start_format > target_format) + return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, + _("Working copy '%s' is already at version %s " + "(format %d) and cannot be downgraded to " + "version %s (format %d)"), + svn_dirent_local_style(wcroot_abspath, + scratch_pool), + svn_wc__version_string_from_format(start_format), + start_format, + svn_wc__version_string_from_format(target_format), + target_format); - /* Note: none of these have "break" statements; the fall-through is - intentional. */ - switch (start_format) - { - case 19: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_20, &bb, - scratch_pool)); - *result_format = 20; - /* FALLTHROUGH */ - - case 20: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_21, &bb, - scratch_pool)); - *result_format = 21; - /* FALLTHROUGH */ - - case 21: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_22, &bb, - scratch_pool)); - *result_format = 22; - /* FALLTHROUGH */ - - case 22: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_23, &bb, - scratch_pool)); - *result_format = 23; - /* FALLTHROUGH */ - - case 23: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_24, &bb, - scratch_pool)); - *result_format = 24; - /* FALLTHROUGH */ - - case 24: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_25, &bb, - scratch_pool)); - *result_format = 25; - /* FALLTHROUGH */ - - case 25: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_26, &bb, - scratch_pool)); - *result_format = 26; - /* FALLTHROUGH */ - - case 26: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_27, &bb, - scratch_pool)); - *result_format = 27; - /* FALLTHROUGH */ - - case 27: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_28, &bb, - scratch_pool)); - *result_format = 28; - /* FALLTHROUGH */ - - case 28: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_29, &bb, - scratch_pool)); - *result_format = 29; - /* FALLTHROUGH */ - - case 29: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_30, &bb, - scratch_pool)); - *result_format = 30; - - case 30: - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_31, &bb, - scratch_pool)); - *result_format = 31; - /* FALLTHROUGH */ - /* ### future bumps go here. */ -#if 0 - case XXX-1: - /* Revamp the recording of tree conflicts. */ - SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_XXX, &bb, - scratch_pool)); - *result_format = XXX; - /* FALLTHROUGH */ -#endif - case SVN_WC__VERSION: - /* already upgraded */ - *result_format = SVN_WC__VERSION; - - SVN_SQLITE__WITH_LOCK( - svn_wc__db_install_schema_statistics(sdb, scratch_pool), - sdb); - } + if (target_format < SVN_WC__SUPPORTED_VERSION) + return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, + _("Working copy version %s (format %d) " + "is not supported by client version %s."), + svn_wc__version_string_from_format(target_format), + target_format, SVN_VER_NUM); + + if (target_format > SVN_WC__VERSION) + return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, + _("Working copy with format %d " + "can't be created by client version %s."), + target_format, SVN_VER_NUM); + + /* FIXME: + ### need lock-out. only one upgrade at a time. note that other code + ### _can_ use this un-upgraded database before we finish the upgrade. */ + /* Update the schema */ + SVN_ERR(svn_wc__update_schema(result_format, wcroot_abspath, sdb, + start_format, target_format, scratch_pool)); + + /* Make sure that the stats1 table is populated. */ + SVN_SQLITE__WITH_TXN( + svn_wc__db_install_schema_statistics(sdb, scratch_pool), + sdb); #ifdef SVN_DEBUG if (*result_format != start_format) @@ -2202,6 +2155,102 @@ svn_wc__upgrade_sdb(int *result_format, return SVN_NO_ERROR; } + + +svn_error_t * +svn_wc__update_schema(int *result_format, + const char *wcroot_abspath, + svn_sqlite__db_t *sdb, + int start_format, + int target_format, + apr_pool_t *scratch_pool) +{ + struct bump_baton bb; + bb.wcroot_abspath = wcroot_abspath; + + /* Repeatedly upgrade until the target format version is reached. */ + for (*result_format = start_format; + *result_format < target_format;) + { + switch (*result_format) + { + case 19: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_20, &bb, scratch_pool)); + *result_format = 20; + break; + + case 20: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_21, &bb, scratch_pool)); + *result_format = 21; + break; + + case 21: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_22, &bb, scratch_pool)); + *result_format = 22; + break; + + case 22: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_23, &bb, scratch_pool)); + *result_format = 23; + break; + + case 23: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_24, &bb, scratch_pool)); + *result_format = 24; + break; + + case 24: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_25, &bb, scratch_pool)); + *result_format = 25; + break; + + case 25: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_26, &bb, scratch_pool)); + *result_format = 26; + break; + + case 26: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_27, &bb, scratch_pool)); + *result_format = 27; + break; + + case 27: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_28, &bb, scratch_pool)); + *result_format = 28; + break; + + case 28: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_29, &bb, scratch_pool)); + *result_format = 29; + break; + + case 29: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_30, &bb, scratch_pool)); + *result_format = 30; + break; + + case 30: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_31, &bb, scratch_pool)); + *result_format = 31; + break; + + case 31: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_32, &bb, scratch_pool)); + *result_format = SVN_WC__VERSION; + break; + + /* ### future bumps go here. */ +#if 0 + case XXX-1: + SVN_ERR(svn_sqlite__with_lock(sdb, bump_to_XXX, &bb, scratch_pool)); + *result_format = XXX; + break; +#endif + } + } + + return SVN_NO_ERROR; +} /* */ Modified: subversion/branches/better-pristines/subversion/libsvn_wc/wc-metadata.sql URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/libsvn_wc/wc-metadata.sql?rev=1807225&r1=1807224&r2=1807225&view=diff ============================================================================== --- subversion/branches/better-pristines/subversion/libsvn_wc/wc-metadata.sql (original) +++ subversion/branches/better-pristines/subversion/libsvn_wc/wc-metadata.sql Mon Sep 4 13:58:26 2017 @@ -228,9 +228,11 @@ CREATE TABLE WC_LOCK ( PRIMARY KEY (wc_id, local_dir_relpath) ); - +/* When we're creating a new working copy, the default schema creates + the earliest supported format. The normal WC upgrade code is used + to bring the format up to SVN_WC__VERSION. */ PRAGMA user_version = --- define: SVN_WC__VERSION +-- define: SVN_WC__SUPPORTED_VERSION ; @@ -921,6 +923,8 @@ DROP INDEX I_ACTUAL_PARENT; CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath, local_relpath); +PRAGMA user_version = 32; + /* ------------------------------------------------------------------------- */ /* Format YYY introduces new handling for conflict information. */ Modified: subversion/branches/better-pristines/subversion/libsvn_wc/wc.h URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/libsvn_wc/wc.h?rev=1807225&r1=1807224&r2=1807225&view=diff ============================================================================== --- subversion/branches/better-pristines/subversion/libsvn_wc/wc.h (original) +++ subversion/branches/better-pristines/subversion/libsvn_wc/wc.h Mon Sep 4 13:58:26 2017 @@ -160,11 +160,17 @@ extern "C" { * == 1.8.x shipped with format 31 * == 1.9.x shipped with format 31 * + * The bump to 32 added support for compressed pristines and pristine storage + * within the working copy database. + * * Please document any further format changes here. */ -#define SVN_WC__VERSION 31 +/* The default WC version created by the client. */ +#define SVN_WC__VERSION 32 +/* The minimum WC version supported by the client. */ +#define SVN_WC__SUPPORTED_VERSION 31 /* Formats <= this have no concept of "revert text-base/props". */ #define SVN_WC__NO_REVERT_FILES 4 @@ -195,6 +201,10 @@ extern "C" { sqlite_stat1 table on opening */ #define SVN_WC__ENSURE_STAT1_TABLE 31 +/* In this version, we added support for compressed and in-database + pristine storage. */ +#define SVN_WC__COMPRESSED_PRISTINES 32 + /* Return a string indicating the released version (or versions) of * Subversion that used WC format number WC_FORMAT, or some other * suitable string if no released version used WC_FORMAT. @@ -583,7 +593,8 @@ svn_wc__internal_get_origin(svn_boolean_ apr_pool_t *scratch_pool); /* Upgrade the wc sqlite database given in SDB for the wc located at - WCROOT_ABSPATH. It's current/starting format is given by START_FORMAT. + WCROOT_ABSPATH. It's current/starting format is given by START_FORMAT, + and the intended format is given by TARGET_FORMAT. After the upgrade is complete (to as far as the automatic upgrade will perform), the resulting format is RESULT_FORMAT. All allocations are performed in SCRATCH_POOL. */ @@ -592,8 +603,18 @@ svn_wc__upgrade_sdb(int *result_format, const char *wcroot_abspath, svn_sqlite__db_t *sdb, int start_format, + int target_format, apr_pool_t *scratch_pool); +/* The schema-update part of svn_wc__upgrade_sdb. */ +svn_error_t * +svn_wc__update_schema(int *result_format, + const char *wcroot_abspath, + svn_sqlite__db_t *sdb, + int start_format, + int target_format, + apr_pool_t *scratch_pool); + /* Create a conflict skel from the old separated data */ svn_error_t * svn_wc__upgrade_conflict_skel_from_raw(svn_skel_t **conflicts, Modified: subversion/branches/better-pristines/subversion/libsvn_wc/wc_db.c URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/libsvn_wc/wc_db.c?rev=1807225&r1=1807224&r2=1807225&view=diff ============================================================================== --- subversion/branches/better-pristines/subversion/libsvn_wc/wc_db.c (original) +++ subversion/branches/better-pristines/subversion/libsvn_wc/wc_db.c Mon Sep 4 13:58:26 2017 @@ -1365,9 +1365,11 @@ init_db(/* output values */ const char *root_node_repos_relpath, svn_revnum_t root_node_revision, svn_depth_t root_node_depth, + const char *wcroot_abspath, apr_pool_t *scratch_pool) { svn_sqlite__stmt_t *stmt; + int result_format; /* Create the database's schema. */ SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_SCHEMA)); @@ -1375,6 +1377,11 @@ init_db(/* output values */ SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES_TRIGGERS)); SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_EXTERNALS)); + /* TODO: Parametrize the target format here. */ + SVN_ERR(svn_wc__update_schema(&result_format, wcroot_abspath, db, + SVN_WC__SUPPORTED_VERSION, SVN_WC__VERSION, + scratch_pool)); + SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool)); /* Insert the repository. */ @@ -1447,7 +1454,7 @@ create_db(svn_sqlite__db_t **sdb, SVN_SQLITE__WITH_LOCK(init_db(repos_id, wc_id, *sdb, repos_root_url, repos_uuid, root_node_repos_relpath, root_node_revision, - root_node_depth, scratch_pool), + root_node_depth, dir_abspath, scratch_pool), *sdb); return SVN_NO_ERROR; @@ -16046,8 +16053,9 @@ svn_wc__db_bump_format(int *result_forma } SVN_ERR(svn_sqlite__read_schema_version(&format, sdb, scratch_pool)); + /* TODO: Parametrize the target format here. */ err = svn_wc__upgrade_sdb(result_format, wcroot_abspath, - sdb, format, scratch_pool); + sdb, format, SVN_WC__VERSION, scratch_pool); if (err == SVN_NO_ERROR && bumped_format) *bumped_format = (*result_format > format); Modified: subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_private.h URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_private.h?rev=1807225&r1=1807224&r2=1807225&view=diff ============================================================================== --- subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_private.h (original) +++ subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_private.h Mon Sep 4 13:58:26 2017 @@ -155,7 +155,8 @@ svn_wc__db_verify_no_work(svn_sqlite__db /* Assert that the given WCROOT is usable. NOTE: the expression is multiply-evaluated!! */ #define VERIFY_USABLE_WCROOT(wcroot) SVN_ERR_ASSERT( \ - (wcroot) != NULL && (wcroot)->format == SVN_WC__VERSION) + (wcroot) != NULL && (wcroot)->format <= SVN_WC__VERSION \ + && (wcroot)->format >= SVN_WC__SUPPORTED_VERSION) /* Check if the WCROOT is usable for light db operations such as path calculations */ Modified: subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_wcroot.c URL: http://svn.apache.org/viewvc/subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_wcroot.c?rev=1807225&r1=1807224&r2=1807225&view=diff ============================================================================== --- subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_wcroot.c (original) +++ subversion/branches/better-pristines/subversion/libsvn_wc/wc_db_wcroot.c Mon Sep 4 13:58:26 2017 @@ -337,7 +337,7 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_ /* Verify that no work items exists. If they do, then our integrity is suspect and, thus, we cannot upgrade this database. */ if (format >= SVN_WC__HAS_WORK_QUEUE && - format < SVN_WC__VERSION && verify_format) + format < SVN_WC__SUPPORTED_VERSION && verify_format) { svn_error_t *err = svn_wc__db_verify_no_work(sdb); if (err) @@ -345,7 +345,7 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_ /* Special message for attempts to upgrade a 1.7-dev wc with outstanding workqueue items. */ if (err->apr_err == SVN_ERR_WC_CLEANUP_REQUIRED - && format < SVN_WC__VERSION && verify_format) + && format < SVN_WC__SUPPORTED_VERSION && verify_format) err = svn_error_quick_wrap(err, _("Cleanup with an older 1.7 " "client before upgrading with " "this client")); @@ -354,16 +354,27 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_ } /* Auto-upgrade the SDB if possible. */ - if (format < SVN_WC__VERSION && verify_format) + if (format < SVN_WC__SUPPORTED_VERSION && verify_format) { - return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL, - _("The working copy at '%s'\nis too old " - "(format %d) to work with client version " - "'%s' (expects format %d). You need to " - "upgrade the working copy first.\n"), - svn_dirent_local_style(wcroot_abspath, - scratch_pool), - format, SVN_VERSION, SVN_WC__VERSION); + if (SVN_WC__SUPPORTED_VERSION == SVN_WC__VERSION) + return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL, + _("The working copy at '%s'\nis too old " + "(format %d) to work with client version " + "'%s' (expects format %d). You need " + "to upgrade the working copy first.\n"), + svn_dirent_local_style(wcroot_abspath, + scratch_pool), + format, SVN_VERSION, SVN_WC__VERSION); + else + return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL, + _("The working copy at '%s'\nis too old " + "(format %d) to work with client version " + "'%s' (expects format %d to %d). You need " + "to upgrade the working copy first.\n"), + svn_dirent_local_style(wcroot_abspath, + scratch_pool), + format, SVN_VERSION, + SVN_WC__SUPPORTED_VERSION, SVN_WC__VERSION); } *wcroot = apr_palloc(result_pool, sizeof(**wcroot));