Sqlite: Cleanup error handling in sqlite statement

We mixed result code and error handling which is now separated.

Change-Id: Ibb9c5f0eb3b77c350eac67884d377ba1baaf76c6
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2017-10-16 12:57:35 +02:00
parent 5e0b207a89
commit 0d3ee85c51
2 changed files with 40 additions and 23 deletions

View File

@@ -107,15 +107,12 @@ void BaseStatement::waitForUnlockNotify() const
void BaseStatement::reset() const void BaseStatement::reset() const
{ {
int resultCode = sqlite3_reset(m_compiledStatement.get()); int resultCode = sqlite3_reset(m_compiledStatement.get());
switch (resultCode) {
case SQLITE_OK: return; if (resultCode != SQLITE_OK) {
case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!"); checkForResetError(resultCode);
case SQLITE_ERROR : throwStatementHasError("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::stepStatement: was called inappropriately!");
case SQLITE_CONSTRAINT: throwConstraintPreventsModification("SqliteStatement::stepStatement: contraint prevent insert or update!");
}
m_isReadyToFetchValues = false; m_isReadyToFetchValues = false;
}
} }
bool BaseStatement::next() const bool BaseStatement::next() const
@@ -133,7 +130,14 @@ bool BaseStatement::next() const
setIfIsReadyToFetchValues(resultCode); setIfIsReadyToFetchValues(resultCode);
return checkForStepError(resultCode); if (resultCode == SQLITE_ROW)
return true;
else if (resultCode == SQLITE_DONE)
return false;
else
checkForStepError(resultCode);
return false;
} }
void BaseStatement::step() const void BaseStatement::step() const
@@ -166,18 +170,21 @@ Utils::SmallStringVector BaseStatement::columnNames() const
void BaseStatement::bind(int index, int value) void BaseStatement::bind(int index, int value)
{ {
int resultCode = sqlite3_bind_int(m_compiledStatement.get(), index, value); int resultCode = sqlite3_bind_int(m_compiledStatement.get(), index, value);
if (resultCode != SQLITE_OK)
checkForBindingError(resultCode); checkForBindingError(resultCode);
} }
void BaseStatement::bind(int index, long long value) void BaseStatement::bind(int index, long long value)
{ {
int resultCode = sqlite3_bind_int64(m_compiledStatement.get(), index, value); int resultCode = sqlite3_bind_int64(m_compiledStatement.get(), index, value);
if (resultCode != SQLITE_OK)
checkForBindingError(resultCode); checkForBindingError(resultCode);
} }
void BaseStatement::bind(int index, double value) void BaseStatement::bind(int index, double value)
{ {
int resultCode = sqlite3_bind_double(m_compiledStatement.get(), index, value); int resultCode = sqlite3_bind_double(m_compiledStatement.get(), index, value);
if (resultCode != SQLITE_OK)
checkForBindingError(resultCode); checkForBindingError(resultCode);
} }
@@ -188,6 +195,7 @@ void BaseStatement::bind(int index, Utils::SmallStringView text)
text.data(), text.data(),
int(text.size()), int(text.size()),
SQLITE_STATIC); SQLITE_STATIC);
if (resultCode != SQLITE_OK)
checkForBindingError(resultCode); checkForBindingError(resultCode);
} }
@@ -228,6 +236,8 @@ void BaseStatement::prepare(Utils::SmallStringView sqlStatement)
} while (resultCode == SQLITE_LOCKED); } while (resultCode == SQLITE_LOCKED);
if (resultCode != SQLITE_OK)
checkForPrepareError(resultCode); checkForPrepareError(resultCode);
} }
@@ -241,11 +251,9 @@ TextEncoding BaseStatement::databaseTextEncoding()
return m_database.backend().textEncoding(); return m_database.backend().textEncoding();
} }
bool BaseStatement::checkForStepError(int resultCode) const void BaseStatement::checkForStepError(int resultCode) const
{ {
switch (resultCode) { switch (resultCode) {
case SQLITE_ROW: return true;
case SQLITE_DONE: return false;
case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!"); case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!");
case SQLITE_ERROR : throwStatementHasError("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!"); case SQLITE_ERROR : throwStatementHasError("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::stepStatement: was called inappropriately!"); case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::stepStatement: was called inappropriately!");
@@ -253,14 +261,23 @@ bool BaseStatement::checkForStepError(int resultCode) const
} }
throwUnknowError("SqliteStatement::stepStatement: unknown error has happened"); throwUnknowError("SqliteStatement::stepStatement: unknown error has happened");
}
Q_UNREACHABLE(); void BaseStatement::checkForResetError(int resultCode) const
{
switch (resultCode) {
case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!");
case SQLITE_ERROR : throwStatementHasError("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::stepStatement: was called inappropriately!");
case SQLITE_CONSTRAINT: throwConstraintPreventsModification("SqliteStatement::stepStatement: contraint prevent insert or update!");
}
throwUnknowError("SqliteStatement::reset: unknown error has happened");
} }
void BaseStatement::checkForPrepareError(int resultCode) const void BaseStatement::checkForPrepareError(int resultCode) const
{ {
switch (resultCode) { switch (resultCode) {
case SQLITE_OK: return;
case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::prepareStatement: database engine was unable to acquire the database locks!"); case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::prepareStatement: database engine was unable to acquire the database locks!");
case SQLITE_ERROR : throwStatementHasError("SqliteStatement::prepareStatement: run-time error (such as a constraint violation) has occurred!"); case SQLITE_ERROR : throwStatementHasError("SqliteStatement::prepareStatement: run-time error (such as a constraint violation) has occurred!");
case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::prepareStatement: was called inappropriately!"); case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::prepareStatement: was called inappropriately!");
@@ -272,7 +289,6 @@ void BaseStatement::checkForPrepareError(int resultCode) const
void BaseStatement::checkForBindingError(int resultCode) const void BaseStatement::checkForBindingError(int resultCode) const
{ {
switch (resultCode) { switch (resultCode) {
case SQLITE_OK: return;
case SQLITE_TOOBIG: throwBingingTooBig("SqliteStatement::bind: string or blob are over size limits(SQLITE_LIMIT_LENGTH)!"); case SQLITE_TOOBIG: throwBingingTooBig("SqliteStatement::bind: string or blob are over size limits(SQLITE_LIMIT_LENGTH)!");
case SQLITE_RANGE : throwBindingIndexIsOutOfRange("SqliteStatement::bind: binding index is out of range!"); case SQLITE_RANGE : throwBindingIndexIsOutOfRange("SqliteStatement::bind: binding index is out of range!");
case SQLITE_NOMEM: throw std::bad_alloc(); case SQLITE_NOMEM: throw std::bad_alloc();

View File

@@ -97,9 +97,10 @@ public:
sqlite3 *sqliteDatabaseHandle() const; sqlite3 *sqliteDatabaseHandle() const;
TextEncoding databaseTextEncoding(); TextEncoding databaseTextEncoding();
bool checkForStepError(int resultCode) const; [[noreturn]] void checkForStepError(int resultCode) const;
void checkForPrepareError(int resultCode) const; [[noreturn]] void checkForResetError(int resultCode) const;
void checkForBindingError(int resultCode) const; [[noreturn]] void checkForPrepareError(int resultCode) const;
[[noreturn]] void checkForBindingError(int resultCode) const;
void setIfIsReadyToFetchValues(int resultCode) const; void setIfIsReadyToFetchValues(int resultCode) const;
void checkIfIsReadyToFetchValues() const; void checkIfIsReadyToFetchValues() const;
void checkColumnsAreValid(const std::vector<int> &columns) const; void checkColumnsAreValid(const std::vector<int> &columns) const;