std::string API (implementing issue #13

This commit is contained in:
r4d2 2014-01-12 00:15:10 +01:00
parent d7f349ba62
commit 905c3d7bb5
4 changed files with 170 additions and 0 deletions

View File

@ -33,6 +33,20 @@ Database::Database(const char* apFilename, const int aFlags /*= SQLITE_OPEN_READ
} }
} }
// Open the provided database UTF-8 filename with SQLITE_OPEN_xxx provided flags.
Database::Database(const std::string& aFilename, const int aFlags /*= SQLITE_OPEN_READONLY*/) : // throw(SQLite::Exception)
mpSQLite(NULL),
mFilename(aFilename)
{
int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, NULL);
if (SQLITE_OK != ret)
{
std::string strerr = sqlite3_errmsg(mpSQLite);
sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw SQLite::Exception(strerr);
}
}
// Close the SQLite database connection. // Close the SQLite database connection.
Database::~Database(void) throw() // nothrow Database::~Database(void) throw() // nothrow
{ {

View File

@ -56,6 +56,21 @@ public:
*/ */
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 Open the provided database UTF-8 filename.
*
* Uses sqlite3_open_v2() with readonly default flag, which is the opposite behavior
* of the old sqlite3_open() function (READWRITE+CREATE).
* This makes sense if you want to use it on a readonly filesystem
* or to prevent creation of a void file when a required file is missing.
*
* Exception is thrown in case of error, then the Database object is NOT constructed.
*
* @param[in] aFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter)
* @param[in] aFlags SQLITE_OPEN_READONLY/SQLITE_OPEN_READWRITE/SQLITE_OPEN_CREATE...
*/
Database(const std::string& aFilename, const int aFlags = SQLITE_OPEN_READONLY); // throw(SQLite::Exception);
/** /**
* @brief Close the SQLite database connection. * @brief Close the SQLite database connection.
* *
@ -83,6 +98,28 @@ public:
*/ */
int exec(const char* apQueries); // throw(SQLite::Exception); int exec(const char* apQueries); // throw(SQLite::Exception);
/**
* @brief Shortcut to execute one or multiple statements without results.
*
* This is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
* - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
*
* @see Statement::exec() to handle precompiled statements (for better performances) without results
* @see Statement::executeStep() to handle "SELECT" queries with results
*
* @param[in] aQueries one or multiple UTF-8 encoded, semicolon-separate SQL statements
*
* @return number of rows modified by those SQL statements (INSERT, UPDATE or DELETE)
*
* @throw SQLite::Exception in case of error
*/
inline int exec(const std::string& aQueries) // throw(SQLite::Exception);
{
return exec(aQueries.c_str());
}
/** /**
* @brief Shortcut to execute a one step query and fetch the first column of the result. * @brief Shortcut to execute a one step query and fetch the first column of the result.
* *
@ -104,6 +141,30 @@ public:
*/ */
Column execAndGet(const char* apQuery); // throw(SQLite::Exception); Column execAndGet(const char* apQuery); // throw(SQLite::Exception);
/**
* @brief Shortcut to execute a one step query and fetch the first column of the result.
*
* This is a shortcut to execute a simple statement with a single result.
* This should be used only for non reusable queries (else you should use a Statement with bind()).
* This should be used only for queries with expected results (else an exception is fired).
*
* @warning WARNING: Be very careful with this dangerous method: you have to
* make a COPY OF THE result, else it will be destroy before the next line
* (when the underlying temporary Statement and Column objects are destroyed)
*
* @see also Statement class for handling queries with multiple results
*
* @param[in] aQuery an UTF-8 encoded SQL query
*
* @return a temporary Column object with the first column of result.
*
* @throw SQLite::Exception in case of error
*/
inline Column execAndGet(const std::string& aQuery) // throw(SQLite::Exception);
{
return execAndGet(aQuery.c_str());
}
/** /**
* @brief Shortcut to test if a table exists. * @brief Shortcut to test if a table exists.
* *
@ -117,6 +178,22 @@ public:
*/ */
bool tableExists(const char* apTableName); // throw(SQLite::Exception); bool tableExists(const char* apTableName); // throw(SQLite::Exception);
/**
* @brief Shortcut to test if a table exists.
*
* Table names are case sensitive.
*
* @param[in] aTableName an UTF-8 encoded case sensitive Table name
*
* @return true if the table exists.
*
* @throw SQLite::Exception in case of error
*/
inline bool tableExists(const std::string& aTableName) // throw(SQLite::Exception);
{
return tableExists(aTableName.c_str());
}
/** /**
* @brief Set a busy handler that sleeps for a specified amount of time when a table is locked. * @brief Set a busy handler that sleeps for a specified amount of time when a table is locked.
* *

View File

@ -30,6 +30,17 @@ Statement::Statement(Database &aDatabase, const char* apQuery) : // throw(SQLite
mColumnCount = sqlite3_column_count(mStmtPtr); mColumnCount = sqlite3_column_count(mStmtPtr);
} }
// Compile and register the SQL query for the provided SQLite Database Connection
Statement::Statement(Database &aDatabase, const std::string& aQuery) : // throw(SQLite::Exception)
mQuery(aQuery),
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship)
mColumnCount(0),
mbOk(false),
mbDone(false)
{
mColumnCount = sqlite3_column_count(mStmtPtr);
}
// 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
{ {

View File

@ -54,6 +54,16 @@ public:
*/ */
Statement(Database& aDatabase, const char* apQuery); // throw(SQLite::Exception); Statement(Database& aDatabase, const char* apQuery); // throw(SQLite::Exception);
/**
* @brief Compile and register the SQL query for the provided SQLite Database Connection
*
* @param[in] aDatabase the SQLite Database Connection
* @param[in] aQuery an UTF-8 encoded query string
*
* Exception is thrown in case of error, then the Statement object is NOT constructed.
*/
Statement(Database& aDatabase, const std::string& aQuery); // throw(SQLite::Exception);
/** /**
* @brief Finalize and unregister the SQL query from the SQLite Database Connection. * @brief Finalize and unregister the SQL query from the SQLite Database Connection.
*/ */
@ -150,6 +160,64 @@ public:
*/ */
void bind(const char* apName); // throw(SQLite::Exception); // bind NULL value void bind(const char* apName); // throw(SQLite::Exception); // bind NULL value
/**
* @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
inline void bind(const std::string& aName, const int& aValue) // throw(SQLite::Exception);
{
bind(aName.c_str(), aValue);
}
/**
* @brief Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
inline void bind(const std::string& aName, const sqlite3_int64& aValue) // throw(SQLite::Exception);
{
bind(aName.c_str(), aValue);
}
/**
* @brief Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
inline void bind(const std::string& aName, const double& aValue) // throw(SQLite::Exception);
{
bind(aName.c_str(), aValue);
}
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note This uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
inline void bind(const std::string& aName, const std::string& aValue) // throw(SQLite::Exception);
{
bind(aName.c_str(), aValue);
}
/**
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note This uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
inline void bind(const std::string& aName, const char* apValue) // throw(SQLite::Exception);
{
bind(aName.c_str(), apValue);
}
/**
* @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note This uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
inline void bind(const std::string& aName, const void* apValue, const int aSize) // throw(SQLite::Exception);
{
bind(aName.c_str(), apValue, aSize);
}
/**
* @brief Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
inline void bind(const std::string& aName) // throw(SQLite::Exception); // bind NULL value
{
bind(aName.c_str());
}
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
/** /**