Adding mpSQLite to the statement Shared Pointer for error reporting

This commit is contained in:
Sébastien Rombauts 2013-03-07 11:48:52 +01:00
parent d535ccb09f
commit 244a8bff60
7 changed files with 60 additions and 48 deletions

View File

@ -1,7 +1,5 @@
C++11 explicit support
Adding mpSQLite to the statement Shared Pointer
=> V0.5.0
Missing features in v0.4.0:

View File

@ -25,7 +25,7 @@ Database::Database(const char* apFilename, const int aFlags /*= SQLITE_OPEN_READ
if (SQLITE_OK != ret)
{
std::string strerr = sqlite3_errmsg(mpSQLite);
sqlite3_close(mpSQLite);
sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw SQLite::Exception(strerr);
}
}

View File

@ -112,23 +112,23 @@ public:
*
* @param[in] aTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY
*/
inline int setBusyTimeout(int aTimeoutMs) // throw(); nothrow
{
return sqlite3_busy_timeout(mpSQLite, aTimeoutMs);
}
inline int setBusyTimeout(int aTimeoutMs) // throw(); nothrow
{
return sqlite3_busy_timeout(mpSQLite, aTimeoutMs);
}
/**
* @brief Get the rowid of the most recent successful INSERT into the database from the current connection.
*
* @return Rowid of the most recent successful INSERT into the database, or 0 if there was none.
*/
inline sqlite3_int64 getLastInsertRowid(void) const // throw(); nothrow
{
return sqlite3_last_insert_rowid(mpSQLite);
}
inline sqlite3_int64 getLastInsertRowid(void) const // throw(); nothrow
{
return sqlite3_last_insert_rowid(mpSQLite);
}
/**
* @brief Filename used to open the database
* Return the filename used to open the database
*/
inline const std::string& getFilename(void) const
{
@ -142,7 +142,7 @@ private:
Database& operator=(const Database&);
/**
* @brief 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 check(const int aRet) const; // throw(SQLite::Exception);

View File

@ -32,11 +32,14 @@ namespace SQLite
{
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
* Encapsulation of the error message from SQLite3, based on std::runtime_error.
*/
class Exception : public std::runtime_error
{
public:
/**
* Encapsulation of the error message from SQLite3, based on std::runtime_error.
*/
Exception(const std::string& aErrorMessage) :
std::runtime_error(aErrorMessage)
{

View File

@ -17,9 +17,8 @@ namespace SQLite
// Compile and register the SQL query for the provided SQLite Database Connection
Statement::Statement(Database &aDatabase, const char* apQuery) : // throw(SQLite::Exception)
mpSQLite(aDatabase.mpSQLite), // need Database friendship
mQuery(apQuery),
mStmtPtr(mpSQLite, mQuery), // prepare the SQL query, and ref count
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship)
mColumnCount(0),
mbOk(false),
mbDone(false)
@ -153,7 +152,7 @@ bool Statement::executeStep(void) // throw(SQLite::Exception)
{
mbOk = false;
mbDone = false;
throw SQLite::Exception(sqlite3_errmsg(mpSQLite));
throw SQLite::Exception(sqlite3_errmsg(mStmtPtr));
}
}
else
@ -185,7 +184,7 @@ int Statement::exec(void) // throw(SQLite::Exception)
{
mbOk = false;
mbDone = false;
throw SQLite::Exception(sqlite3_errmsg(mpSQLite));
throw SQLite::Exception(sqlite3_errmsg(mStmtPtr));
}
}
else
@ -194,7 +193,7 @@ int Statement::exec(void) // throw(SQLite::Exception)
}
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE)
return sqlite3_changes(mpSQLite);
return sqlite3_changes(mStmtPtr);
}
// Return a copy of the column data specified by its index starting at 0
@ -234,7 +233,7 @@ void Statement::check(const int aRet) const // throw(SQLite::Exception)
{
if (SQLITE_OK != aRet)
{
throw SQLite::Exception(sqlite3_errmsg(mpSQLite));
throw SQLite::Exception(sqlite3_errmsg(mStmtPtr));
}
}
@ -250,13 +249,14 @@ void Statement::check(const int aRet) const // throw(SQLite::Exception)
* @param[in] aQuery The SQL query string to prepare
*/
Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
mpSQLite(apSQLite),
mpStmt(NULL),
mpRefCount(NULL)
{
int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), aQuery.size(), &mpStmt, NULL);
if (SQLITE_OK != ret)
{
throw SQLite::Exception(sqlite3_errmsg(apSQLite));
throw SQLite::Exception(sqlite3_errmsg(mpSQLite));
}
// Initialize the reference counter of the sqlite3_stmt :
// used to share the mStmtPtr between Statement and Column objects;
@ -270,6 +270,7 @@ Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
* @param[in] aPtr Pointer to copy
*/
Statement::Ptr::Ptr (const Statement::Ptr& aPtr) :
mpSQLite(aPtr.mpSQLite),
mpStmt(aPtr.mpStmt),
mpRefCount(aPtr.mpRefCount)
{
@ -295,7 +296,6 @@ Statement::Ptr::~Ptr(void)
// as no Statement not Column objet use it anymore
int ret = sqlite3_finalize(mpStmt);
// Never throw an exception in a destructor
// TODO : Add mpSQLite to the pointer ?
//std::cout << sqlite3_errmsg(mpSQLite) << std::endl;
SQLITE_CPP_ASSERT (SQLITE_OK == ret);

View File

@ -42,12 +42,12 @@ public:
explicit Statement(Database &aDatabase, const char* apQuery); // throw(SQLite::Exception);
/**
* @brief Finalize and unregister the SQL query from the SQLite Database Connection.
* Finalize and unregister the SQL query from the SQLite Database Connection.
*/
virtual ~Statement(void) throw(); // nothrow
/**
* @brief Reset the statement to make it ready for a new execution.
* Reset the statement to make it ready for a new execution.
*/
void reset(void); // throw(SQLite::Exception);
@ -60,52 +60,52 @@ public:
// (prefixed with the corresponding sign "?", ":", "@" or "$")
/**
* @brief Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const int& aValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a 64bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a 64bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const sqlite3_int64& aValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const double& aValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const std::string& aValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const char* apValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex); // throw(SQLite::Exception);
/**
* @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName, const int& aValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName, const sqlite3_int64& aValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName, const double& aValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName, const std::string& aValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName, const char* apValue) ; // throw(SQLite::Exception);
/**
* @brief Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
* Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName); // throw(SQLite::Exception); // bind NULL value
@ -155,14 +155,14 @@ public:
Column getColumn(const int aIndex) const; // throw(SQLite::Exception);
/**
* @brief Test if the column is NULL
* Test if the column is NULL
*/
bool isColumnNull(const int aIndex) const; // throw(SQLite::Exception);
////////////////////////////////////////////////////////////////////////////
/**
* @brief UTF-8 SQL Query.
* UTF-8 SQL Query.
*/
inline const std::string& getQuery(void) const
{
@ -170,7 +170,7 @@ public:
}
/**
* @brief Return the number of columns in the result set returned by the prepared statement
* Return the number of columns in the result set returned by the prepared statement
*/
inline int getColumnCount(void) const
{
@ -178,7 +178,7 @@ public:
}
/**
* @brief True when the last row is fetched with executeStep().
* true when the last row is fetched with executeStep().
*/
inline bool isOk(void) const
{
@ -186,7 +186,7 @@ public:
}
/**
* @brief True when the last row is fetched with executeStep().
* true when the last row is fetched with executeStep().
*/
inline bool isDone(void) const
{
@ -195,9 +195,11 @@ public:
public:
/**
* @brief Shared pointer to the sqlite3_stmt SQLite Statement Object
* Shared pointer to the sqlite3_stmt SQLite Statement Object.
*
* This is a internal class, not part of the API (hence full documentation is in the cpp)
* Manage the finalization of the sqlite3_stmt with a reference counter.
*
* This is a internal class, not part of the API (hence full documentation is in the cpp).
*/
class Statement::Ptr
{
@ -209,14 +211,24 @@ public:
// Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0
~Ptr(void) throw(); // nothrow (no virtual destructor needed here)
/// Inline cast operator returning the pointer to SQLite Database Connection Handle
inline operator sqlite3*() const
{
return mpSQLite;
}
/// Inline cast operator returning the pointer to SQLite Statement Object
inline operator sqlite3_stmt*() const { return mpStmt; }
inline operator sqlite3_stmt*() const
{
return mpStmt;
}
private:
// Unused/forbidden copy operator
Ptr& operator=(const Ptr& aPtr);
private:
sqlite3* mpSQLite; //!< Pointer to SQLite Database Connection Handle
sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object
unsigned int* mpRefCount; //!< Pointer to the heap allocated reference counter of the sqlite3_stmt (to share it with Column objects)
};
@ -228,12 +240,11 @@ private:
Statement& operator=(const Statement&);
/**
* @brief Check if a return code equals SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
* Check if a return code equals SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
*/
void check(const int aRet) const; // throw(SQLite::Exception);
private:
sqlite3* mpSQLite; //!< Pointer to SQLite Database Connection Handle
std::string mQuery; //!< UTF-8 SQL Query
Ptr mStmtPtr; //!< Shared Pointer to the prepared SQLite Statement Object
int mColumnCount; //!< Number of column in the result of the prepared statement

View File

@ -31,7 +31,7 @@ Transaction::~Transaction(void) throw() // nothrow
{
mDatabase.exec("ROLLBACK");
}
catch (SQLite::Exception& e)
catch (SQLite::Exception& /*e*/)
{
// Never throw an exception in a destructor
//std::cout << e.what() << std::endl;