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 <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2017-10-23 13:26:32 +02:00
parent e7e7ee057e
commit 9678c86e40
2 changed files with 48 additions and 2 deletions

View File

@@ -193,6 +193,8 @@ public:
while (BaseStatement::next()) while (BaseStatement::next())
emplaceBackValues<ResultTypeCount>(resultValues); emplaceBackValues<ResultTypeCount>(resultValues);
resetter.reset();
return resultValues; return resultValues;
} }
@@ -210,6 +212,8 @@ public:
while (BaseStatement::next()) while (BaseStatement::next())
emplaceBackValues<ResultTypeCount>(resultValues); emplaceBackValues<ResultTypeCount>(resultValues);
resetter.reset();
return resultValues; return resultValues;
} }
@@ -228,6 +232,8 @@ public:
while (BaseStatement::next()) while (BaseStatement::next())
emplaceBackValues<ResultTypeCount>(resultValues); emplaceBackValues<ResultTypeCount>(resultValues);
resetter.reset();
} }
return resultValues; return resultValues;
@@ -249,6 +255,8 @@ public:
while (BaseStatement::next()) while (BaseStatement::next())
emplaceBackValues<ResultTypeCount>(resultValues); emplaceBackValues<ResultTypeCount>(resultValues);
resetter.reset();
} }
return resultValues; return resultValues;
@@ -267,6 +275,8 @@ public:
if (BaseStatement::next()) if (BaseStatement::next())
resultValue = assignValue<Utils::optional<ResultType>, ResultTypeCount>(); resultValue = assignValue<Utils::optional<ResultType>, ResultTypeCount>();
resetter.reset();
return resultValue; return resultValue;
} }
@@ -288,12 +298,29 @@ private:
: statement(statement) : statement(statement)
{} {}
~Resetter() void reset()
{ {
try {
statement.reset(); statement.reset();
} catch (...) {
shouldReset = false;
throw;
}
shouldReset = false;
}
~Resetter() noexcept
{
try {
if (shouldReset)
statement.reset();
} catch (...) {
}
} }
StatementImplementation &statement; StatementImplementation &statement;
bool shouldReset = true;
}; };
struct ValueGetter struct ValueGetter

View File

@@ -620,6 +620,25 @@ TEST_F(SqliteStatement, GetValuesWithTupleArgumentsCallsResetIfExceptionIsThrown
Sqlite::StatementHasError); 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<int>(3, std::vector<std::tuple<int>>{{1}, {2}}),
Sqlite::StatementHasError);
}
TEST_F(SqliteStatement, ThrowExceptionOnlyInReset)
{
MockSqliteStatement mockStatement;
ON_CALL(mockStatement, reset()).WillByDefault(Throw(Sqlite::StatementHasError("")));
ASSERT_THROW(mockStatement.values<int>(3, std::vector<std::tuple<int>>{{1}, {2}}),
Sqlite::StatementHasError);
}
void SqliteStatement::SetUp() void SqliteStatement::SetUp()
{ {
database.execute("CREATE TABLE test(name TEXT UNIQUE, number NUMERIC, value NUMERIC)"); database.execute("CREATE TABLE test(name TEXT UNIQUE, number NUMERIC, value NUMERIC)");