From c2b14f5d6852fb9efaca8aeec7961e9d036203e8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 24 Sep 2020 16:38:21 +0200 Subject: keyboxd: New command TRANSACTION. * kbx/backend-sqlite.c (be_sqlite_rollback): New. (be_sqlite_commit): New. (be_sqlite_search): Take care of global transactions. (be_sqlite_store): Ditto. (be_sqlite_delete): Ditto. * kbx/frontend.c (kbxd_rollback, kbxd_commit): New. * kbx/keyboxd.h (opt): Add vars for transactions. * kbx/kbxserver.c (struct server_local_s): Add fields next_session and client_pid. (session_list): New var. (cmd_transaction): New. (register_commands): Register command. (kbxd_start_command_handler): Store pids and track sessions. Do a final rollback. -- This command is currently an experiment to allow a client to run everything in one session. Signed-off-by: Werner Koch --- kbx/backend-sqlite.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 10 deletions(-) (limited to 'kbx/backend-sqlite.c') diff --git a/kbx/backend-sqlite.c b/kbx/backend-sqlite.c index 0b5155a8f..c31415694 100644 --- a/kbx/backend-sqlite.c +++ b/kbx/backend-sqlite.c @@ -681,6 +681,42 @@ be_sqlite_release_local (be_sqlite_local_t ctx) } +gpg_error_t +be_sqlite_rollback (void) +{ + opt.in_transaction = 0; + if (!opt.active_transaction) + return 0; /* Nothing to do. */ + + if (!database_hd) + { + log_error ("Warning: No database handle for global rollback\n"); + return gpg_error (GPG_ERR_INTERNAL); + } + + opt.active_transaction = 0; + return run_sql_statement ("rollback"); +} + + +gpg_error_t +be_sqlite_commit (void) +{ + opt.in_transaction = 0; + if (!opt.active_transaction) + return 0; /* Nothing to do. */ + + if (!database_hd) + { + log_error ("Warning: No database handle for global commit\n"); + return gpg_error (GPG_ERR_INTERNAL); + } + + opt.active_transaction = 0; + return run_sql_statement ("commit"); +} + + /* Run a select for the search given by (DESC,NDESC). The data is not * returned but stored in the request item. */ static gpg_error_t @@ -1000,6 +1036,16 @@ be_sqlite_search (ctrl_t ctrl, goto leave; } + /* Start a global transaction if needed. */ + if (!opt.active_transaction && opt.in_transaction) + { + err = run_sql_statement ("begin transaction"); + if (err) + goto leave; + opt.active_transaction = 1; + } + + again: if (!ctx->select_done) { @@ -1395,9 +1441,14 @@ be_sqlite_store (ctrl_t ctrl, backend_handle_t backend_hd, goto leave; /* ctx = part->besqlite; */ - err = run_sql_statement ("begin transaction"); - if (err) - goto leave; + if (!opt.active_transaction) + { + err = run_sql_statement ("begin transaction"); + if (err) + goto leave; + if (opt.in_transaction) + opt.active_transaction = 1; + } in_transaction = 1; err = store_into_pubkey (mode, pktype, ubid, blob, bloblen); @@ -1541,10 +1592,17 @@ be_sqlite_store (ctrl_t ctrl, backend_handle_t backend_hd, leave: if (in_transaction && !err) - err = run_sql_statement ("commit"); + { + if (opt.active_transaction) + ; /* We are in a global transaction. */ + else + err = run_sql_statement ("commit"); + } else if (in_transaction) { - if (run_sql_statement ("rollback")) + if (opt.active_transaction) + ; /* We are in a global transaction. */ + else if (run_sql_statement ("rollback")) log_error ("Warning: database rollback failed - should not happen!\n"); } if (got_mutex) @@ -1586,9 +1644,14 @@ be_sqlite_delete (ctrl_t ctrl, backend_handle_t backend_hd, goto leave; /* ctx = part->besqlite; */ - err = run_sql_statement ("begin transaction"); - if (err) - goto leave; + if (!opt.active_transaction) + { + err = run_sql_statement ("begin transaction"); + if (err) + goto leave; + if (opt.in_transaction) + opt.active_transaction = 1; + } in_transaction = 1; err = run_sql_statement_bind_ubid @@ -1607,11 +1670,19 @@ be_sqlite_delete (ctrl_t ctrl, backend_handle_t backend_hd, leave: if (stmt) sqlite3_finalize (stmt); + if (in_transaction && !err) - err = run_sql_statement ("commit"); + { + if (opt.active_transaction) + ; /* We are in a global transaction. */ + else + err = run_sql_statement ("commit"); + } else if (in_transaction) { - if (run_sql_statement ("rollback")) + if (opt.active_transaction) + ; /* We are in a global transaction. */ + else if (run_sql_statement ("rollback")) log_error ("Warning: database rollback failed - should not happen!\n"); } release_mutex (); -- cgit v1.2.3