Updated comments for the heap allocated (thread unsage) mpStmtRefCount ref counter shared between Statement and Column objects

This commit is contained in:
Sébastien Rombauts 2012-11-27 15:41:40 +01:00
parent a5cb3267eb
commit 0055fcc2db
4 changed files with 22 additions and 11 deletions

View File

@ -21,19 +21,19 @@ Column::Column(sqlite3* apSQLite, sqlite3_stmt* apStmt, unsigned int* apStmtRefC
mpStmtRefCount(apStmtRefCount), mpStmtRefCount(apStmtRefCount),
mIndex(aIndex) mIndex(aIndex)
{ {
// Increment the reference counter of the sqlite3_stmt,
// telling the Statement object not to finalize the sqlite3_stmt during the lifetime of this Column objet
(*mpStmtRefCount)++; (*mpStmtRefCount)++;
} }
// Finalize and unregister the SQL query from the SQLite Database Connection. // Finalize and unregister the SQL query from the SQLite Database Connection.
Column::~Column(void) throw() // nothrow Column::~Column(void) throw() // nothrow
{ {
// Decrement and check the reference counter // Decrement and check the reference counter of the sqlite3_stmt
(*mpStmtRefCount)--; (*mpStmtRefCount)--;
if (0 == *mpStmtRefCount) if (0 == *mpStmtRefCount)
{ {
// When count reaches zero, dealloc and finalize the statement // When count reaches zero, finalize the sqlite3_stmt, as no Column nor Statement object use it any more
delete mpStmtRefCount;
int ret = sqlite3_finalize(mpStmt); int ret = sqlite3_finalize(mpStmt);
if (SQLITE_OK != ret) if (SQLITE_OK != ret)
{ {
@ -41,7 +41,11 @@ Column::~Column(void) throw() // nothrow
//std::cout << sqlite3_errmsg(mpSQLite); //std::cout << sqlite3_errmsg(mpSQLite);
} }
mpStmt = NULL; mpStmt = NULL;
// and delete the reference counter
delete mpStmtRefCount;
} }
// else, the finalization will be done by the Statement or another Column object (the last one)
} }
// Return the integer value of the column specified by its index starting at 0 // Return the integer value of the column specified by its index starting at 0

View File

@ -20,6 +20,8 @@ namespace SQLite
* @brief Encapsulation of a Column in a Row of the result. * @brief Encapsulation of a Column in a Row of the result.
* *
* A Column is a particular field of SQLite data in the current row of result of the Statement. * A Column is a particular field of SQLite data in the current row of result of the Statement.
*
* @todo mpStmtRefCount is thread unsafe !
*/ */
class Column class Column
{ {
@ -84,7 +86,7 @@ private:
private: private:
sqlite3* mpSQLite; //!< Pointer to SQLite Database Connection Handle sqlite3* mpSQLite; //!< Pointer to SQLite Database Connection Handle
sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object
unsigned int* mpStmtRefCount; //!< Pointer to the reference counter of the Statement Object (to share it with a Statement object) unsigned int* mpStmtRefCount; //!< Pointer to the heap allocated reference counter of the sqlite3_stmt (shared with the Statement object)
int mIndex; //!< Index of the column in the row of result int mIndex; //!< Index of the column in the row of result
}; };

View File

@ -28,7 +28,8 @@ Statement::Statement(Database &aDatabase, const char* apQuery) : // throw(SQLite
int ret = sqlite3_prepare_v2(mpSQLite, mQuery.c_str(), mQuery.size(), &mpStmt, NULL); int ret = sqlite3_prepare_v2(mpSQLite, mQuery.c_str(), mQuery.size(), &mpStmt, NULL);
check(ret); check(ret);
mColumnCount = sqlite3_column_count(mpStmt); mColumnCount = sqlite3_column_count(mpStmt);
// Initialize the reference counter of the Statement Object : used to share the mpStmt with Column objects // Initialize the reference counter of the sqlite3_stmt : used to share the mpStmt with Column objects;
// This is needed to enable Column objects to live longer than the Statement objet it refers to.
mpStmtRefCount = new unsigned int; mpStmtRefCount = new unsigned int;
*mpStmtRefCount = 1; *mpStmtRefCount = 1;
} }
@ -36,13 +37,11 @@ Statement::Statement(Database &aDatabase, const char* apQuery) : // throw(SQLite
// Finalize and unregister the SQL query from the SQLite Database Connection. // Finalize and unregister the SQL query from the SQLite Database Connection.
Statement::~Statement(void) throw() // nothrow Statement::~Statement(void) throw() // nothrow
{ {
// Decrement and check the reference counter // Decrement and check the reference counter of the sqlite3_stmt
(*mpStmtRefCount)--; (*mpStmtRefCount)--;
if (0 == *mpStmtRefCount) if (0 == *mpStmtRefCount)
{ {
// When count reaches zero, dealloc and finalize the statement // If count reaches zero, finalize the sqlite3_stmt, as no Column objet use it anymore
delete mpStmtRefCount;
int ret = sqlite3_finalize(mpStmt); int ret = sqlite3_finalize(mpStmt);
if (SQLITE_OK != ret) if (SQLITE_OK != ret)
{ {
@ -50,7 +49,11 @@ Statement::~Statement(void) throw() // nothrow
//std::cout << sqlite3_errmsg(mpSQLite); //std::cout << sqlite3_errmsg(mpSQLite);
} }
mpStmt = NULL; mpStmt = NULL;
// and delete the reference counter
delete mpStmtRefCount;
} }
// else, the finalization will be done by the last Column object
} }
// Reset the statement to make it ready for a new execution // Reset the statement to make it ready for a new execution

View File

@ -28,6 +28,8 @@ class Column;
* Resource Acquisition Is Initialization (RAII) means that the Statement * Resource Acquisition Is Initialization (RAII) means that the Statement
* is compiled in the constructor and finalized in the destructor, so that there is * is compiled in the constructor and finalized in the destructor, so that there is
* no need to worry about memory management or the validity of the underlying SQLite Statement. * no need to worry about memory management or the validity of the underlying SQLite Statement.
*
* @todo mpStmtRefCount is thread unsafe !
*/ */
class Statement class Statement
{ {
@ -176,7 +178,7 @@ private:
private: private:
sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object
unsigned int* mpStmtRefCount; //!< Pointer to the reference counter of the Statement Object (to share it with Column objects) unsigned int* mpStmtRefCount; //!< Pointer to the heap allocated reference counter of the sqlite3_stmt (to share it with Column objects)
sqlite3* mpSQLite; //!< Pointer to SQLite Database Connection Handle sqlite3* mpSQLite; //!< Pointer to SQLite Database Connection Handle
std::string mQuery; //!< UTF-8 SQL Query std::string mQuery; //!< UTF-8 SQL Query
int mColumnCount; //!< Number of column in the result of the prepared statement int mColumnCount; //!< Number of column in the result of the prepared statement