Statement now stores the status of the last operation so it can be checked in the pointer destructor

This commit is contained in:
AndyLing 2014-09-19 10:54:55 +01:00
parent 55edadd56d
commit 4e770eb741
2 changed files with 26 additions and 10 deletions

View File

@ -50,7 +50,7 @@ public:
* @brief Compile and register the SQL query for the provided SQLite Database Connection * @brief Compile and register the SQL query for the provided SQLite Database Connection
* *
* @param[in] aDatabase the SQLite Database Connection * @param[in] aDatabase the SQLite Database Connection
* @param[in] apQuery an UTF-8 encoded query string * @param[in] apQuery an UTF-8 encoded query string
* *
* Exception is thrown in case of error, then the Statement object is NOT constructed. * Exception is thrown in case of error, then the Statement object is NOT constructed.
*/ */
@ -362,6 +362,16 @@ public:
return mpStmt; return mpStmt;
} }
int getLastStatus () const
{
return mLastStatus ;
}
void setLastStatus (int status)
{
mLastStatus = status ;
}
private: private:
/// @{ Unused/forbidden copy operator /// @{ Unused/forbidden copy operator
Ptr& operator=(const Ptr& aPtr); Ptr& operator=(const Ptr& aPtr);
@ -372,6 +382,7 @@ public:
sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object
unsigned int* mpRefCount; //!< Pointer to the heap allocated reference counter of the sqlite3_stmt unsigned int* mpRefCount; //!< Pointer to the heap allocated reference counter of the sqlite3_stmt
//!< (to share it with Column objects) //!< (to share it with Column objects)
int mLastStatus;//!< The return status of the last statement evaluation
}; };
private: private:
@ -385,7 +396,7 @@ private:
* *
* @param[in] SQLite return code to test against the SQLITE_OK expected value * @param[in] SQLite return code to test against the SQLITE_OK expected value
*/ */
void check(const int aRet) const; void check(const int aRet);
private: private:
std::string mQuery; //!< UTF-8 SQL Query std::string mQuery; //!< UTF-8 SQL Query

View File

@ -181,7 +181,8 @@ bool Statement::executeStep()
{ {
if (false == mbDone) if (false == mbDone)
{ {
int ret = sqlite3_step(mStmtPtr); int ret = sqlite3_step(mStmtPtr) ;
mStmtPtr.setLastStatus (ret);
if (SQLITE_ROW == ret) // one row is ready : call getColumn(N) to access it if (SQLITE_ROW == ret) // one row is ready : call getColumn(N) to access it
{ {
mbOk = true; mbOk = true;
@ -200,7 +201,7 @@ bool Statement::executeStep()
} }
else else
{ {
throw SQLite::Exception("Statement need to be reseted"); throw SQLite::Exception("Statement needs to be reset");
} }
return mbOk; // true only if one row is accessible by getColumn(N) return mbOk; // true only if one row is accessible by getColumn(N)
@ -212,6 +213,7 @@ int Statement::exec()
if (false == mbDone) if (false == mbDone)
{ {
int ret = sqlite3_step(mStmtPtr); int ret = sqlite3_step(mStmtPtr);
mStmtPtr.setLastStatus (ret);
if (SQLITE_DONE == ret) // the statement has finished executing successfully if (SQLITE_DONE == ret) // the statement has finished executing successfully
{ {
mbOk = false; mbOk = false;
@ -272,8 +274,9 @@ bool Statement::isColumnNull(const int aIndex) const
} }
// Check if aRet equal SQLITE_OK, else throw a SQLite::Exception with the SQLite error message // Check if aRet equal SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
void Statement::check(const int aRet) const void Statement::check(const int aRet)
{ {
mStmtPtr.setLastStatus (aRet) ;
if (SQLITE_OK != aRet) if (SQLITE_OK != aRet)
{ {
throw SQLite::Exception(sqlite3_errmsg(mStmtPtr)); throw SQLite::Exception(sqlite3_errmsg(mStmtPtr));
@ -294,10 +297,11 @@ void Statement::check(const int aRet) const
Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) : Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
mpSQLite(apSQLite), mpSQLite(apSQLite),
mpStmt(NULL), mpStmt(NULL),
mpRefCount(NULL) mpRefCount(NULL),
mLastStatus(SQLITE_OK)
{ {
int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, NULL); mLastStatus = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, NULL);
if (SQLITE_OK != ret) if (SQLITE_OK != mLastStatus)
{ {
throw SQLite::Exception(sqlite3_errmsg(mpSQLite)); throw SQLite::Exception(sqlite3_errmsg(mpSQLite));
} }
@ -315,7 +319,8 @@ Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
Statement::Ptr::Ptr(const Statement::Ptr& aPtr) : Statement::Ptr::Ptr(const Statement::Ptr& aPtr) :
mpSQLite(aPtr.mpSQLite), mpSQLite(aPtr.mpSQLite),
mpStmt(aPtr.mpStmt), mpStmt(aPtr.mpStmt),
mpRefCount(aPtr.mpRefCount) mpRefCount(aPtr.mpRefCount),
mLastStatus(SQLITE_OK)
{ {
assert(NULL != mpRefCount); assert(NULL != mpRefCount);
assert(0 != *mpRefCount); assert(0 != *mpRefCount);
@ -341,7 +346,7 @@ Statement::Ptr::~Ptr() noexcept // nothrow
// as no Statement not Column objet use it anymore // as no Statement not Column objet use it anymore
int ret = sqlite3_finalize(mpStmt); int ret = sqlite3_finalize(mpStmt);
// Never throw an exception in a destructor // Never throw an exception in a destructor
SQLITECPP_ASSERT(SQLITE_OK == ret, sqlite3_errmsg(mpSQLite)); // See SQLITECPP_ENABLE_ASSERT_HANDLER SQLITECPP_ASSERT((SQLITE_OK == ret || mLastStatus == ret), sqlite3_errmsg(mpSQLite)); // See SQLITECPP_ENABLE_ASSERT_HANDLER
// and delete the reference counter // and delete the reference counter
delete mpRefCount; delete mpRefCount;