diff --git a/src/libs/sqlite/sqlitebasestatement.h b/src/libs/sqlite/sqlitebasestatement.h index aa7fb11c7eb..ef098d42244 100644 --- a/src/libs/sqlite/sqlitebasestatement.h +++ b/src/libs/sqlite/sqlitebasestatement.h @@ -59,6 +59,8 @@ enum class Type : char { Invalid, Integer, Float, Text, Blob, Null }; class SQLITE_EXPORT BaseStatement { public: + using Database = ::Sqlite::Database; + explicit BaseStatement(Utils::SmallStringView sqlStatement, Database &database); BaseStatement(const BaseStatement &) = delete; @@ -403,7 +405,7 @@ public: } private: - DeferredTransaction m_transaction; + DeferredTransaction m_transaction; Resetter resetter; }; diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h index b379e2f80f1..3804d6c7a30 100644 --- a/src/libs/sqlite/sqlitedatabase.h +++ b/src/libs/sqlite/sqlitedatabase.h @@ -163,7 +163,6 @@ public: void lock() override; void unlock() override; -private: void deferredBegin() override; void immediateBegin() override; void exclusiveBegin() override; @@ -173,6 +172,7 @@ private: void sessionCommit() override; void sessionRollback() override; +private: void initializeTables(); void registerTransactionStatements(); void deleteTransactionStatements(); diff --git a/src/libs/sqlite/sqlitetransaction.h b/src/libs/sqlite/sqlitetransaction.h index 09a60446d26..1941548877b 100644 --- a/src/libs/sqlite/sqlitetransaction.h +++ b/src/libs/sqlite/sqlitetransaction.h @@ -59,9 +59,12 @@ protected: ~TransactionInterface() = default; }; +template class AbstractTransaction { public: + using Transaction = TransactionInterface; + AbstractTransaction(const AbstractTransaction &) = delete; AbstractTransaction &operator=(const AbstractTransaction &) = delete; @@ -87,11 +90,14 @@ protected: bool m_rollback = false; }; +template class AbstractThrowingSessionTransaction { public: - AbstractThrowingSessionTransaction(const AbstractTransaction &) = delete; - AbstractThrowingSessionTransaction &operator=(const AbstractTransaction &) = delete; + using Transaction = TransactionInterface; + + AbstractThrowingSessionTransaction(const AbstractThrowingSessionTransaction &) = delete; + AbstractThrowingSessionTransaction &operator=(const AbstractThrowingSessionTransaction &) = delete; void commit() { @@ -123,16 +129,19 @@ protected: bool m_rollback = false; }; -class AbstractThrowingTransaction : public AbstractTransaction +template +class AbstractThrowingTransaction : public AbstractTransaction { + using Base = AbstractTransaction; + public: AbstractThrowingTransaction(const AbstractThrowingTransaction &) = delete; AbstractThrowingTransaction &operator=(const AbstractThrowingTransaction &) = delete; ~AbstractThrowingTransaction() noexcept(false) { try { - if (m_rollback) - m_interface.rollback(); + if (Base::m_rollback) + Base::m_interface.rollback(); } catch (...) { if (!std::uncaught_exceptions()) throw; @@ -141,37 +150,40 @@ public: protected: AbstractThrowingTransaction(TransactionInterface &transactionInterface) - : AbstractTransaction(transactionInterface) + : AbstractTransaction(transactionInterface) { } }; -class AbstractNonThrowingDestructorTransaction : public AbstractTransaction +template +class AbstractNonThrowingDestructorTransaction : public AbstractTransaction { + using Base = AbstractTransaction; + public: AbstractNonThrowingDestructorTransaction(const AbstractNonThrowingDestructorTransaction &) = delete; AbstractNonThrowingDestructorTransaction &operator=(const AbstractNonThrowingDestructorTransaction &) = delete; ~AbstractNonThrowingDestructorTransaction() { try { - if (m_rollback) - m_interface.rollback(); + if (Base::m_rollback) + Base::m_interface.rollback(); } catch (...) { } } protected: AbstractNonThrowingDestructorTransaction(TransactionInterface &transactionInterface) - : AbstractTransaction(transactionInterface) + : AbstractTransaction(transactionInterface) { } }; -template -class BasicDeferredTransaction final : public BaseTransaction +template +class BasicDeferredTransaction : public BaseTransaction { public: - BasicDeferredTransaction(TransactionInterface &transactionInterface) + BasicDeferredTransaction(typename BaseTransaction::Transaction &transactionInterface) : BaseTransaction(transactionInterface) { transactionInterface.deferredBegin(); @@ -183,14 +195,38 @@ public: } }; -using DeferredTransaction = BasicDeferredTransaction; -using DeferredNonThrowingDestructorTransaction = BasicDeferredTransaction; +template +class DeferredTransaction final + : public BasicDeferredTransaction> +{ + using Base = BasicDeferredTransaction>; -template -class BasicImmediateTransaction final : public BaseTransaction +public: + using Base::Base; +}; + +template +DeferredTransaction(TransactionInterface &) -> DeferredTransaction; + +template +class DeferredNonThrowingDestructorTransaction final + : public BasicDeferredTransaction> +{ + using Base = BasicDeferredTransaction>; + +public: + using Base::Base; +}; + +template +DeferredNonThrowingDestructorTransaction(TransactionInterface &) + -> DeferredNonThrowingDestructorTransaction; + +template +class BasicImmediateTransaction : public BaseTransaction { public: - BasicImmediateTransaction(TransactionInterface &transactionInterface) + BasicImmediateTransaction(typename BaseTransaction::Transaction &transactionInterface) : BaseTransaction(transactionInterface) { transactionInterface.immediateBegin(); @@ -202,14 +238,38 @@ public: } }; -using ImmediateTransaction = BasicImmediateTransaction; -using ImmediateNonThrowingDestructorTransaction = BasicImmediateTransaction; +template +class ImmediateTransaction final + : public BasicImmediateTransaction> +{ + using Base = BasicImmediateTransaction>; -template -class BasicExclusiveTransaction final : public BaseTransaction +public: + using Base::Base; +}; + +template +ImmediateTransaction(TransactionInterface &) -> ImmediateTransaction; + +template +class ImmediateNonThrowingDestructorTransaction final + : public BasicImmediateTransaction> +{ + using Base = BasicImmediateTransaction>; + +public: + using Base::Base; +}; + +template +ImmediateNonThrowingDestructorTransaction(TransactionInterface &) + -> ImmediateNonThrowingDestructorTransaction; + +template +class BasicExclusiveTransaction : public BaseTransaction { public: - BasicExclusiveTransaction(TransactionInterface &transactionInterface) + BasicExclusiveTransaction(typename BaseTransaction::Transaction &transactionInterface) : BaseTransaction(transactionInterface) { transactionInterface.exclusiveBegin(); @@ -221,24 +281,51 @@ public: } }; -using ExclusiveTransaction = BasicExclusiveTransaction; -using ExclusiveNonThrowingDestructorTransaction - = BasicExclusiveTransaction; - -class ImmediateSessionTransaction final : public AbstractThrowingSessionTransaction +template +class ExclusiveTransaction final + : public BasicExclusiveTransaction> { + using Base = BasicExclusiveTransaction>; + public: - ImmediateSessionTransaction(TransactionInterface &transactionInterface) - : AbstractThrowingSessionTransaction(transactionInterface) + using Base::Base; +}; + +template +ExclusiveTransaction(TransactionInterface &) -> ExclusiveTransaction; + +template +class ExclusiveNonThrowingDestructorTransaction final + : public BasicExclusiveTransaction> +{ + using Base = BasicExclusiveTransaction>; + +public: + using Base::Base; +}; + +template +ExclusiveNonThrowingDestructorTransaction(TransactionInterface &) + -> ExclusiveNonThrowingDestructorTransaction; + +template +class ImmediateSessionTransaction final + : public AbstractThrowingSessionTransaction +{ + using Base = AbstractThrowingSessionTransaction; + +public: + ImmediateSessionTransaction(typename Base::Transaction &transactionInterface) + : AbstractThrowingSessionTransaction(transactionInterface) { transactionInterface.immediateSessionBegin(); } - ~ImmediateSessionTransaction() - { - AbstractThrowingSessionTransaction::m_rollback - = !AbstractThrowingSessionTransaction::m_isAlreadyCommited; - } + ~ImmediateSessionTransaction() { Base::m_rollback = !Base::m_isAlreadyCommited; } }; +template +ImmediateSessionTransaction(TransactionInterface &) + -> ImmediateSessionTransaction; + } // namespace Sqlite diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h b/src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h index 2f7e2eb93e6..c245f31d545 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h +++ b/src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h @@ -273,7 +273,7 @@ private: public: DatabaseType &database; Initializer initializer{database}; - Sqlite::ImmediateNonThrowingDestructorTransaction transaction{database}; + Sqlite::ImmediateNonThrowingDestructorTransaction transaction{database}; mutable ReadStatement<1, 2> selectImageStatement{ "SELECT image FROM images WHERE name=?1 AND mtime >= ?2", database}; mutable ReadStatement<1, 2> selectSmallImageStatement{ diff --git a/tests/unit/unittest/mocksqlitestatement.h b/tests/unit/unittest/mocksqlitestatement.h index 6e10384fbcc..82ddc187a5f 100644 --- a/tests/unit/unittest/mocksqlitestatement.h +++ b/tests/unit/unittest/mocksqlitestatement.h @@ -34,6 +34,8 @@ class BaseMockSqliteStatement { public: + using Database = SqliteDatabaseMock; + BaseMockSqliteStatement() = default; BaseMockSqliteStatement(SqliteDatabaseMock &databaseMock) : m_databaseMock{&databaseMock} @@ -112,9 +114,9 @@ Utils::PathString BaseMockSqliteStatement::fetchValue(int col template class MockSqliteStatement - : public Sqlite::StatementImplementation, ResultCount, BindParameterCount> + : public Sqlite::StatementImplementation { - using Base = Sqlite::StatementImplementation, ResultCount, BindParameterCount>; + using Base = Sqlite::StatementImplementation; public: explicit MockSqliteStatement(SqliteDatabaseMock &databaseMock) diff --git a/tests/unit/unittest/sqlitealgorithms-test.cpp b/tests/unit/unittest/sqlitealgorithms-test.cpp index a1647979fa8..6a494696615 100644 --- a/tests/unit/unittest/sqlitealgorithms-test.cpp +++ b/tests/unit/unittest/sqlitealgorithms-test.cpp @@ -115,7 +115,7 @@ public: protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; - Sqlite::ImmediateTransaction transaction{database}; + Sqlite::ImmediateTransaction transaction{database}; Initializer initializer{database}; Sqlite::ReadStatement<2> selectViewsStatement{"SELECT key, value FROM data ORDER BY key", database};