diff --git a/src/SQLiteC++/Database.cpp b/src/SQLiteC++/Database.cpp index 46307c6..983780c 100644 --- a/src/SQLiteC++/Database.cpp +++ b/src/SQLiteC++/Database.cpp @@ -16,27 +16,21 @@ namespace SQLite { // Open the provided database UTF-8 filename. -Database::Database(const char* apFilename, const bool abReadOnly /*= true*/, const bool abCreate /*= false*/) : + Database::Database(const char* apFilename, const int aFlags /*= SQLITE_OPEN_READONLY*/) throw (SQLite::Exception) : mpSQLite(NULL), mFilename (apFilename) { - int flags = abReadOnly?SQLITE_OPEN_READONLY:SQLITE_OPEN_READWRITE; - if (abCreate) - { - flags |= SQLITE_OPEN_CREATE; - } - - int ret = sqlite3_open_v2(apFilename, &mpSQLite, flags, NULL); + int ret = sqlite3_open_v2(apFilename, &mpSQLite, aFlags, NULL); if (SQLITE_OK != ret) { std::string strerr = sqlite3_errmsg(mpSQLite); sqlite3_close(mpSQLite); - throw std::runtime_error(strerr); + throw SQLite::Exception(strerr); } } // Close the SQLite database connection. -Database::~Database(void) +Database::~Database(void) throw () // nothrow { // check for undestroyed statements std::vector::iterator iStatement; @@ -56,13 +50,13 @@ Database::~Database(void) } // Register a Statement object (a SQLite query) -void Database::registerStatement (Statement& aStatement) +void Database::registerStatement (Statement& aStatement) throw (SQLite::Exception) { mStatementList.push_back (&aStatement); } // Unregister a Statement object -void Database::unregisterStatement (Statement& aStatement) +void Database::unregisterStatement (Statement& aStatement) throw (SQLite::Exception) { std::vector::iterator iStatement; iStatement = std::find (mStatementList.begin(), mStatementList.end(), &aStatement); diff --git a/src/SQLiteC++/Database.h b/src/SQLiteC++/Database.h index 6b723bf..77df398 100644 --- a/src/SQLiteC++/Database.h +++ b/src/SQLiteC++/Database.h @@ -10,15 +10,16 @@ #pragma once #include -#include #include #include +#include "Exception.h" namespace SQLite { -// Forward declaration +// Forward declarations class Statement; +class Exception; /** * @brief Management of a SQLite Database Connection. @@ -34,9 +35,17 @@ public: /** * @brief Open the provided database UTF-8 filename. * + * Uses sqlite3_open_v2() with readonly default flag, which is the opposite behaviour + * of the old sqlite3_open() function (READWRITE+CREATE). + * This makes sense if you want to use it on a readonly filesystem + * or to prenvent 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] 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 bool abReadOnly = true, const bool abCreate = false); + explicit Database(const char* apFilename, const int aFlags = SQLITE_OPEN_READONLY) throw (SQLite::Exception); /** * @brief Close the SQLite database connection. @@ -44,17 +53,17 @@ public: * All SQLite statements must have been finalized before, * so all Statement objects must have been unregistered. */ - virtual ~Database(void); + virtual ~Database(void) throw (); // nothrow /** * @brief Register a Statement object (a SQLite query) */ - void registerStatement (Statement& aStatement); + void registerStatement (Statement& aStatement) throw (SQLite::Exception); /** * @brief Unregister a Statement object */ - void unregisterStatement (Statement& aStatement); + void unregisterStatement (Statement& aStatement) throw (SQLite::Exception); /** * @brief Filename used to open the database diff --git a/src/SQLiteC++/Exception.h b/src/SQLiteC++/Exception.h new file mode 100644 index 0000000..7a2699a --- /dev/null +++ b/src/SQLiteC++/Exception.h @@ -0,0 +1,34 @@ +/** + * @file Exception.h + * @brief Encapsulation of the error message from SQLite3 on a std::runtime_error. + * + * Copyright (c) 2012 Sebastien Rombauts (sebastien dot rombauts at gmail dot com) + * + * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt + * or copy at http://opensource.org/licenses/MIT) + */ +#pragma once + +#include + +#ifdef _WIN32 +#pragma warning(disable:4290) // Disable warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +namespace SQLite +{ + +/** + * @brief Encapsulation of the error message from SQLite3, based on std::runtime_error. + */ +class Exception : public std::runtime_error +{ +public: + Exception(const std::string& aErrorMessage) : + std::runtime_error(aErrorMessage) + { + } +}; + + +}; // namespace SQLite diff --git a/src/SQLiteC++/SQLiteC++.h b/src/SQLiteC++/SQLiteC++.h index 37c603b..57bd35a 100644 --- a/src/SQLiteC++/SQLiteC++.h +++ b/src/SQLiteC++/SQLiteC++.h @@ -1,6 +1,6 @@ /** * @file SQLiteC++.h - * @brief SQLiteC++ is a smart and simple C++ SQLite3 wrapper. + * @brief SQLiteC++ is a smart and simple C++ SQLite3 wrapper. This file is only "easy include" for other files. * * Copyright (c) 2012 Sebastien Rombauts (sebastien dot rombauts at gmail dot com) * diff --git a/src/SQLiteC++/Statement.cpp b/src/SQLiteC++/Statement.cpp index 96e1f24..968751c 100644 --- a/src/SQLiteC++/Statement.cpp +++ b/src/SQLiteC++/Statement.cpp @@ -16,7 +16,8 @@ namespace SQLite { // Compile and register the SQL query for the provided SQLite Database Connection -Statement::Statement(Database &aDatabase, const char* apQuery) : +Statement::Statement(Database &aDatabase, const char* apQuery) throw (SQLite::Exception) : + mpStmt(NULL), mDatabase(aDatabase), mQuery(apQuery), mbDone(false) @@ -24,35 +25,36 @@ Statement::Statement(Database &aDatabase, const char* apQuery) : int ret = sqlite3_prepare_v2(mDatabase.mpSQLite, mQuery.c_str(), mQuery.size(), &mpStmt, NULL); if (SQLITE_OK != ret) { - throw std::runtime_error(sqlite3_errmsg(mDatabase.mpSQLite)); + throw SQLite::Exception(sqlite3_errmsg(mDatabase.mpSQLite)); } mDatabase.registerStatement(*this); } -//Finalize and unregister the SQL query from the SQLite Database Connection. -Statement::~Statement(void) +// Finalize and unregister the SQL query from the SQLite Database Connection. +Statement::~Statement(void) throw () // nothrow { int ret = sqlite3_finalize(mpStmt); if (SQLITE_OK != ret) { std::cout << sqlite3_errmsg(mDatabase.mpSQLite); } + mpStmt = NULL; mDatabase.unregisterStatement(*this); } // Reset the statement to make it ready for a new execution -void Statement::reset (void) +void Statement::reset (void) throw (SQLite::Exception) { mbDone = false; int ret = sqlite3_reset(mpStmt); if (SQLITE_OK != ret) { - throw std::runtime_error(sqlite3_errmsg(mDatabase.mpSQLite)); + throw SQLite::Exception(sqlite3_errmsg(mDatabase.mpSQLite)); } } // Execute a step of the query to fetch one row of results -bool Statement::executeStep (void) +bool Statement::executeStep (void) throw (SQLite::Exception) { bool bOk = false; @@ -70,7 +72,7 @@ bool Statement::executeStep (void) } else { - throw std::runtime_error(sqlite3_errmsg(mDatabase.mpSQLite)); + throw SQLite::Exception(sqlite3_errmsg(mDatabase.mpSQLite)); } } diff --git a/src/SQLiteC++/Statement.h b/src/SQLiteC++/Statement.h index 299e461..cce74f0 100644 --- a/src/SQLiteC++/Statement.h +++ b/src/SQLiteC++/Statement.h @@ -10,7 +10,7 @@ #pragma once #include -#include +#include "Exception.h" namespace SQLite { @@ -32,24 +32,24 @@ public: * * Exception is thrown in case of error, then the Statement object is NOT constructed. */ - explicit Statement(Database &aDatabase, const char* apQuery); + explicit Statement(Database &aDatabase, const char* apQuery) throw (SQLite::Exception); /** * @brief Finalize and unregister the SQL query from the SQLite Database Connection. */ - virtual ~Statement(void); + virtual ~Statement(void) throw (); // nothrow /** * @brief Reset the statement to make it ready for a new execution. */ - void reset (void); + void reset (void) throw (SQLite::Exception); // TODO bind /** * @brief Execute a step of the query to fetch one row of results. */ - bool executeStep (void); + bool executeStep (void) throw (SQLite::Exception); /** * @brief UTF-8 SQL Query.