diff options
author | John Turner <jturner.usa@gmail.com> | 2025-09-14 00:16:10 -0400 |
---|---|---|
committer | John Turner <jturner.usa@gmail.com> | 2025-09-14 00:16:10 -0400 |
commit | 13e0821fd783a1d5083d825af53cf20e8dcbfd76 (patch) | |
tree | 1ea363b0f13b3e87d177100e6ae6b9f30a2de1b8 /subprojects/boost-sqlite/include/boost/sqlite/transaction.hpp | |
parent | aa55cb93036a89c64c08e08f4e1de4fa1fd5a775 (diff) | |
parent | efcea3a80da7c4479d5fe168435ecc9fd06bdc72 (diff) | |
download | sqlite-kv-bench-13e0821fd783a1d5083d825af53cf20e8dcbfd76.tar.gz |
Merge commit 'efcea3a80da7c4479d5fe168435ecc9fd06bdc72' as 'subprojects/boost-sqlite'
Diffstat (limited to 'subprojects/boost-sqlite/include/boost/sqlite/transaction.hpp')
-rw-r--r-- | subprojects/boost-sqlite/include/boost/sqlite/transaction.hpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/subprojects/boost-sqlite/include/boost/sqlite/transaction.hpp b/subprojects/boost-sqlite/include/boost/sqlite/transaction.hpp new file mode 100644 index 0000000..b90bdbf --- /dev/null +++ b/subprojects/boost-sqlite/include/boost/sqlite/transaction.hpp @@ -0,0 +1,198 @@ +// +// Copyright (c) 2024 Klemens Morgenstern (klemens.morgenstern@gmx.net) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_SQLITE_TRANSACTION_HPP +#define BOOST_SQLITE_TRANSACTION_HPP + +#include <boost/sqlite/connection.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + +/** + * @brief A simple transaction guard implementing RAAI for transactions + * @ingroup reference + * + * @par Example + * @code{.cpp} + * sqlite::connection conn; + * conn.connect("./my-database.db"); + * + * sqlite::transaction t{conn}; + * conn.prepare("insert into log (text) values ($1)").execute(std::make_tuple("booting up")); + * t.commit(); + * @endcode + */ +struct transaction +{ + /// The mode of the transaction + enum behaviour {deferred, immediate, exclusive}; + /// A tag to use, to adopt an already initiated transaction. + constexpr static struct adopt_transaction_t {} adopt_transaction{}; + + + /// Create transaction guard on an existing transaction + transaction(connection & conn, adopt_transaction_t) : conn_(conn), completed_(false) + { + } + + + /// Create transaction guard and initiate a transaction + transaction(connection & conn) : conn_(conn) + { + conn.execute("BEGIN"); + completed_ = false; + } + + /// Create transaction guard and initiate a transaction with the defined behaviour + transaction(connection & conn, behaviour b) : conn_(conn) + { + switch (b) + { + case deferred: conn.execute("BEGIN DEFERRED"); break; + case immediate: conn.execute("BEGIN IMMEDIATE"); break; + case exclusive: conn.execute("BEGIN EXCLUSIVE"); break; + } + completed_ = false; + } + + // see https://www.sqlite.org/lang_transaction.html re noexcept + /// rollback the transaction if not committed. + ~transaction() noexcept(SQLITE_VERSION_NUMBER >= 3007011) + { + if (!completed_) + conn_.execute("ROLLBACK"); + } + + ///@{ + /// Commit the transaction. + void commit() + { + conn_.execute("COMMIT"); + completed_ = true; + } + + void commit(system::error_code & ec, error_info & ei) + { + conn_.execute("COMMIT", ec, ei); + completed_ = true; + } + ///@} + + ///@{ + /// Rollback the transaction explicitly. + void rollback() + { + conn_.execute("ROLLBACK"); + completed_ = true; + } + + void rollback(system::error_code & ec, error_info & ei) + { + conn_.execute("ROLLBACK", ec, ei); + completed_ = true; + } + ///@} + + private: + connection & conn_; + bool completed_ = true; +}; + +/** + * @brief A simple transaction guard implementing RAAI for savepoints. Savepoints can be used recursively. + * @ingroup reference + * + * @par Example + * @code{.cpp} + * sqlite::connection conn; + * conn.connect("./my-database.db"); + * + * sqlite::savepoint t{conn, "my-savepoint}; + * conn.prepare("insert into log (text) values ($1)").execute(std::make_tuple("booting up")); + * t.commit(); + * @endcode +*/ +struct savepoint +{ + /// A tag to use, to adopt an already initiated transaction. + constexpr static transaction::adopt_transaction_t adopt_transaction{}; + + /// Create savepoint guard on an existing savepoint + savepoint(connection & conn, std::string name, transaction::adopt_transaction_t) + : conn_(conn), name_(std::move(name)) + { + } + + /// Create transaction guard and initiate it + savepoint(connection & conn, std::string name) : conn_(conn), name_(std::move(name)) + { + conn.execute("SAVEPOINT " + name_); + completed_ = false; + } + + + /// rollback to the savepoint if not committed. + ~savepoint() noexcept(SQLITE_VERSION_NUMBER >= 3007011) + { + if (!completed_) + conn_.execute("ROLLBACK TO " + name_); + } + + ///@{ + /// Commit/Release the transaction. + void commit() + { + conn_.execute("RELEASE " + name_); + completed_ = true; + } + + void commit(system::error_code & ec, error_info & ei) + { + conn_.execute("RELEASE " + name_, ec, ei); + completed_ = true; + } + + void release() + { + conn_.execute("RELEASE " + name_); + completed_ = true; + } + + void release(system::error_code & ec, error_info & ei) + { + conn_.execute("RELEASE " + name_, ec, ei); + completed_ = true; + } + ///@} + + ///@{ + /// Rollback the transaction explicitly. + void rollback() + { + conn_.execute("ROLLBACK TO" + name_); + completed_ = true; + } + + void rollback(system::error_code & ec, error_info & ei) + { + conn_.execute("ROLLBACK TO " + name_, ec, ei); + completed_ = true; + } + ///@} + + /// The name of the savepoint. + const std::string & name() const {return name_;} + private: + connection & conn_; + std::string name_; + bool completed_ = true; +}; + + +BOOST_SQLITE_END_NAMESPACE + +#endif //BOOST_SQLITE_TRANSACTION_HPP |