diff --git a/src/libs/sqlite/sqlitereadstatement.h b/src/libs/sqlite/sqlitereadstatement.h index 281a7a3fa61..04618ba8ebc 100644 --- a/src/libs/sqlite/sqlitereadstatement.h +++ b/src/libs/sqlite/sqlitereadstatement.h @@ -50,6 +50,50 @@ public: using Base::value; using Base::values; + template + auto valueWithTransaction(const QueryTypes &...queryValues) + { + DeferredTransaction transaction{Base::database()}; + + auto resultValue = Base::template value(queryValues...); + + transaction.commit(); + + return resultValue; + } + + template + auto valuesWithTransaction(std::size_t reserveSize, const QueryTypes &...queryValues) + { + DeferredTransaction transaction{Base::database()}; + + auto resultValues = Base::template values(reserveSize, queryValues...); + + transaction.commit(); + + return resultValues; + } + + template + void readCallbackWithTransaction(Callable &&callable, const QueryTypes &...queryValues) + { + DeferredTransaction transaction{Base::database()}; + + Base::readCallback(std::forward(callable), queryValues...); + + transaction.commit(); + } + + template + void readToWithTransaction(Container &container, const QueryTypes &...queryValues) + { + DeferredTransaction transaction{Base::database()}; + + Base::readTo(container, queryValues...); + + transaction.commit(); + } + protected: void checkIsReadOnlyStatement() { diff --git a/src/libs/sqlite/sqlitereadwritestatement.h b/src/libs/sqlite/sqlitereadwritestatement.h index 4e2aecabc72..8ea9404251e 100644 --- a/src/libs/sqlite/sqlitereadwritestatement.h +++ b/src/libs/sqlite/sqlitereadwritestatement.h @@ -49,6 +49,59 @@ public: using Base::value; using Base::values; using Base::write; + + template + auto valueWithTransaction(const QueryTypes &...queryValues) + { + ImmediateTransaction transaction{Base::database()}; + + auto resultValue = Base::template value(queryValues...); + + transaction.commit(); + + return resultValue; + } + + template + auto valuesWithTransaction(std::size_t reserveSize, const QueryTypes &...queryValues) + { + ImmediateTransaction transaction{Base::database()}; + + auto resultValues = Base::template values(reserveSize, queryValues...); + + transaction.commit(); + + return resultValues; + } + + template + void readCallbackWithTransaction(Callable &&callable, const QueryTypes &...queryValues) + { + ImmediateTransaction transaction{Base::database()}; + + Base::readCallback(std::forward(callable), queryValues...); + + transaction.commit(); + } + + template + void readToWithTransaction(Container &container, const QueryTypes &...queryValues) + { + ImmediateTransaction transaction{Base::database()}; + + Base::readTo(container, queryValues...); + + transaction.commit(); + } + + void executeWithTransaction() + { + ImmediateTransaction transaction{Base::database()}; + + Base::execute(); + + transaction.commit(); + } }; } // namespace Sqlite diff --git a/tests/unit/unittest/sqlitestatement-test.cpp b/tests/unit/unittest/sqlitestatement-test.cpp index c6945ff5ec7..324fe554549 100644 --- a/tests/unit/unittest/sqlitestatement-test.cpp +++ b/tests/unit/unittest/sqlitestatement-test.cpp @@ -1380,4 +1380,112 @@ TEST_F(SqliteStatement, ReadToCallsResetIfExceptionIsThrown) EXPECT_THROW(mockStatement.readTo(values), Sqlite::StatementHasError); } +TEST_F(SqliteStatement, ReadStatementValuesWithTransactions) +{ + using Tuple = std::tuple; + ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); + database.unlock(); + + std::vector values = statement.valuesWithTransaction(1024, "bar", "blah"); + + ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1})); + database.lock(); +} + +TEST_F(SqliteStatement, ReadStatementValueWithTransactions) +{ + using Tuple = std::tuple; + ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); + database.unlock(); + + auto value = statement.valueWithTransaction("bar", "blah"); + + ASSERT_THAT(*value, Eq(Tuple{"bar", "blah", 1})); + database.lock(); +} + +TEST_F(SqliteStatement, ReadStatementReadCallbackWithTransactions) +{ + using Tuple = std::tuple; + MockFunction callbackMock; + ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); + database.unlock(); + + EXPECT_CALL(callbackMock, Call(Eq("bar"), Eq("blah"), Eq(1))); + + statement.readCallbackWithTransaction(callbackMock.AsStdFunction(), "bar", "blah"); + database.lock(); +} + +TEST_F(SqliteStatement, ReadStatementReadToWithTransactions) +{ + using Tuple = std::tuple; + ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); + std::vector values; + database.unlock(); + + statement.readToWithTransaction(values, "bar", "blah"); + + ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1})); + database.lock(); +} + +TEST_F(SqliteStatement, ReadWriteStatementValuesWithTransactions) +{ + using Tuple = std::tuple; + ReadWriteStatement<3> statement( + "SELECT name, number, value FROM test WHERE name=? AND number=?", database); + database.unlock(); + + std::vector values = statement.valuesWithTransaction(1024, "bar", "blah"); + + ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1})); + database.lock(); +} + +TEST_F(SqliteStatement, ReadWriteStatementValueWithTransactions) +{ + using Tuple = std::tuple; + ReadWriteStatement<3> statement( + "SELECT name, number, value FROM test WHERE name=? AND number=?", database); + database.unlock(); + + auto value = statement.valueWithTransaction("bar", "blah"); + + ASSERT_THAT(*value, Eq(Tuple{"bar", "blah", 1})); + database.lock(); +} + +TEST_F(SqliteStatement, ReadWriteStatementReadCallbackWithTransactions) +{ + using Tuple = std::tuple; + MockFunction callbackMock; + ReadWriteStatement<3> statement( + "SELECT name, number, value FROM test WHERE name=? AND number=?", database); + database.unlock(); + + EXPECT_CALL(callbackMock, Call(Eq("bar"), Eq("blah"), Eq(1))); + + statement.readCallbackWithTransaction(callbackMock.AsStdFunction(), "bar", "blah"); + database.lock(); +} + +TEST_F(SqliteStatement, ReadWriteStatementReadToWithTransactions) +{ + using Tuple = std::tuple; + ReadWriteStatement<3> statement( + "SELECT name, number, value FROM test WHERE name=? AND number=?", database); + std::vector values; + database.unlock(); + + statement.readToWithTransaction(values, "bar", "blah"); + + ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1})); + database.lock(); +} + } // namespace