mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-02 16:43:03 +01:00
g10: Support nested transactions on the TOFU DB.
* g10/gpg.h (struct server_control_s): New field in_transaction. * g10/tofu.c (struct tofu_dbs_s): Remove fields savepoint_inner and savepoint_inner_commit. (begin_transaction): Increment CTRL->TOFU.IN_TRANSACTION. Name the savepoint according to the nesting level. (end_transaction): Name the savepoint according to the nesting level. Decrement CTRL->TOFU.IN_TRANSACTION. (rollback_transaction): Likewise. Only ever rollback a non-batch transaction. (opendbs): Assert that there are no outstanding transactions. -- Signed-off-by: Neal H. Walfield <neal@g10code.com>
This commit is contained in:
parent
4c2abb221b
commit
33e97813d7
@ -82,6 +82,7 @@ struct server_control_s
|
||||
/* Local data for tofu.c */
|
||||
struct {
|
||||
tofu_dbs_t dbs;
|
||||
int in_transaction;
|
||||
int batch_update_ref;
|
||||
time_t batch_update_started;
|
||||
} tofu;
|
||||
|
41
g10/tofu.c
41
g10/tofu.c
@ -70,9 +70,6 @@ struct tofu_dbs_s
|
||||
sqlite3_stmt *savepoint_batch;
|
||||
sqlite3_stmt *savepoint_batch_commit;
|
||||
|
||||
sqlite3_stmt *savepoint_inner;
|
||||
sqlite3_stmt *savepoint_inner_commit;
|
||||
|
||||
sqlite3_stmt *record_binding_get_old_policy;
|
||||
sqlite3_stmt *record_binding_update;
|
||||
sqlite3_stmt *record_binding_update2;
|
||||
@ -209,9 +206,12 @@ begin_transaction (ctrl_t ctrl, int only_batch)
|
||||
if (only_batch)
|
||||
return 0;
|
||||
|
||||
rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_inner,
|
||||
NULL, NULL, &err,
|
||||
"savepoint inner;", SQLITE_ARG_END);
|
||||
log_assert(ctrl->tofu.in_transaction >= 0);
|
||||
ctrl->tofu.in_transaction ++;
|
||||
|
||||
rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err,
|
||||
"savepoint inner%d;",
|
||||
ctrl->tofu.in_transaction);
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("error beginning transaction on TOFU database: %s\n"),
|
||||
@ -263,9 +263,9 @@ end_transaction (ctrl_t ctrl, int only_batch)
|
||||
if (only_batch)
|
||||
return 0;
|
||||
|
||||
rc = gpgsql_stepx (dbs->db, &dbs->s.savepoint_inner_commit,
|
||||
NULL, NULL, &err,
|
||||
"release inner;", SQLITE_ARG_END);
|
||||
log_assert (ctrl->tofu.in_transaction > 0);
|
||||
rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err,
|
||||
"release inner%d;", ctrl->tofu.in_transaction);
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("error committing transaction on TOFU database: %s\n"),
|
||||
@ -274,6 +274,8 @@ end_transaction (ctrl_t ctrl, int only_batch)
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
|
||||
ctrl->tofu.in_transaction --;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -287,18 +289,15 @@ rollback_transaction (ctrl_t ctrl)
|
||||
|
||||
if (!dbs)
|
||||
return 0; /* Shortcut to allow for easier cleanup code. */
|
||||
log_assert (ctrl->tofu.in_transaction > 0);
|
||||
|
||||
if (dbs->batch_update)
|
||||
{
|
||||
/* Just undo the most recent update; don't revert any progress
|
||||
made by the batch transaction. */
|
||||
rc = sqlite3_exec (dbs->db, "rollback to inner;", NULL, NULL, &err);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rollback the whole she-bang. */
|
||||
rc = sqlite3_exec (dbs->db, "rollback;", NULL, NULL, &err);
|
||||
}
|
||||
/* Be careful to not any progress made by closed transactions in
|
||||
batch mode. */
|
||||
rc = gpgsql_exec_printf (dbs->db, NULL, NULL, &err,
|
||||
"rollback to inner%d;",
|
||||
ctrl->tofu.in_transaction);
|
||||
|
||||
ctrl->tofu.in_transaction --;
|
||||
|
||||
if (rc)
|
||||
{
|
||||
@ -694,6 +693,8 @@ tofu_closedbs (ctrl_t ctrl)
|
||||
tofu_dbs_t dbs;
|
||||
sqlite3_stmt **statements;
|
||||
|
||||
log_assert(ctrl->tofu.in_transaction == 0);
|
||||
|
||||
dbs = ctrl->tofu.dbs;
|
||||
if (!dbs)
|
||||
return; /* Not initialized. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user