Author: julianfoad
Date: Wed Dec 19 16:53:41 2012
New Revision: 1423944
URL: http://svn.apache.org/viewvc?rev=1423944&view=rev
Log:
Introduce SVN_SQLITE__WITH_LOCK macro. A follow-up to r1423728 which
introduced SVN_SQLITE__WITH_TXN and SVN_SQLITE__WITH_IMMEDIATE_TXN.
This provides a more convenient interface for wrapping a transaction than
the existing function svn_sqlite__with_lock(), because there is no need to
marshall the called function's parameters via a 'baton' structure.
Use it in the one place where it is both beneficial and in regularly
maintained code (that is, not in backward-compatibility code). This will
serve as both a test and a showcase. Further use -- through a new
SVN_WC__DB_WITH_TXN macro -- will follow in a separate commit.
* subversion/include/private/svn_sqlite.h
(svn_sqlite__begin_savepoint,
svn_sqlite__finish_savepoint): New functions.
(SVN_SQLITE__WITH_LOCK): New macro.
* subversion/libsvn_subr/sqlite.c
(svn_sqlite__begin_savepoint,
svn_sqlite__finish_savepoint): New functions extracted from
svn_sqlite__with_lock().
(svn_sqlite__with_lock): Rewrite as a simple wrapper around the new macro.
* subversion/libsvn_wc/wc_db.c
(init_db_baton): Delete.
(init_db): Take the parameters directly.
(create_db): Pass the parameters directly, using SVN_SQLITE__WITH_LOCK().
Modified:
subversion/trunk/subversion/include/private/svn_sqlite.h
subversion/trunk/subversion/libsvn_subr/sqlite.c
subversion/trunk/subversion/libsvn_wc/wc_db.c
Modified: subversion/trunk/subversion/include/private/svn_sqlite.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_sqlite.h?rev=1423944&r1=1423943&r2=1423944&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_sqlite.h (original)
+++ subversion/trunk/subversion/include/private/svn_sqlite.h Wed Dec 19
16:53:41 2012
@@ -389,6 +389,10 @@ svn_sqlite__begin_transaction(svn_sqlite
svn_error_t *
svn_sqlite__begin_immediate_transaction(svn_sqlite__db_t *db);
+/* Begin a savepoint in DB. */
+svn_error_t *
+svn_sqlite__begin_savepoint(svn_sqlite__db_t *db);
+
/* Commit the current transaction in DB if ERR is SVN_NO_ERROR, otherwise
* roll back the transaction. Return a composition of ERR and any error
* that may occur during the commit or roll-back. */
@@ -396,6 +400,13 @@ svn_error_t *
svn_sqlite__finish_transaction(svn_sqlite__db_t *db,
svn_error_t *err);
+/* Release the current savepoint in DB if EXPR is SVN_NO_ERROR, otherwise
+ * roll back to the savepoint and then release it. Return a composition of
+ * ERR and any error that may occur during the release or roll-back. */
+svn_error_t *
+svn_sqlite__finish_savepoint(svn_sqlite__db_t *db,
+ svn_error_t *err);
+
/* Evaluate the expression EXPR within a transaction.
*
* Begin a transaction in DB; evaluate the expression EXPR, which would
@@ -447,6 +458,23 @@ svn_sqlite__with_immediate_transaction(s
void *cb_baton,
apr_pool_t *scratch_pool);
+/* Evaluate the expression EXPR within a 'savepoint'. Savepoints can be
+ * nested.
+ *
+ * Begin a savepoint in DB; evaluate the expression EXPR, which would
+ * typically be a function call that does some work in DB; finally release
+ * the savepoint if EXPR evaluated to SVN_NO_ERROR, otherwise roll back
+ * to the savepoint and then release it.
+ */
+#define SVN_SQLITE__WITH_LOCK(expr, db) \
+ do { \
+ svn_sqlite__db_t *svn_sqlite__db = (db); \
+ svn_error_t *svn_sqlite__err; \
+ \
+ SVN_ERR(svn_sqlite__begin_savepoint(svn_sqlite__db)); \
+ svn_sqlite__err = (expr); \
+ SVN_ERR(svn_sqlite__finish_savepoint(svn_sqlite__db, svn_sqlite__err)); \
+ } while (0)
/* Helper function to handle several SQLite operations inside a shared lock.
This callback is similar to svn_sqlite__with_transaction(), but can be
Modified: subversion/trunk/subversion/libsvn_subr/sqlite.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/sqlite.c?rev=1423944&r1=1423943&r2=1423944&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/trunk/subversion/libsvn_subr/sqlite.c Wed Dec 19 16:53:41 2012
@@ -1015,6 +1015,17 @@ svn_sqlite__begin_immediate_transaction(
}
svn_error_t *
+svn_sqlite__begin_savepoint(svn_sqlite__db_t *db)
+{
+ svn_sqlite__stmt_t *stmt;
+
+ SVN_ERR(get_internal_statement(&stmt, db,
+ STMT_INTERNAL_SAVEPOINT_SVN));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_sqlite__finish_transaction(svn_sqlite__db_t *db,
svn_error_t *err)
{
@@ -1066,39 +1077,11 @@ svn_sqlite__finish_transaction(svn_sqlit
}
svn_error_t *
-svn_sqlite__with_transaction(svn_sqlite__db_t *db,
- svn_sqlite__transaction_callback_t cb_func,
- void *cb_baton,
- apr_pool_t *scratch_pool /* NULL allowed */)
-{
- SVN_SQLITE__WITH_TXN(cb_func(cb_baton, db, scratch_pool), db);
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_sqlite__with_immediate_transaction(
- svn_sqlite__db_t *db,
- svn_sqlite__transaction_callback_t cb_func,
- void *cb_baton,
- apr_pool_t *scratch_pool /* NULL allowed */)
-{
- SVN_SQLITE__WITH_IMMEDIATE_TXN(cb_func(cb_baton, db, scratch_pool), db);
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_sqlite__with_lock(svn_sqlite__db_t *db,
- svn_sqlite__transaction_callback_t cb_func,
- void *cb_baton,
- apr_pool_t *scratch_pool)
+svn_sqlite__finish_savepoint(svn_sqlite__db_t *db,
+ svn_error_t *err)
{
- svn_error_t *err;
svn_sqlite__stmt_t *stmt;
- SVN_ERR(get_internal_statement(&stmt, db, STMT_INTERNAL_SAVEPOINT_SVN));
- SVN_ERR(svn_sqlite__step_done(stmt));
- err = cb_func(cb_baton, db, scratch_pool);
-
if (err)
{
svn_error_t *err2;
@@ -1138,6 +1121,37 @@ svn_sqlite__with_lock(svn_sqlite__db_t *
}
svn_error_t *
+svn_sqlite__with_transaction(svn_sqlite__db_t *db,
+ svn_sqlite__transaction_callback_t cb_func,
+ void *cb_baton,
+ apr_pool_t *scratch_pool /* NULL allowed */)
+{
+ SVN_SQLITE__WITH_TXN(cb_func(cb_baton, db, scratch_pool), db);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_sqlite__with_immediate_transaction(
+ svn_sqlite__db_t *db,
+ svn_sqlite__transaction_callback_t cb_func,
+ void *cb_baton,
+ apr_pool_t *scratch_pool /* NULL allowed */)
+{
+ SVN_SQLITE__WITH_IMMEDIATE_TXN(cb_func(cb_baton, db, scratch_pool), db);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_sqlite__with_lock(svn_sqlite__db_t *db,
+ svn_sqlite__transaction_callback_t cb_func,
+ void *cb_baton,
+ apr_pool_t *scratch_pool /* NULL allowed */)
+{
+ SVN_SQLITE__WITH_LOCK(cb_func(cb_baton, db, scratch_pool), db);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_sqlite__hotcopy(const char *src_path,
const char *dst_path,
apr_pool_t *scratch_pool)
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1423944&r1=1423943&r2=1423944&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Dec 19 16:53:41 2012
@@ -1422,29 +1422,21 @@ does_node_exist(svn_boolean_t *exists,
return svn_error_trace(svn_sqlite__reset(stmt));
}
-/* Baton for passing args to init_db(). */
-struct init_db_baton
-{
- /* output values */
- apr_int64_t wc_id;
- apr_int64_t repos_id;
- /* input values */
- const char *repos_root_url;
- const char *repos_uuid;
- const char *root_node_repos_relpath;
- svn_revnum_t root_node_revision;
- svn_depth_t root_node_depth;
-};
-
/* Helper for create_db(). Initializes our wc.db schema.
- *
- * Implements svn_sqlite__transaction_callback_t. */
+ */
static svn_error_t *
-init_db(void *baton,
+init_db(/* output values */
+ apr_int64_t *repos_id,
+ apr_int64_t *wc_id,
+ /* input values */
svn_sqlite__db_t *db,
+ const char *repos_root_url,
+ const char *repos_uuid,
+ const char *root_node_repos_relpath,
+ svn_revnum_t root_node_revision,
+ svn_depth_t root_node_depth,
apr_pool_t *scratch_pool)
{
- struct init_db_baton *idb = baton;
svn_sqlite__stmt_t *stmt;
/* Create the database's schema. */
@@ -1454,33 +1446,33 @@ init_db(void *baton,
SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_EXTERNALS));
/* Insert the repository. */
- SVN_ERR(create_repos_id(&idb->repos_id, idb->repos_root_url, idb->repos_uuid,
+ SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid,
db, scratch_pool));
/* Insert the wcroot. */
/* ### Right now, this just assumes wc metadata is being stored locally. */
SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_WCROOT));
- SVN_ERR(svn_sqlite__insert(&idb->wc_id, stmt));
+ SVN_ERR(svn_sqlite__insert(wc_id, stmt));
- if (idb->root_node_repos_relpath)
+ if (root_node_repos_relpath)
{
svn_wc__db_status_t status = svn_wc__db_status_normal;
- if (idb->root_node_revision > 0)
+ if (root_node_revision > 0)
status = svn_wc__db_status_incomplete; /* Will be filled by update */
SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "isdsisrtst",
- idb->wc_id, /* 1 */
+ *wc_id, /* 1 */
"", /* 2 */
0, /* op_depth is 0 for base
*/
NULL, /* 4 */
- idb->repos_id,
- idb->root_node_repos_relpath,
- idb->root_node_revision,
+ *repos_id,
+ root_node_repos_relpath,
+ root_node_revision,
presence_map, status, /* 8 */
svn_token__to_word(depth_map,
- idb->root_node_depth),
+ root_node_depth),
kind_map, svn_kind_dir /* 10 */));
SVN_ERR(svn_sqlite__insert(NULL, stmt));
@@ -1513,23 +1505,16 @@ create_db(svn_sqlite__db_t **sdb,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- struct init_db_baton idb;
-
SVN_ERR(svn_wc__db_util_open_db(sdb, dir_abspath, sdb_fname,
svn_sqlite__mode_rwcreate, exclusive,
NULL /* my_statements */,
result_pool, scratch_pool));
- idb.repos_root_url = repos_root_url;
- idb.repos_uuid = repos_uuid;
- idb.root_node_repos_relpath = root_node_repos_relpath;
- idb.root_node_revision = root_node_revision;
- idb.root_node_depth = root_node_depth;
-
- SVN_ERR(svn_sqlite__with_lock(*sdb, init_db, &idb, scratch_pool));
-
- *repos_id = idb.repos_id;
- *wc_id = idb.wc_id;
+ 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),
+ *sdb);
return SVN_NO_ERROR;
}