most features are implemented #4
41
thirdparty/SQLiteCpp/src/Backup.cpp
vendored
41
thirdparty/SQLiteCpp/src/Backup.cpp
vendored
@ -10,95 +10,78 @@
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Backup.h>
|
||||
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
namespace SQLite {
|
||||
// Initialize resource for SQLite database backup
|
||||
Backup::Backup(Database& aDestDatabase,
|
||||
const char* apDestDatabaseName,
|
||||
Database& aSrcDatabase,
|
||||
const char* apSrcDatabaseName) :
|
||||
mpSQLiteBackup(NULL)
|
||||
const char* apSrcDatabaseName)
|
||||
: mpSQLiteBackup(NULL)
|
||||
{
|
||||
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
|
||||
apDestDatabaseName,
|
||||
aSrcDatabase.getHandle(),
|
||||
apSrcDatabaseName);
|
||||
if (NULL == mpSQLiteBackup)
|
||||
{
|
||||
if (NULL == mpSQLiteBackup) {
|
||||
// If an error occurs, the error code and message are attached to the destination database connection.
|
||||
throw SQLite::Exception(aDestDatabase.getHandle());
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize resource for SQLite database backup
|
||||
Backup::Backup(Database& aDestDatabase,
|
||||
const std::string& aDestDatabaseName,
|
||||
Database& aSrcDatabase,
|
||||
const std::string& aSrcDatabaseName) :
|
||||
mpSQLiteBackup(NULL)
|
||||
const std::string& aSrcDatabaseName)
|
||||
: mpSQLiteBackup(NULL)
|
||||
{
|
||||
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
|
||||
aDestDatabaseName.c_str(),
|
||||
aSrcDatabase.getHandle(),
|
||||
aSrcDatabaseName.c_str());
|
||||
if (NULL == mpSQLiteBackup)
|
||||
{
|
||||
if (NULL == mpSQLiteBackup) {
|
||||
// If an error occurs, the error code and message are attached to the destination database connection.
|
||||
throw SQLite::Exception(aDestDatabase.getHandle());
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize resource for SQLite database backup
|
||||
Backup::Backup(Database &aDestDatabase, Database &aSrcDatabase) :
|
||||
mpSQLiteBackup(NULL)
|
||||
Backup::Backup(Database& aDestDatabase, Database& aSrcDatabase)
|
||||
: mpSQLiteBackup(NULL)
|
||||
{
|
||||
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
|
||||
"main",
|
||||
aSrcDatabase.getHandle(),
|
||||
"main");
|
||||
if (NULL == mpSQLiteBackup)
|
||||
{
|
||||
if (NULL == mpSQLiteBackup) {
|
||||
// If an error occurs, the error code and message are attached to the destination database connection.
|
||||
throw SQLite::Exception(aDestDatabase.getHandle());
|
||||
}
|
||||
}
|
||||
|
||||
// Release resource for SQLite database backup
|
||||
Backup::~Backup()
|
||||
{
|
||||
if (NULL != mpSQLiteBackup)
|
||||
{
|
||||
if (NULL != mpSQLiteBackup) {
|
||||
sqlite3_backup_finish(mpSQLiteBackup);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute backup step with a given number of source pages to be copied
|
||||
int Backup::executeStep(const int aNumPage /* = -1 */)
|
||||
{
|
||||
const int res = sqlite3_backup_step(mpSQLiteBackup, aNumPage);
|
||||
if (SQLITE_OK != res && SQLITE_DONE != res && SQLITE_BUSY != res && SQLITE_LOCKED != res)
|
||||
{
|
||||
if (SQLITE_OK != res && SQLITE_DONE != res && SQLITE_BUSY != res && SQLITE_LOCKED != res) {
|
||||
throw SQLite::Exception(sqlite3_errstr(res), res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Get the number of remaining source pages to be copied in this backup process
|
||||
int Backup::getRemainingPageCount()
|
||||
{
|
||||
return sqlite3_backup_remaining(mpSQLiteBackup);
|
||||
}
|
||||
|
||||
// Get the number of total source pages to be copied in this backup process
|
||||
int Backup::getTotalPageCount()
|
||||
{
|
||||
return sqlite3_backup_pagecount(mpSQLiteBackup);
|
||||
}
|
||||
|
||||
} // namespace SQLite
|
||||
|
29
thirdparty/SQLiteCpp/src/Column.cpp
vendored
29
thirdparty/SQLiteCpp/src/Column.cpp
vendored
@ -9,41 +9,33 @@
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Column.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
const int INTEGER = SQLITE_INTEGER;
|
||||
const int FLOAT = SQLITE_FLOAT;
|
||||
const int TEXT = SQLITE_TEXT;
|
||||
const int BLOB = SQLITE_BLOB;
|
||||
const int Null = SQLITE_NULL;
|
||||
|
||||
|
||||
// Encapsulation of a Column in a row of the result pointed by the prepared Statement.
|
||||
Column::Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept : // nothrow
|
||||
mStmtPtr(aStmtPtr),
|
||||
Column::Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept
|
||||
: // nothrow
|
||||
mStmtPtr(aStmtPtr)
|
||||
,
|
||||
mIndex(aIndex)
|
||||
{
|
||||
}
|
||||
|
||||
// Finalize and unregister the SQL query from the SQLite Database Connection.
|
||||
Column::~Column()
|
||||
{
|
||||
// the finalization will be done by the destructor of the last shared pointer
|
||||
}
|
||||
|
||||
// Return the named assigned to this result column (potentially aliased)
|
||||
const char* Column::getName() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_column_name(mStmtPtr, mIndex);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
// Return the name of the table column that is the origin of this result column
|
||||
const char* Column::getOriginName() const noexcept // nothrow
|
||||
@ -51,74 +43,61 @@ const char* Column::getOriginName() const noexcept // nothrow
|
||||
return sqlite3_column_origin_name(mStmtPtr, mIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Return the integer value of the column specified by its index starting at 0
|
||||
int Column::getInt() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_column_int(mStmtPtr, mIndex);
|
||||
}
|
||||
|
||||
// Return the unsigned integer value of the column specified by its index starting at 0
|
||||
unsigned Column::getUInt() const noexcept // nothrow
|
||||
{
|
||||
return static_cast<unsigned>(getInt64());
|
||||
}
|
||||
|
||||
// Return the 64bits integer value of the column specified by its index starting at 0
|
||||
long long Column::getInt64() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_column_int64(mStmtPtr, mIndex);
|
||||
}
|
||||
|
||||
// Return the double value of the column specified by its index starting at 0
|
||||
double Column::getDouble() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_column_double(mStmtPtr, mIndex);
|
||||
}
|
||||
|
||||
// Return a pointer to the text value (NULL terminated string) of the column specified by its index starting at 0
|
||||
const char* Column::getText(const char* apDefaultValue /* = "" */) const noexcept // nothrow
|
||||
{
|
||||
const char* pText = reinterpret_cast<const char*>(sqlite3_column_text(mStmtPtr, mIndex));
|
||||
return (pText ? pText : apDefaultValue);
|
||||
}
|
||||
|
||||
// Return a pointer to the blob value (*not* NULL terminated) of the column specified by its index starting at 0
|
||||
const void* Column::getBlob() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_column_blob(mStmtPtr, mIndex);
|
||||
}
|
||||
|
||||
// Return a std::string to a TEXT or BLOB column
|
||||
std::string Column::getString() const
|
||||
{
|
||||
// Note: using sqlite3_column_blob and not sqlite3_column_text
|
||||
// - no need for sqlite3_column_text to add a \0 on the end, as we're getting the bytes length directly
|
||||
const char* data = static_cast<const char*>(sqlite3_column_blob(mStmtPtr, mIndex));
|
||||
|
||||
// SQLite docs: "The safest policy is to invoke… sqlite3_column_blob() followed by sqlite3_column_bytes()"
|
||||
// Note: std::string is ok to pass nullptr as first arg, if length is 0
|
||||
return std::string(data, sqlite3_column_bytes(mStmtPtr, mIndex));
|
||||
}
|
||||
|
||||
// Return the type of the value of the column
|
||||
int Column::getType() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_column_type(mStmtPtr, mIndex);
|
||||
}
|
||||
|
||||
// Return the number of bytes used by the text value of the column
|
||||
int Column::getBytes() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_column_bytes(mStmtPtr, mIndex);
|
||||
}
|
||||
|
||||
// Standard std::ostream inserter
|
||||
std::ostream& operator<<(std::ostream& aStream, const Column& aColumn)
|
||||
{
|
||||
aStream.write(aColumn.getText(), aColumn.getBytes());
|
||||
return aStream;
|
||||
}
|
||||
|
||||
|
||||
} // namespace SQLite
|
||||
|
46
thirdparty/SQLiteCpp/src/Database.cpp
vendored
46
thirdparty/SQLiteCpp/src/Database.cpp
vendored
@ -9,52 +9,42 @@
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Database.h>
|
||||
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Assertion.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef SQLITE_DETERMINISTIC
|
||||
#define SQLITE_DETERMINISTIC 0x800
|
||||
#endif // SQLITE_DETERMINISTIC
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
const int OPEN_READONLY = SQLITE_OPEN_READONLY;
|
||||
const int OPEN_READWRITE = SQLITE_OPEN_READWRITE;
|
||||
const int OPEN_CREATE = SQLITE_OPEN_CREATE;
|
||||
const int OPEN_URI = SQLITE_OPEN_URI;
|
||||
|
||||
const int OK = SQLITE_OK;
|
||||
|
||||
const char* VERSION = SQLITE_VERSION;
|
||||
const int VERSION_NUMBER = SQLITE_VERSION_NUMBER;
|
||||
|
||||
// Return SQLite version string using runtime call to the compiled library
|
||||
const char* getLibVersion() noexcept // nothrow
|
||||
{
|
||||
return sqlite3_libversion();
|
||||
}
|
||||
|
||||
// Return SQLite version number using runtime call to the compiled library
|
||||
int getLibVersionNumber() noexcept // nothrow
|
||||
{
|
||||
return sqlite3_libversion_number();
|
||||
}
|
||||
|
||||
|
||||
// Open the provided database UTF-8 filename with SQLite::OPEN_xxx provided flags.
|
||||
Database::Database(const char* apFilename,
|
||||
const int aFlags /* = SQLite::OPEN_READONLY*/,
|
||||
const int aBusyTimeoutMs /* = 0 */,
|
||||
const char* apVfs /* = nullptr*/) :
|
||||
mpSQLite(nullptr),
|
||||
const char* apVfs /* = nullptr*/)
|
||||
:
|
||||
mpSQLite(nullptr)
|
||||
,
|
||||
mFilename(apFilename)
|
||||
{
|
||||
const int ret = sqlite3_open_v2(apFilename, &mpSQLite, aFlags, apVfs);
|
||||
@ -69,13 +59,14 @@ Database::Database(const char* apFilename,
|
||||
setBusyTimeout(aBusyTimeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
// 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*/,
|
||||
const int aBusyTimeoutMs /* = 0 */,
|
||||
const std::string& aVfs /* = "" */) :
|
||||
mpSQLite(nullptr),
|
||||
const std::string& aVfs /* = "" */)
|
||||
:
|
||||
mpSQLite(nullptr)
|
||||
,
|
||||
mFilename(aFilename)
|
||||
{
|
||||
const int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, aVfs.empty() ? nullptr : aVfs.c_str());
|
||||
@ -90,20 +81,16 @@ Database::Database(const std::string& aFilename,
|
||||
setBusyTimeout(aBusyTimeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
// Close the SQLite database connection.
|
||||
Database::~Database()
|
||||
{
|
||||
const int ret = sqlite3_close(mpSQLite);
|
||||
|
||||
// Avoid unreferenced variable warning when build in release mode
|
||||
(void)ret;
|
||||
|
||||
// Only case of error is SQLITE_BUSY: "database is locked" (some statements are not finalized)
|
||||
// Never throw an exception in a destructor :
|
||||
SQLITECPP_ASSERT(SQLITE_OK == ret, "database is locked"); // See SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set a busy handler that sleeps for a specified amount of time when a table is locked.
|
||||
*
|
||||
@ -122,17 +109,14 @@ void Database::setBusyTimeout(const int aBusyTimeoutMs)
|
||||
const int ret = sqlite3_busy_timeout(mpSQLite, aBusyTimeoutMs);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Shortcut to execute one or multiple SQL statements without results (UPDATE, INSERT, ALTER, COMMIT, CREATE...).
|
||||
int Database::exec(const char* apQueries)
|
||||
{
|
||||
const int ret = sqlite3_exec(mpSQLite, apQueries, nullptr, nullptr, nullptr);
|
||||
check(ret);
|
||||
|
||||
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE only)
|
||||
return sqlite3_changes(mpSQLite);
|
||||
}
|
||||
|
||||
// Shortcut to execute a one step query and fetch the first column of the result.
|
||||
// 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
|
||||
@ -145,7 +129,6 @@ Column Database::execAndGet(const char* apQuery)
|
||||
(void)query.executeStep(); // Can return false if no result, which will throw next line in getColumn()
|
||||
return query.getColumn(0);
|
||||
}
|
||||
|
||||
// Shortcut to test if a table exists.
|
||||
bool Database::tableExists(const char* apTableName)
|
||||
{
|
||||
@ -154,37 +137,31 @@ bool Database::tableExists(const char* apTableName)
|
||||
(void)query.executeStep(); // Cannot return false, as the above query always return a result
|
||||
return (1 == query.getColumn(0).getInt());
|
||||
}
|
||||
|
||||
// Get the rowid of the most recent successful INSERT into the database from the current connection.
|
||||
long long Database::getLastInsertRowid() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_last_insert_rowid(mpSQLite);
|
||||
}
|
||||
|
||||
// Get total number of rows modified by all INSERT, UPDATE or DELETE statement since connection.
|
||||
int Database::getTotalChanges() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_total_changes(mpSQLite);
|
||||
}
|
||||
|
||||
// Return the numeric result code for the most recent failed API call (if any).
|
||||
int Database::getErrorCode() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_errcode(mpSQLite);
|
||||
}
|
||||
|
||||
// Return the extended numeric result code for the most recent failed API call (if any).
|
||||
int Database::getExtendedErrorCode() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_extended_errcode(mpSQLite);
|
||||
}
|
||||
|
||||
// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
|
||||
const char* Database::getErrorMsg() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_errmsg(mpSQLite);
|
||||
}
|
||||
|
||||
// Attach a custom function to your sqlite database. Assumes UTF8 text representation.
|
||||
// Parameter details can be found here: http://www.sqlite.org/c3ref/create_function.html
|
||||
void Database::createFunction(const char* apFuncName,
|
||||
@ -206,7 +183,6 @@ void Database::createFunction(const char* apFuncName,
|
||||
apApp, apFunc, apStep, apFinal, apDestroy);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Load an extension into the sqlite database. Only affects the current connection.
|
||||
// Parameter details can be found here: http://www.sqlite.org/c3ref/load_extension.html
|
||||
void Database::loadExtension(const char* apExtensionName, const char* apEntryPointName)
|
||||
@ -215,7 +191,6 @@ void Database::loadExtension(const char* apExtensionName, const char *apEntryPoi
|
||||
// Unused
|
||||
(void)apExtensionName;
|
||||
(void)apEntryPointName;
|
||||
|
||||
throw std::runtime_error("sqlite extensions are disabled");
|
||||
#else
|
||||
#ifdef SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION // Since SQLite 3.13 (2016-05-18):
|
||||
@ -229,12 +204,10 @@ void Database::loadExtension(const char* apExtensionName, const char *apEntryPoi
|
||||
int ret = sqlite3_enable_load_extension(mpSQLite, 1);
|
||||
#endif
|
||||
check(ret);
|
||||
|
||||
ret = sqlite3_load_extension(mpSQLite, apExtensionName, apEntryPointName, 0);
|
||||
check(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set the key for the current sqlite database instance.
|
||||
void Database::key(const std::string& aKey) const
|
||||
{
|
||||
@ -253,7 +226,6 @@ void Database::key(const std::string& aKey) const
|
||||
}
|
||||
#endif // SQLITE_HAS_CODEC
|
||||
}
|
||||
|
||||
// Reset the key for the current sqlite database instance.
|
||||
void Database::rekey(const std::string& aNewKey) const
|
||||
{
|
||||
@ -275,7 +247,6 @@ void Database::rekey(const std::string& aNewKey) const
|
||||
throw exception;
|
||||
#endif // SQLITE_HAS_CODEC
|
||||
}
|
||||
|
||||
// Test if a file contains an unencrypted database.
|
||||
bool Database::isUnencrypted(const std::string& aFilename)
|
||||
{
|
||||
@ -299,5 +270,4 @@ bool Database::isUnencrypted(const std::string& aFilename)
|
||||
const SQLite::Exception exception("Could not open database, the aFilename parameter was empty.");
|
||||
throw exception;
|
||||
}
|
||||
|
||||
} // namespace SQLite
|
||||
|
65
thirdparty/SQLiteCpp/src/Exception.cpp
vendored
65
thirdparty/SQLiteCpp/src/Exception.cpp
vendored
@ -9,59 +9,66 @@
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
Exception::Exception(const char* aErrorMessage) :
|
||||
std::runtime_error(aErrorMessage),
|
||||
mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense
|
||||
Exception::Exception(const char* aErrorMessage)
|
||||
:
|
||||
std::runtime_error(aErrorMessage)
|
||||
,
|
||||
mErrcode(-1)
|
||||
, // 0 would be SQLITE_OK, which doesn't make sense
|
||||
mExtendedErrcode(-1)
|
||||
{
|
||||
}
|
||||
Exception::Exception(const std::string& aErrorMessage) :
|
||||
std::runtime_error(aErrorMessage),
|
||||
mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense
|
||||
Exception::Exception(const std::string& aErrorMessage)
|
||||
:
|
||||
std::runtime_error(aErrorMessage)
|
||||
,
|
||||
mErrcode(-1)
|
||||
, // 0 would be SQLITE_OK, which doesn't make sense
|
||||
mExtendedErrcode(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Exception::Exception(const char* aErrorMessage, int ret) :
|
||||
std::runtime_error(aErrorMessage),
|
||||
mErrcode(ret),
|
||||
Exception::Exception(const char* aErrorMessage, int ret)
|
||||
:
|
||||
std::runtime_error(aErrorMessage)
|
||||
,
|
||||
mErrcode(ret)
|
||||
,
|
||||
mExtendedErrcode(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Exception::Exception(const std::string& aErrorMessage, int ret) :
|
||||
std::runtime_error(aErrorMessage),
|
||||
mErrcode(ret),
|
||||
Exception::Exception(const std::string& aErrorMessage, int ret)
|
||||
:
|
||||
std::runtime_error(aErrorMessage)
|
||||
,
|
||||
mErrcode(ret)
|
||||
,
|
||||
mExtendedErrcode(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Exception::Exception(sqlite3* apSQLite) :
|
||||
std::runtime_error(sqlite3_errmsg(apSQLite)),
|
||||
mErrcode(sqlite3_errcode(apSQLite)),
|
||||
Exception::Exception(sqlite3* apSQLite)
|
||||
:
|
||||
std::runtime_error(sqlite3_errmsg(apSQLite))
|
||||
,
|
||||
mErrcode(sqlite3_errcode(apSQLite))
|
||||
,
|
||||
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
|
||||
{
|
||||
}
|
||||
|
||||
Exception::Exception(sqlite3* apSQLite, int ret) :
|
||||
std::runtime_error(sqlite3_errmsg(apSQLite)),
|
||||
mErrcode(ret),
|
||||
Exception::Exception(sqlite3* apSQLite, int ret)
|
||||
:
|
||||
std::runtime_error(sqlite3_errmsg(apSQLite))
|
||||
,
|
||||
mErrcode(ret)
|
||||
,
|
||||
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
|
||||
{
|
||||
}
|
||||
|
||||
// Return a string, solely based on the error code
|
||||
const char* Exception::getErrorStr() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_errstr(mErrcode);
|
||||
}
|
||||
|
||||
|
||||
} // namespace SQLite
|
||||
|
142
thirdparty/SQLiteCpp/src/Statement.cpp
vendored
142
thirdparty/SQLiteCpp/src/Statement.cpp
vendored
@ -9,45 +9,54 @@
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Column.h>
|
||||
#include <SQLiteCpp/Assertion.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
// Compile and register the SQL query for the provided SQLite Database Connection
|
||||
Statement::Statement(Database &aDatabase, const char* apQuery) :
|
||||
mQuery(apQuery),
|
||||
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship)
|
||||
mColumnCount(0),
|
||||
mbHasRow(false),
|
||||
Statement::Statement(Database& aDatabase, const char* apQuery)
|
||||
:
|
||||
mQuery(apQuery)
|
||||
,
|
||||
mStmtPtr(aDatabase.mpSQLite, mQuery)
|
||||
, // prepare the SQL query, and ref count (needs Database friendship)
|
||||
mColumnCount(0)
|
||||
,
|
||||
mbHasRow(false)
|
||||
,
|
||||
mbDone(false)
|
||||
{
|
||||
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) :
|
||||
mQuery(aQuery),
|
||||
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship)
|
||||
mColumnCount(0),
|
||||
mbHasRow(false),
|
||||
Statement::Statement(Database& aDatabase, const std::string& aQuery)
|
||||
:
|
||||
mQuery(aQuery)
|
||||
,
|
||||
mStmtPtr(aDatabase.mpSQLite, mQuery)
|
||||
, // prepare the SQL query, and ref count (needs Database friendship)
|
||||
mColumnCount(0)
|
||||
,
|
||||
mbHasRow(false)
|
||||
,
|
||||
mbDone(false)
|
||||
{
|
||||
mColumnCount = sqlite3_column_count(mStmtPtr);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
|
||||
Statement::Statement(Statement&& aStatement) noexcept :
|
||||
mQuery(std::move(aStatement.mQuery)),
|
||||
mStmtPtr(std::move(aStatement.mStmtPtr)),
|
||||
mColumnCount(aStatement.mColumnCount),
|
||||
mbHasRow(aStatement.mbHasRow),
|
||||
Statement::Statement(Statement&& aStatement) noexcept
|
||||
:
|
||||
mQuery(std::move(aStatement.mQuery))
|
||||
,
|
||||
mStmtPtr(std::move(aStatement.mStmtPtr))
|
||||
,
|
||||
mColumnCount(aStatement.mColumnCount)
|
||||
,
|
||||
mbHasRow(aStatement.mbHasRow)
|
||||
,
|
||||
mbDone(aStatement.mbDone)
|
||||
{
|
||||
aStatement.mColumnCount = 0;
|
||||
@ -55,62 +64,53 @@ Statement::Statement(Statement&& aStatement) noexcept :
|
||||
aStatement.mbDone = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Finalize and unregister the SQL query from the SQLite Database Connection.
|
||||
Statement::~Statement()
|
||||
{
|
||||
// the finalization will be done by the destructor of the last shared pointer
|
||||
}
|
||||
|
||||
// Reset the statement to make it ready for a new execution (see also #clearBindings() bellow)
|
||||
void Statement::reset()
|
||||
{
|
||||
const int ret = tryReset();
|
||||
check(ret);
|
||||
}
|
||||
|
||||
int Statement::tryReset() noexcept
|
||||
{
|
||||
mbHasRow = false;
|
||||
mbDone = false;
|
||||
return sqlite3_reset(mStmtPtr);
|
||||
}
|
||||
|
||||
// Clears away all the bindings of a prepared statement (can be associated with #reset() above).
|
||||
void Statement::clearBindings()
|
||||
{
|
||||
const int ret = sqlite3_clear_bindings(mStmtPtr);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const int aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_int(mStmtPtr, aIndex, aValue);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a 32bits unsigned int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const unsigned aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_int64(mStmtPtr, aIndex, 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 int aIndex, const long long aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_int64(mStmtPtr, aIndex, 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 int aIndex, const double aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_double(mStmtPtr, aIndex, aValue);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const std::string& aValue)
|
||||
{
|
||||
@ -118,21 +118,18 @@ void Statement::bind(const int aIndex, const std::string& aValue)
|
||||
static_cast<int>(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 int aIndex, const char* apValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_TRANSIENT);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const void* apValue, const int aSize)
|
||||
{
|
||||
const int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, aSize, SQLITE_TRANSIENT);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bindNoCopy(const int aIndex, const std::string& aValue)
|
||||
{
|
||||
@ -140,29 +137,24 @@ void Statement::bindNoCopy(const int aIndex, const std::string& aValue)
|
||||
static_cast<int>(aValue.size()), SQLITE_STATIC);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bindNoCopy(const int aIndex, const char* apValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_STATIC);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bindNoCopy(const int aIndex, const void* apValue, const int aSize)
|
||||
{
|
||||
const int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, aSize, SQLITE_STATIC);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex)
|
||||
{
|
||||
const int ret = sqlite3_bind_null(mStmtPtr, aIndex);
|
||||
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)
|
||||
{
|
||||
@ -170,7 +162,6 @@ void Statement::bind(const char* apName, const int aValue)
|
||||
const int ret = sqlite3_bind_int(mStmtPtr, index, aValue);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a 32bits unsigned int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const char* apName, const unsigned aValue)
|
||||
{
|
||||
@ -178,7 +169,6 @@ void Statement::bind(const char* apName, const unsigned aValue)
|
||||
const int ret = sqlite3_bind_int64(mStmtPtr, 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 long long aValue)
|
||||
{
|
||||
@ -186,7 +176,6 @@ void Statement::bind(const char* apName, const long long aValue)
|
||||
const int ret = sqlite3_bind_int64(mStmtPtr, 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)
|
||||
{
|
||||
@ -194,7 +183,6 @@ void Statement::bind(const char* apName, const double aValue)
|
||||
const int ret = sqlite3_bind_double(mStmtPtr, 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)
|
||||
{
|
||||
@ -203,7 +191,6 @@ void Statement::bind(const char* apName, const std::string& aValue)
|
||||
static_cast<int>(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)
|
||||
{
|
||||
@ -211,7 +198,6 @@ void Statement::bind(const char* apName, const char* apValue)
|
||||
const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_TRANSIENT);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a binary blob value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const char* apName, const void* apValue, const int aSize)
|
||||
{
|
||||
@ -219,7 +205,6 @@ void Statement::bind(const char* apName, const void* apValue, const int aSize)
|
||||
const int ret = sqlite3_bind_blob(mStmtPtr, index, apValue, aSize, SQLITE_TRANSIENT);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a string value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bindNoCopy(const char* apName, const std::string& aValue)
|
||||
{
|
||||
@ -228,7 +213,6 @@ void Statement::bindNoCopy(const char* apName, const std::string& aValue)
|
||||
static_cast<int>(aValue.size()), SQLITE_STATIC);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bindNoCopy(const char* apName, const char* apValue)
|
||||
{
|
||||
@ -236,7 +220,6 @@ void Statement::bindNoCopy(const char* apName, const char* apValue)
|
||||
const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_STATIC);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a binary blob value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bindNoCopy(const char* apName, const void* apValue, const int aSize)
|
||||
{
|
||||
@ -244,7 +227,6 @@ void Statement::bindNoCopy(const char* apName, const void* apValue, const int aS
|
||||
const int ret = sqlite3_bind_blob(mStmtPtr, index, apValue, aSize, SQLITE_STATIC);
|
||||
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)
|
||||
{
|
||||
@ -252,8 +234,6 @@ void Statement::bind(const char* apName)
|
||||
const int ret = sqlite3_bind_null(mStmtPtr, index);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
|
||||
// Execute a step of the query to fetch one row of results
|
||||
bool Statement::executeStep()
|
||||
{
|
||||
@ -269,10 +249,8 @@ bool Statement::executeStep()
|
||||
throw SQLite::Exception("Statement needs to be reseted", ret);
|
||||
}
|
||||
}
|
||||
|
||||
return mbHasRow; // true only if one row is accessible by getColumn(N)
|
||||
}
|
||||
|
||||
// Execute a one-step query with no expected result
|
||||
int Statement::exec()
|
||||
{
|
||||
@ -292,11 +270,9 @@ int Statement::exec()
|
||||
throw SQLite::Exception("Statement needs to be reseted", ret);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE)
|
||||
return sqlite3_changes(mStmtPtr);
|
||||
}
|
||||
|
||||
int Statement::tryExecuteStep() noexcept
|
||||
{
|
||||
if (false == mbDone)
|
||||
@ -316,7 +292,6 @@ int Statement::tryExecuteStep() noexcept
|
||||
mbHasRow = false;
|
||||
mbDone = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
@ -325,30 +300,24 @@ int Statement::tryExecuteStep() noexcept
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
{
|
||||
checkRow();
|
||||
checkIndex(aIndex);
|
||||
|
||||
// Share the Statement Object handle with the new Column created
|
||||
return Column(mStmtPtr, aIndex);
|
||||
}
|
||||
|
||||
// Return a copy of the column data specified by its column name starting at 0
|
||||
// (use the Column copy-constructor)
|
||||
Column Statement::getColumn(const char* apName)
|
||||
{
|
||||
checkRow();
|
||||
const int index = getColumnIndex(apName);
|
||||
|
||||
// Share the Statement Object handle with the new Column created
|
||||
return Column(mStmtPtr, index);
|
||||
}
|
||||
|
||||
// Test if the column is NULL
|
||||
bool Statement::isColumnNull(const int aIndex) const
|
||||
{
|
||||
@ -356,21 +325,18 @@ bool Statement::isColumnNull(const int aIndex) const
|
||||
checkIndex(aIndex);
|
||||
return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, aIndex));
|
||||
}
|
||||
|
||||
bool Statement::isColumnNull(const char* apName) const
|
||||
{
|
||||
checkRow();
|
||||
const int index = getColumnIndex(apName);
|
||||
return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, index));
|
||||
}
|
||||
|
||||
// Return the named assigned to the specified result column (potentially aliased)
|
||||
const char* Statement::getColumnName(const int aIndex) const
|
||||
{
|
||||
checkIndex(aIndex);
|
||||
return sqlite3_column_name(mStmtPtr, aIndex);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
// Return the named assigned to the specified result column (potentially aliased)
|
||||
const char* Statement::getColumnOriginName(const int aIndex) const
|
||||
@ -379,7 +345,6 @@ const char* Statement::getColumnOriginName(const int aIndex) const
|
||||
return sqlite3_column_origin_name(mStmtPtr, aIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Return the index of the specified (potentially aliased) column name
|
||||
int Statement::getColumnIndex(const char* apName) const
|
||||
{
|
||||
@ -392,60 +357,55 @@ int Statement::getColumnIndex(const char* apName) const
|
||||
mColumnNames[pName] = i;
|
||||
}
|
||||
}
|
||||
|
||||
const TColumnNames::const_iterator iIndex = mColumnNames.find(apName);
|
||||
if (iIndex == mColumnNames.end())
|
||||
{
|
||||
throw SQLite::Exception("Unknown column name.");
|
||||
}
|
||||
|
||||
return (*iIndex).second;
|
||||
}
|
||||
|
||||
int Statement::getBindParameterCount() const noexcept
|
||||
{
|
||||
return sqlite3_bind_parameter_count(mStmtPtr);
|
||||
}
|
||||
|
||||
// Return the numeric result code for the most recent failed API call (if any).
|
||||
int Statement::getErrorCode() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_errcode(mStmtPtr);
|
||||
}
|
||||
|
||||
// Return the extended numeric result code for the most recent failed API call (if any).
|
||||
int Statement::getExtendedErrorCode() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_extended_errcode(mStmtPtr);
|
||||
}
|
||||
|
||||
// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
|
||||
const char* Statement::getErrorMsg() const noexcept // nothrow
|
||||
{
|
||||
return sqlite3_errmsg(mStmtPtr);
|
||||
}
|
||||
|
||||
// Return a UTF-8 string containing the SQL text of prepared statement with bound parameters expanded.
|
||||
std::string Statement::getExpandedSQL() {
|
||||
std::string Statement::getExpandedSQL()
|
||||
{
|
||||
char* expanded = sqlite3_expanded_sql(mStmtPtr);
|
||||
std::string expandedString(expanded);
|
||||
sqlite3_free(expanded);
|
||||
return expandedString;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Internal class : shared pointer to the sqlite3_stmt SQLite Statement Object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Prepare the statement and initialize its reference counter
|
||||
*
|
||||
* @param[in] apSQLite The sqlite3 database connexion
|
||||
* @param[in] aQuery The SQL query string to prepare
|
||||
*/
|
||||
Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
|
||||
mpSQLite(apSQLite),
|
||||
mpStmt(NULL),
|
||||
Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery)
|
||||
:
|
||||
mpSQLite(apSQLite)
|
||||
,
|
||||
mpStmt(NULL)
|
||||
,
|
||||
mpRefCount(NULL)
|
||||
{
|
||||
const int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, NULL);
|
||||
@ -458,29 +418,32 @@ Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
|
||||
// This is needed to enable Column objects to live longer than the Statement objet it refers to.
|
||||
mpRefCount = new unsigned int(1); // NOLINT(readability/casting)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor increments the ref counter
|
||||
*
|
||||
* @param[in] aPtr Pointer to copy
|
||||
*/
|
||||
Statement::Ptr::Ptr(const Statement::Ptr& aPtr) :
|
||||
mpSQLite(aPtr.mpSQLite),
|
||||
mpStmt(aPtr.mpStmt),
|
||||
Statement::Ptr::Ptr(const Statement::Ptr& aPtr)
|
||||
:
|
||||
mpSQLite(aPtr.mpSQLite)
|
||||
,
|
||||
mpStmt(aPtr.mpStmt)
|
||||
,
|
||||
mpRefCount(aPtr.mpRefCount)
|
||||
{
|
||||
assert(NULL != mpRefCount);
|
||||
assert(0 != *mpRefCount);
|
||||
|
||||
// Increment the reference counter of the sqlite3_stmt,
|
||||
// asking not to finalize the sqlite3_stmt during the lifetime of the new objet
|
||||
++(*mpRefCount);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
|
||||
Statement::Ptr::Ptr(Ptr&& aPtr) :
|
||||
mpSQLite(aPtr.mpSQLite),
|
||||
mpStmt(aPtr.mpStmt),
|
||||
Statement::Ptr::Ptr(Ptr&& aPtr)
|
||||
:
|
||||
mpSQLite(aPtr.mpSQLite)
|
||||
,
|
||||
mpStmt(aPtr.mpStmt)
|
||||
,
|
||||
mpRefCount(aPtr.mpRefCount)
|
||||
{
|
||||
aPtr.mpSQLite = NULL;
|
||||
@ -488,7 +451,6 @@ Statement::Ptr::Ptr(Ptr&& aPtr) :
|
||||
aPtr.mpRefCount = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0
|
||||
*/
|
||||
@ -497,7 +459,6 @@ Statement::Ptr::~Ptr()
|
||||
if (NULL != mpRefCount)
|
||||
{
|
||||
assert(0 != *mpRefCount);
|
||||
|
||||
// Decrement and check the reference counter of the sqlite3_stmt
|
||||
--(*mpRefCount);
|
||||
if (0 == *mpRefCount)
|
||||
@ -505,7 +466,6 @@ Statement::Ptr::~Ptr()
|
||||
// If count reaches zero, finalize the sqlite3_stmt, as no Statement nor Column objet use it anymore.
|
||||
// No need to check the return code, as it is the same as the last statement evaluation.
|
||||
sqlite3_finalize(mpStmt);
|
||||
|
||||
// and delete the reference counter
|
||||
delete mpRefCount;
|
||||
mpRefCount = NULL;
|
||||
@ -514,6 +474,4 @@ Statement::Ptr::~Ptr()
|
||||
// else, the finalization will be done later, by the last object
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace SQLite
|
||||
|
15
thirdparty/SQLiteCpp/src/Transaction.cpp
vendored
15
thirdparty/SQLiteCpp/src/Transaction.cpp
vendored
@ -9,23 +9,19 @@
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Transaction.h>
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Assertion.h>
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
|
||||
// Begins the SQLite transaction
|
||||
Transaction::Transaction(Database& aDatabase) :
|
||||
mDatabase(aDatabase),
|
||||
Transaction::Transaction(Database& aDatabase)
|
||||
:
|
||||
mDatabase(aDatabase)
|
||||
,
|
||||
mbCommited(false)
|
||||
{
|
||||
mDatabase.exec("BEGIN");
|
||||
}
|
||||
|
||||
// Safely rollback the transaction if it has not been committed.
|
||||
Transaction::~Transaction()
|
||||
{
|
||||
@ -41,7 +37,6 @@ Transaction::~Transaction()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Commit the transaction.
|
||||
void Transaction::commit()
|
||||
{
|
||||
@ -55,6 +50,4 @@ void Transaction::commit()
|
||||
throw SQLite::Exception("Transaction already commited.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace SQLite
|
||||
|
Loading…
Reference in New Issue
Block a user