Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/SQLiteCpp/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ class Database
{
if (SQLITE_OK != aRet)
{
throw SQLite::Exception(sqlite3_errstr(aRet));
throw SQLite::Exception(mpSQLite, aRet);
}
}

Expand Down
103 changes: 84 additions & 19 deletions include/SQLiteCpp/Exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@

#include <stdexcept>
#include <string>
#include <sstream>
#include <sqlite3.h>


/// Compatibility with non-clang compilers.
#ifndef __has_feature
#define __has_feature(x) 0
#endif

// Detect whether the compiler supports C++11 noexcept exception specifications.
#if ( defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)) \
&& defined(__GXX_EXPERIMENTAL_CXX0X__))
// GCC 4.7 and following have noexcept
#elif defined(__clang__) && __has_feature(cxx_noexcept)
// Clang 3.0 and above have noexcept
#elif defined(_MSC_VER) && _MSC_VER > 1800
// Visual Studio 2015 and above have noexcept
#else
// Visual Studio 2013 does not support noexcept, and "throw()" is deprecated by C++11
#define noexcept
#endif


namespace SQLite
Expand All @@ -30,29 +51,73 @@ class Exception : public std::runtime_error
* @param[in] aErrorMessage The string message describing the SQLite error
*/
explicit Exception(const std::string& aErrorMessage) :
std::runtime_error(aErrorMessage)
std::runtime_error(aErrorMessage),
mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense
mExtendedErrcode(-1)
{
}
};

/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] apSQLite The SQLite object, to obtain detailed error messages from.
*/
explicit Exception(sqlite3* apSQLite) :
std::runtime_error(sqlite3_errmsg(apSQLite)),
mErrcode(sqlite3_errcode(apSQLite)),
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{
}

} // namespace SQLite
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] apSQLite The SQLite object, to obtain detailed error messages from.
* @param[in] ret Return value from function call that failed.
*/
explicit Exception(sqlite3* apSQLite, int ret) :
std::runtime_error(sqlite3_errmsg(apSQLite)),
mErrcode(ret),
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{
}

/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] apSQLite The SQLite object, to obtain detailed error messages from.
* @param[in] ret Return value from function call that failed.
* @param[in] aErrorMessage String providing more context, added to the SQLite errmsg
*/
explicit Exception(sqlite3* apSQLite, int ret, const std::string &aErrorMessage) :
std::runtime_error(aErrorMessage + ": " + sqlite3_errmsg(apSQLite)),
mErrcode(ret),
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{
}

/// Compatibility with non-clang compilers.
#ifndef __has_feature
#define __has_feature(x) 0
#endif
/// @brief Return the result code (if any, otherwise -1).
inline int getErrorCode() const noexcept // nothrow
{
return mErrcode;
}

// Detect whether the compiler supports C++11 noexcept exception specifications.
#if ( defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)) \
&& defined(__GXX_EXPERIMENTAL_CXX0X__))
// GCC 4.7 and following have noexcept
#elif defined(__clang__) && __has_feature(cxx_noexcept)
// Clang 3.0 and above have noexcept
#elif defined(_MSC_VER) && _MSC_VER > 1800
// Visual Studio 2015 and above have noexcept
#else
// Visual Studio 2013 does not support noexcept, and "throw()" is deprecated by C++11
#define noexcept
#endif
/// @brief Return the extended numeric result code (if any, otherwise -1).
inline int getExtendedErrorCode() const noexcept // nothrow
{
return mExtendedErrcode;
}

/// @brief Return a string, solely based on the error code
inline const char *getErrStr() const noexcept // nothrow
{
return sqlite3_errstr(mErrcode);
}

private:
const int mErrcode;
const int mExtendedErrcode;
};


} // namespace SQLite
2 changes: 1 addition & 1 deletion include/SQLiteCpp/Statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ class Statement
{
if (SQLITE_OK != aRet)
{
throw SQLite::Exception(sqlite3_errstr(aRet));
throw SQLite::Exception(mStmtPtr, aRet);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/Backup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ Backup::Backup(Database& aDestDatabase,
apSrcDatabaseName);
if (NULL == mpSQLiteBackup)
{
std::string strerr = sqlite3_errmsg(aDestDatabase.getHandle());
throw SQLite::Exception(strerr);
throw SQLite::Exception(aDestDatabase.getHandle());
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ Database::Database(const char* apFilename,
const int ret = sqlite3_open_v2(apFilename, &mpSQLite, aFlags, apVfs);
if (SQLITE_OK != ret)
{
std::string strerr = sqlite3_errstr(ret);
const SQLite::Exception exception(mpSQLite, ret); // must create before closing
sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw SQLite::Exception(strerr);
throw exception;
}

if (aBusyTimeoutMs > 0)
Expand All @@ -58,9 +58,9 @@ Database::Database(const std::string& aFilename,
const int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, aVfs.empty() ? NULL : aVfs.c_str());
if (SQLITE_OK != ret)
{
std::string strerr = sqlite3_errstr(ret);
const SQLite::Exception exception(mpSQLite, ret); // must create before closing
sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw SQLite::Exception(strerr);
throw exception;
}

if (aBusyTimeoutMs > 0)
Expand Down
6 changes: 3 additions & 3 deletions src/Statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ bool Statement::executeStep()
{
mbOk = false;
mbDone = false;
throw SQLite::Exception(sqlite3_errstr(ret));
throw SQLite::Exception(mStmtPtr, ret);
}
}
else
Expand Down Expand Up @@ -227,7 +227,7 @@ int Statement::exec()
{
mbOk = false;
mbDone = false;
throw SQLite::Exception(sqlite3_errstr(ret));
throw SQLite::Exception(mStmtPtr, ret);
}
}
else
Expand Down Expand Up @@ -317,7 +317,7 @@ Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
const int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, NULL);
if (SQLITE_OK != ret)
{
throw SQLite::Exception(sqlite3_errstr(ret));
throw SQLite::Exception(apSQLite, ret);
}
// Initialize the reference counter of the sqlite3_stmt :
// used to share the mStmtPtr between Statement and Column objects;
Expand Down