diff options
Diffstat (limited to 'src/libs/sqlite/sqlitetransaction.h')
-rw-r--r-- | src/libs/sqlite/sqlitetransaction.h | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/src/libs/sqlite/sqlitetransaction.h b/src/libs/sqlite/sqlitetransaction.h index 5c2c0fe0f8..d3eee99fb1 100644 --- a/src/libs/sqlite/sqlitetransaction.h +++ b/src/libs/sqlite/sqlitetransaction.h @@ -27,6 +27,8 @@ #include "sqliteglobal.h" +#include <utils/smallstringview.h> + #include <exception> #include <mutex> @@ -49,6 +51,9 @@ public: virtual void rollback() = 0; virtual void lock() = 0; virtual void unlock() = 0; + virtual void immediateSessionBegin() = 0; + virtual void sessionCommit() = 0; + virtual void sessionRollback() = 0; protected: ~TransactionInterface() = default; @@ -82,6 +87,42 @@ protected: bool m_rollback = false; }; +class AbstractThrowingSessionTransaction +{ +public: + AbstractThrowingSessionTransaction(const AbstractTransaction &) = delete; + AbstractThrowingSessionTransaction &operator=(const AbstractTransaction &) = delete; + + void commit() + { + m_interface.sessionCommit(); + m_isAlreadyCommited = true; + m_locker.unlock(); + } + + ~AbstractThrowingSessionTransaction() noexcept(false) + { + try { + if (m_rollback) + m_interface.sessionRollback(); + } catch (...) { + if (!std::uncaught_exception()) + throw; + } + } + +protected: + AbstractThrowingSessionTransaction(TransactionInterface &interface) + : m_interface(interface) + {} + +protected: + TransactionInterface &m_interface; + std::unique_lock<TransactionInterface> m_locker{m_interface}; + bool m_isAlreadyCommited = false; + bool m_rollback = false; +}; + class AbstractThrowingTransaction : public AbstractTransaction { public: @@ -181,6 +222,23 @@ public: }; using ExclusiveTransaction = BasicExclusiveTransaction<AbstractThrowingTransaction>; -using ExclusiveNonThrowingDestructorTransaction = BasicExclusiveTransaction<AbstractNonThrowingDestructorTransaction>; +using ExclusiveNonThrowingDestructorTransaction + = BasicExclusiveTransaction<AbstractNonThrowingDestructorTransaction>; + +class ImmediateSessionTransaction final : public AbstractThrowingSessionTransaction +{ +public: + ImmediateSessionTransaction(TransactionInterface &interface) + : AbstractThrowingSessionTransaction(interface) + { + interface.immediateSessionBegin(); + } + + ~ImmediateSessionTransaction() + { + AbstractThrowingSessionTransaction::m_rollback + = !AbstractThrowingSessionTransaction::m_isAlreadyCommited; + } +}; } // namespace Sqlite |