From 9678c86e40d5d97abcb99cd370186cb2cc35a820 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 23 Oct 2017 13:26:32 +0200 Subject: [PATCH] Sqlite: Fix double throwing for reset We do want prevent throwing again for reset if we already have thrown an exception but we want to throw if there was no exception. Change-Id: Iaf9fffb872ccd579a8ccde02381b5e5d30d5c4cb Reviewed-by: Tim Jenssen --- src/libs/sqlite/sqlitebasestatement.h | 31 ++++++++++++++++++-- tests/unit/unittest/sqlitestatement-test.cpp | 19 ++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) 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)");