diff --git a/TODO.txt b/TODO.txt index 09acee6..d7821ff 100644 --- a/TODO.txt +++ b/TODO.txt @@ -2,10 +2,14 @@ C++11 explicit support => V0.5.0 +Update Doxygen Documentation, but remove it from the master branch +Publish the Doxygen Documentation in the Github Pages (gh-pages branch) + Missing features in v0.4.0: - **Blob** => make an example/test with image stored in a row -- getColumnByName ? std::map getRow() ? +- getBytes - getColumnType + isText + isInt + isDouble... +- getColumnByName ? std::map getRow() ? Missing documentation in v0.4.0: - parameters of functions in Column and Statement diff --git a/src/SQLiteC++/Column.cpp b/src/SQLiteC++/Column.cpp index 0077891..148307c 100644 --- a/src/SQLiteC++/Column.cpp +++ b/src/SQLiteC++/Column.cpp @@ -15,7 +15,7 @@ namespace SQLite { // Encapsulation of a Column in a Row of the result. -Column::Column(Statement::Ptr aStmtPtr, int aIndex) throw() : // nothrow +Column::Column(Statement::Ptr& aStmtPtr, int aIndex) throw() : // nothrow mStmtPtr (aStmtPtr), mIndex (aIndex) { @@ -51,12 +51,11 @@ const char* Column::getText(void) const throw() // nothrow return (const char*)sqlite3_column_text(mStmtPtr, mIndex); } - // Standard std::ostream inserter -std::ostream& operator<<(std::ostream &stream, const Column& column) +std::ostream& operator<<(std::ostream& aStream, const Column& aColumn) { - stream << column.getText(); - return stream; + aStream << aColumn.getText(); + return aStream; } } // namespace SQLite diff --git a/src/SQLiteC++/Column.h b/src/SQLiteC++/Column.h index 8e82524..5cea6d2 100644 --- a/src/SQLiteC++/Column.h +++ b/src/SQLiteC++/Column.h @@ -20,18 +20,27 @@ namespace SQLite /** * @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 : it points to a single cell. + * + * Its value can be expressed as a text, and, when applicable, as a numeric + * (integer or floting point) or a binary blob. */ class Column { public: - /// Encapsulation of a Column in a Row of the result. - explicit Column(Statement::Ptr aStmtPtr, int aIndex) throw(); // nothrow + /** + * @brief Encapsulation of a Column in a Row of the result. + * + * @param[in] aStmtPtr Shared pointer to the prepared SQLite Statement Object. + * @param[in] aIndex Index of the column in the row of result + */ + Column(Statement::Ptr& aStmtPtr, int aIndex) throw(); // nothrow /// Simple destructor - virtual ~Column(void) throw(); // nothrow - - // default copy constructor and asignement operator are enough - + virtual ~Column(void) throw(); // nothrow + // default copy constructor and asignement operator are perfectly suited : + // they copy the Statement::Ptr which in turn increments the reference counter. + /// Return the integer value of the column. int getInt (void) const throw(); /// Return the 64bits integer value of the column. @@ -42,7 +51,9 @@ public: /// Warning, the value pointed at is only valid while the statement is valid (ie. not finalized), /// thus you must copy it before using it beyond its scope (to a std::string for instance). const char* getText (void) const throw(); - +// TODO const void* getBlob (void) const throw(); +// TODO int getBytes (void) const throw(); + /// Inline cast operator to int inline operator int() const { @@ -76,12 +87,26 @@ public: } #endif + /// Return UTF-8 encoded English language explanation of the most recent error. + inline const char* errmsg(void) const + { + return sqlite3_errmsg(mStmtPtr); + } private: Statement::Ptr mStmtPtr; //!< Shared Pointer to the prepared SQLite Statement Object int mIndex; //!< Index of the column in the row of result }; -/// Standard std::ostream inserter -std::ostream& operator<<(std::ostream &stream, const Column& column); +/** + * @brief Standard std::ostream text inserter + * + * Insert the text value of the Column object, using getText(), into the provided stream. + * + * @param[in] aStream Stream to use + * @param[in] aColumn Column object to insert into the provided stream + * + * @return Reference to the stream used + */ +std::ostream& operator<<(std::ostream& aStream, const Column& aColumn); } // namespace SQLite diff --git a/src/SQLiteC++/Database.h b/src/SQLiteC++/Database.h index 8a421ea..fa491e7 100644 --- a/src/SQLiteC++/Database.h +++ b/src/SQLiteC++/Database.h @@ -44,7 +44,7 @@ public: * @param[in] apFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter) * @param[in] aFlags SQLITE_OPEN_READONLY/SQLITE_OPEN_READWRITE/SQLITE_OPEN_CREATE... */ - explicit Database(const char* apFilename, const int aFlags = SQLITE_OPEN_READONLY); // throw(SQLite::Exception); + Database(const char* apFilename, const int aFlags = SQLITE_OPEN_READONLY); // throw(SQLite::Exception); /** * @brief Close the SQLite database connection. @@ -135,9 +135,16 @@ public: return mFilename; } + /** + * Return UTF-8 encoded English language explanation of the most recent error. + */ + inline const char* errmsg(void) const + { + return sqlite3_errmsg(mpSQLite); + } + private: // Database must not be copyable - Database(void); Database(const Database&); Database& operator=(const Database&); diff --git a/src/SQLiteC++/Exception.h b/src/SQLiteC++/Exception.h index 26fc222..fbe5306 100644 --- a/src/SQLiteC++/Exception.h +++ b/src/SQLiteC++/Exception.h @@ -39,6 +39,8 @@ class Exception : public std::runtime_error public: /** * Encapsulation of the error message from SQLite3, based on std::runtime_error. + * + * @param[in] aErrorMessage The string message describing the SQLite error */ Exception(const std::string& aErrorMessage) : std::runtime_error(aErrorMessage) diff --git a/src/SQLiteC++/SQLiteC++.h b/src/SQLiteC++/SQLiteC++.h index f6bf9d6..8059ff1 100644 --- a/src/SQLiteC++/SQLiteC++.h +++ b/src/SQLiteC++/SQLiteC++.h @@ -32,5 +32,5 @@ * with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same * numbers used in [SQLITECPP_VERSION]. */ -#define SQLITECPP_VERSION "0.4.0" -#define SQLITECPP_VERSION_NUMBER 0004000 +#define SQLITECPP_VERSION "0.5.0" +#define SQLITECPP_VERSION_NUMBER 0005000 diff --git a/src/SQLiteC++/Statement.cpp b/src/SQLiteC++/Statement.cpp index 67b9805..dd3437b 100644 --- a/src/SQLiteC++/Statement.cpp +++ b/src/SQLiteC++/Statement.cpp @@ -198,7 +198,7 @@ int Statement::exec(void) // throw(SQLite::Exception) // Return a copy of the column data specified by its index starting at 0 // (use the Column copy-constructor) -Column Statement::getColumn(const int aIndex) const // throw(SQLite::Exception) +Column Statement::getColumn(const int aIndex) // throw(SQLite::Exception) { if (false == mbOk) { @@ -282,7 +282,9 @@ Statement::Ptr::Ptr (const Statement::Ptr& aPtr) : ++(*mpRefCount); } -// Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0 +/** + * Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0 + */ Statement::Ptr::~Ptr(void) { assert(NULL != mpRefCount); diff --git a/src/SQLiteC++/Statement.h b/src/SQLiteC++/Statement.h index bb7c01f..442b2e1 100644 --- a/src/SQLiteC++/Statement.h +++ b/src/SQLiteC++/Statement.h @@ -37,9 +37,12 @@ public: /** * @brief Compile and register the SQL query for the provided SQLite Database Connection * + * @param[in] aDatabase the SQLite Database Connection + * @param[in] apQuery an UTF-8 encoded query string + * * Exception is thrown in case of error, then the Statement object is NOT constructed. */ - explicit Statement(Database &aDatabase, const char* apQuery); // throw(SQLite::Exception); + Statement(Database& aDatabase, const char* apQuery); // throw(SQLite::Exception); /** * Finalize and unregister the SQL query from the SQLite Database Connection. @@ -114,6 +117,9 @@ public: /** * @brief Execute a step of the prepared query to fetch one row of results. * + * While true is returned, a row of results is available, and can be accessed + * thru the getColumn() method + * * @see exec() execute a one-step prepared statement with no expected result * @see Database::exec() is a shortcut to execute one or multiple statements without results * @@ -145,57 +151,72 @@ public: //////////////////////////////////////////////////////////////////////////// /** - * @brief Return a copie of the column data specified by its index starting at 0 (aIndex >= 0) + * @brief Return a copie of the column data specified by its index * - * @warning The resulting Column object must not be copied or memorized as it is only valid for a short time, - * only while the row from the Statement remains valid, that is only until next executeStep. - * Thus, you should instead extract immediately its data (getInt()...) and use or copy this data - * for any later usage. + * Can be used to access the data of the current row of result when applicable, + * while the executeStep() method returns true. + * + * Throw an exception if there is no row to return a Column from : + * - before any executeStep() call + * - after the last executeStep() returned false + * - after a reset() call + * + * Throw an exception if the specified index is out of the [0, getColumnCount()) range. + * + * @param[in] aIndex Index of the column, starting at 0 + * + * @note This method is no more const, starting in v0.5, + * which reflects the fact that the returned Column object will + * share the ownership of the underlying sqlite3_stmt. + * + * @warning The resulting Column object must not be memorized "as-is". + * Is is only a wrapper arround the current result row, so it is only valid + * while the row from the Statement remains valid, that is only until next executeStep() call. + * Thus, you should instead extract immediately its data (getInt(), getText()...) + * and use or copy this data for any later usage. */ - Column getColumn(const int aIndex) const; // throw(SQLite::Exception); + Column getColumn(const int aIndex); // throw(SQLite::Exception); /** - * Test if the column is NULL + * Test if the column value is NULL + * + * @param[in] aIndex Index of the column, starting at 0 + * + * @return true if the column value is NULL */ bool isColumnNull(const int aIndex) const; // throw(SQLite::Exception); //////////////////////////////////////////////////////////////////////////// - /** - * UTF-8 SQL Query. - */ + /// Returne the UTF-8 SQL Query. inline const std::string& getQuery(void) const { return mQuery; } - - /** - * 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 { return mColumnCount; } - - /** - * true when the last row is fetched with executeStep(). - */ + /// true when a row has been fetched with executeStep() inline bool isOk(void) const { return mbOk; } - - /** - * true when the last row is fetched with executeStep(). - */ + /// true when the last executeStep() had no more row to fetch inline bool isDone(void) const { return mbDone; } + /// Return UTF-8 encoded English language explanation of the most recent error. + inline const char* errmsg(void) const + { + return sqlite3_errmsg(mStmtPtr); + } public: /** - * Shared pointer to the sqlite3_stmt SQLite Statement Object. + * @brief Shared pointer to the sqlite3_stmt SQLite Statement Object. * * Manage the finalization of the sqlite3_stmt with a reference counter. * @@ -241,15 +262,17 @@ private: /** * Check if a return code equals SQLITE_OK, else throw a SQLite::Exception with the SQLite error message + * + * @param[in] SQLite return code to test against the SQLITE_OK expected value */ void check(const int aRet) const; // throw(SQLite::Exception); private: 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 - bool mbOk; //!< True when a row has been fetched with executeStep() - bool mbDone; //!< True when the last executeStep() had no more row to fetch + int mColumnCount; //!< Number of columns in the result of the prepared statement + bool mbOk; //!< true when a row has been fetched with executeStep() + bool mbDone; //!< true when the last executeStep() had no more row to fetch }; } // namespace SQLite diff --git a/src/SQLiteC++/Transaction.cpp b/src/SQLiteC++/Transaction.cpp index 8cfc1d6..cad0034 100644 --- a/src/SQLiteC++/Transaction.cpp +++ b/src/SQLiteC++/Transaction.cpp @@ -14,8 +14,8 @@ namespace SQLite { -//Begins the SQLite transaction -Transaction::Transaction(Database &aDatabase) : // throw(SQLite::Exception) +// Begins the SQLite transaction +Transaction::Transaction(Database& aDatabase) : // throw(SQLite::Exception) mDatabase(aDatabase), mbCommited(false) { diff --git a/src/SQLiteC++/Transaction.h b/src/SQLiteC++/Transaction.h index 64119d9..a9431d8 100644 --- a/src/SQLiteC++/Transaction.h +++ b/src/SQLiteC++/Transaction.h @@ -35,9 +35,11 @@ public: /** * @brief Begins the SQLite transaction * + * @param[in] aDatabase the SQLite Database Connection + * * Exception is thrown in case of error, then the Transaction is NOT initiated. */ - explicit Transaction(Database &aDatabase); // throw(SQLite::Exception); + explicit Transaction(Database& aDatabase); // throw(SQLite::Exception); /** * @brief Safely rollback the transaction if it has not been committed. @@ -51,7 +53,6 @@ public: private: // Transaction must not be copyable - Transaction(void); Transaction(const Transaction&); Transaction& operator=(const Transaction&); diff --git a/src/example1/main.cpp b/src/example1/main.cpp index f06b5dc..a78efdf 100644 --- a/src/example1/main.cpp +++ b/src/example1/main.cpp @@ -77,13 +77,13 @@ int main (void) // Compile a SQL query, containing one parameter (index 1) SQLite::Statement query(db, "SELECT * FROM test WHERE size > ?"); std::cout << "SQLite statement '" << query.getQuery().c_str() << "' compiled (" << query.getColumnCount () << " columns in the result)\n"; - // Bind the integer value 6 to the first parameter of the SQL query - query.bind(1, 6); + // Bind the integer value 1 to the first parameter of the SQL query + query.bind(1, 1); // Loop to execute the query step by step, to get one a row of results at a time while (query.executeStep()) { - // Demonstrate how to get some typed column value + // Demonstrate how to get some typed column value (and the equivalent explicit call) int id = query.getColumn(0); // = query.getColumn(0).getInt() //const char* pvalue = query.getColumn(1); // = query.getColumn(1).getText() std::string value2 = query.getColumn(1); // = query.getColumn(1).getText()