From 17124b302570a3aa5c11eb1b87e90f626a8b1e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Rombauts?= Date: Wed, 11 Apr 2012 22:30:50 +0200 Subject: [PATCH] Added bind by name methods to the Statement class - v0.2.0 - Added a Changelog file - Updated the TODO file --- CHANGELOG.txt | 15 +++++++++++ TODO.txt | 22 +++++++++------- src/SQLiteC++/SQLiteC++.h | 4 +-- src/SQLiteC++/Statement.cpp | 52 ++++++++++++++++++++++++++++++++++++- src/SQLiteC++/Statement.h | 39 +++++++++++++++++++++++++--- src/SQLiteC++/Transaction.h | 4 +-- src/example1/main.cpp | 6 ++--- 7 files changed, 120 insertions(+), 22 deletions(-) create mode 100644 CHANGELOG.txt diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000..18a5125 --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,15 @@ +Fri Mar 30 + Start of a new thin C++ SQLite wrapper + +Mon Apr 2 + The wrapper is functionnal + Added documentation and examples + Publication on GitHub + +Version 0.1.0 - Wed Apr 4 + Added a Database::exec() methode to execute simple SQL statement + Added a version number like in sqlite3.h, starting with 0.1.0 + +Version 0.2.0 - Wed Apr 11 + Added getLastInsertId() and setBusyTimout() + Added bind() by name methods diff --git a/TODO.txt b/TODO.txt index 228e336..f0165eb 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,23 +1,25 @@ Add a comparison of others C++ wrappers (code style, C++ design, in code documentation, tests, online documentation, examples, license, UTF-16) -Missing features : -- Bind(Name) +Missing features in v0.2.0: +- Statement::execStepAndGetScalar() easy wrapper +- Database::execScalar() easy wrapper like CppSqlite +- Database::tableExists - getColumnByName ? std::map getRow() ? -- operator<< binding ? -- execScalar() easy wrapper like CppSqlite -- TableExists -- batch mode managing multiple queries semicolon separated -- support for different transaction mode +Advanced missing features: +- batch mode managing multiple queries semicolon separated ? - Function ? - Agregate ? -- ATTACH Database ? can already be done by "ATTACH" Statement -- :memory: ? can already be done by Database constructor with ":memory:" filename +- support for different transaction mode ? NO: too specific +- operator<< binding ? NO: redundant with bind() + +- ATTACH Database ? NO: can already be done by "ATTACH" Statement +- :memory: ? NO: can already be done by Database constructor with ":memory:" filename Add a full test suite -Add optionnal usage of experimental sqlite3_trace() function to enable statistics +Add optional usage of experimental sqlite3_trace() function to enable statistics Post an article to CodeProject : Is there a license issue ? Mirror the repository to GoogleCode : with a versionned downloadable ZIP file diff --git a/src/SQLiteC++/SQLiteC++.h b/src/SQLiteC++/SQLiteC++.h index 49b7a3e..c76d45f 100644 --- a/src/SQLiteC++/SQLiteC++.h +++ b/src/SQLiteC++/SQLiteC++.h @@ -31,5 +31,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.1.0" -#define SQLITECPP_VERSION_NUMBER 0001000 +#define SQLITECPP_VERSION "0.2.0" +#define SQLITECPP_VERSION_NUMBER 0002000 diff --git a/src/SQLiteC++/Statement.cpp b/src/SQLiteC++/Statement.cpp index e28e6d0..9e6be6f 100644 --- a/src/SQLiteC++/Statement.cpp +++ b/src/SQLiteC++/Statement.cpp @@ -91,6 +91,56 @@ void Statement::bind(const int aIndex) // throw(SQLite::Exception) check(ret); } + +// Bind an int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement +void Statement::bind(const char* apName, const int& aValue) // throw(SQLite::Exception) +{ + int index = sqlite3_bind_parameter_index(mpStmt, apName); + int ret = sqlite3_bind_int(mpStmt, index, aValue); + check(ret); +} + +// Bind a 64bits int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement +void Statement::bind(const char* apName, const sqlite3_int64& aValue) // throw(SQLite::Exception) +{ + int index = sqlite3_bind_parameter_index(mpStmt, apName); + int ret = sqlite3_bind_int64(mpStmt, index, aValue); + check(ret); +} + +// Bind a double (64bits float) value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement +void Statement::bind(const char* apName, const double& aValue) // throw(SQLite::Exception) +{ + int index = sqlite3_bind_parameter_index(mpStmt, apName); + int ret = sqlite3_bind_double(mpStmt, index, aValue); + check(ret); +} + +// Bind a string value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement +void Statement::bind(const char* apName, const std::string& aValue) // throw(SQLite::Exception) +{ + int index = sqlite3_bind_parameter_index(mpStmt, apName); + int ret = sqlite3_bind_text(mpStmt, index, aValue.c_str(), aValue.size(), SQLITE_TRANSIENT); + check(ret); +} + +// Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement +void Statement::bind(const char* apName, const char* apValue) // throw(SQLite::Exception) +{ + int index = sqlite3_bind_parameter_index(mpStmt, apName); + int ret = sqlite3_bind_text(mpStmt, index, apValue, -1, SQLITE_TRANSIENT); + check(ret); +} + +// Bind a NULL value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement +void Statement::bind(const char* apName) // throw(SQLite::Exception) +{ + int index = sqlite3_bind_parameter_index(mpStmt, apName); + int ret = sqlite3_bind_null(mpStmt, index); + check(ret); +} + + // Execute a step of the query to fetch one row of results bool Statement::executeStep(void) // throw(SQLite::Exception) { @@ -145,7 +195,7 @@ bool Statement::isColumnNull(const int aIndex) const // throw(SQLite::Exception) return (SQLITE_NULL == sqlite3_column_type(mpStmt, aIndex)); } -// @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 Statement::check(const int aRet) const // throw(SQLite::Exception) { if (SQLITE_OK != aRet) diff --git a/src/SQLiteC++/Statement.h b/src/SQLiteC++/Statement.h index 5c01e23..ccdc0e3 100644 --- a/src/SQLiteC++/Statement.h +++ b/src/SQLiteC++/Statement.h @@ -53,6 +53,12 @@ public: void reset(void); // throw(SQLite::Exception); //////////////////////////////////////////////////////////////////////////// + // Bind a value to a parameter of the SQL statement, + // in the form "?" (unnamed), "?NNN", ":VVV", "@VVV" or "$VVV". + // + // Can use the parameter index, starting from "1", to the higher NNN value, + // or the complete parameter name "?NNN", ":VVV", "@VVV" or "$VVV" + // (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) @@ -77,7 +83,32 @@ public: /** * @brief 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); // bind NULL value + 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) + */ + 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) + */ + 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) + */ + 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) + */ + 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) + */ + 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) + */ + void bind(const char* apName); // throw(SQLite::Exception); // bind NULL value //////////////////////////////////////////////////////////////////////////// @@ -199,7 +230,7 @@ public: private: sqlite3* mpSQLite; //!< Pointer to SQLite Database Connection Handle - sqlite3_stmt* mpStmt; //!< Pointeur to SQLite Statement Object + sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object int mIndex; //!< Index of the column in the row of result }; @@ -210,12 +241,12 @@ private: Statement& operator=(const Statement&); /** - * @brief Check if aRet equal SQLITE_OK, else throw a SQLite::Exception with the SQLite error message + * @brief 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_stmt* mpStmt; //!< Pointeur to SQLite Statement Object + sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object Database& mDatabase; //!< Reference to the SQLite Database Connection std::string mQuery; //!< UTF-8 SQL Query int mColumnCount; //!< Number of column in the result of the prepared statement diff --git a/src/SQLiteC++/Transaction.h b/src/SQLiteC++/Transaction.h index 9f63f7d..1e75e94 100644 --- a/src/SQLiteC++/Transaction.h +++ b/src/SQLiteC++/Transaction.h @@ -22,7 +22,7 @@ class Database; * @brief RAII encapsulation of a SQLite Transaction. * * A Transaction is a way to group multiple SQL statements into an atomic secured operation; - * either it succeeds, with all the changes commited to the database file, + * either it succeeds, with all the changes committed to the database file, * or if it fails, all the changes are rolled back to the initial state. * * Resource Acquisition Is Initialization (RAII) means that the Transaction @@ -40,7 +40,7 @@ public: explicit Transaction(Database &aDatabase); // throw(SQLite::Exception); /** - * @brief Safely rollback the transaction if it has not been commited. + * @brief Safely rollback the transaction if it has not been committed. */ virtual ~Transaction(void) throw(); // nothrow diff --git a/src/example1/main.cpp b/src/example1/main.cpp index 60c6e01..c771b4f 100644 --- a/src/example1/main.cpp +++ b/src/example1/main.cpp @@ -23,8 +23,8 @@ class Example { public: Example(void) : - mDb("example.db3"), // Open a database file - mQuery(mDb, "SELECT * FROM test WHERE size > ?") // Compile a SQL query, containing one parameter (index 1) + mDb("example.db3"), // Open a database file + mQuery(mDb, "SELECT * FROM test WHERE size > :min_size")// Compile a SQL query, containing one parameter (index 1) { } virtual ~Example(void) @@ -37,7 +37,7 @@ public: std::cout << "ListGreaterThan (" << aParamValue << ")\n"; // Bind the integer value provided to the first parameter of the SQL query - mQuery.bind(1, aParamValue); + mQuery.bind(":min_size", aParamValue); // same as mQuery.bind(1, aParamValue); // Loop to execute the query step by step, to get one a row of results at a time while (mQuery.executeStep())