diff --git a/src/libs/sqlite/sqlitebasestatement.h b/src/libs/sqlite/sqlitebasestatement.h index 48026beef33..b6f04632147 100644 --- a/src/libs/sqlite/sqlitebasestatement.h +++ b/src/libs/sqlite/sqlitebasestatement.h @@ -193,6 +193,8 @@ public: while (BaseStatement::next()) emplaceBackValues(resultValues); + resetter.reset(); + return resultValues; } @@ -210,6 +212,8 @@ public: while (BaseStatement::next()) emplaceBackValues(resultValues); + resetter.reset(); + return resultValues; } @@ -228,6 +232,8 @@ public: while (BaseStatement::next()) emplaceBackValues(resultValues); + + resetter.reset(); } return resultValues; @@ -249,6 +255,8 @@ public: while (BaseStatement::next()) emplaceBackValues(resultValues); + + resetter.reset(); } return resultValues; @@ -267,6 +275,8 @@ public: if (BaseStatement::next()) resultValue = assignValue, ResultTypeCount>(); + resetter.reset(); + return resultValue; } @@ -288,12 +298,29 @@ private: : statement(statement) {} - ~Resetter() + void reset() { - statement.reset(); + try { + statement.reset(); + } catch (...) { + shouldReset = false; + throw; + } + + shouldReset = false; + } + + ~Resetter() noexcept + { + try { + if (shouldReset) + statement.reset(); + } catch (...) { + } } StatementImplementation &statement; + bool shouldReset = true; }; struct ValueGetter diff --git a/tests/unit/unittest/sqlitestatement-test.cpp b/tests/unit/unittest/sqlitestatement-test.cpp index 96484278c58..f033c07ed73 100644 --- a/tests/unit/unittest/sqlitestatement-test.cpp +++ b/tests/unit/unittest/sqlitestatement-test.cpp @@ -620,6 +620,25 @@ TEST_F(SqliteStatement, GetValuesWithTupleArgumentsCallsResetIfExceptionIsThrown Sqlite::StatementHasError); } +TEST_F(SqliteStatement, DoubleThrowExceptionsInReset) +{ + MockSqliteStatement mockStatement; + ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError(""))); + ON_CALL(mockStatement, reset()).WillByDefault(Throw(Sqlite::StatementHasError(""))); + + ASSERT_THROW(mockStatement.values(3, std::vector>{{1}, {2}}), + Sqlite::StatementHasError); +} + +TEST_F(SqliteStatement, ThrowExceptionOnlyInReset) +{ + MockSqliteStatement mockStatement; + ON_CALL(mockStatement, reset()).WillByDefault(Throw(Sqlite::StatementHasError(""))); + + ASSERT_THROW(mockStatement.values(3, std::vector>{{1}, {2}}), + Sqlite::StatementHasError); +} + void SqliteStatement::SetUp() { database.execute("CREATE TABLE test(name TEXT UNIQUE, number NUMERIC, value NUMERIC)");