Small improvements & code cleanup

This commit is contained in:
Kacperos155 2022-07-23 16:07:53 +02:00
parent 9158225e5d
commit be5400ca99
10 changed files with 54 additions and 58 deletions

View File

@ -14,6 +14,7 @@
#include <SQLiteCpp/Database.h> #include <SQLiteCpp/Database.h>
#include <string> #include <string>
#include <memory>
// Forward declaration to avoid inclusion of <sqlite3.h> in a header // Forward declaration to avoid inclusion of <sqlite3.h> in a header
struct sqlite3_backup; struct sqlite3_backup;
@ -95,9 +96,6 @@ public:
Backup(const Backup&) = delete; Backup(const Backup&) = delete;
Backup& operator=(const Backup&) = delete; Backup& operator=(const Backup&) = delete;
/// Release the SQLite Backup resource.
~Backup();
/** /**
* @brief Execute a step of backup with a given number of source pages to be copied * @brief Execute a step of backup with a given number of source pages to be copied
* *
@ -114,14 +112,19 @@ public:
int executeStep(const int aNumPage = -1); int executeStep(const int aNumPage = -1);
/// Return the number of source pages still to be backed up as of the most recent call to executeStep(). /// Return the number of source pages still to be backed up as of the most recent call to executeStep().
int getRemainingPageCount(); int getRemainingPageCount() const;
/// Return the total number of pages in the source database as of the most recent call to executeStep(). /// Return the total number of pages in the source database as of the most recent call to executeStep().
int getTotalPageCount(); int getTotalPageCount() const;
private: private:
// TODO: use std::unique_ptr with a custom deleter to call sqlite3_backup_finish() // Deleter functor to use with smart pointers to close the SQLite database backup in an RAII fashion.
sqlite3_backup* mpSQLiteBackup = nullptr; ///< Pointer to SQLite Database Backup Handle struct Deleter
{
void operator()(sqlite3_backup* apBackup);
};
std::unique_ptr<sqlite3_backup, Deleter> mpSQLiteBackup{}; ///< Pointer to SQLite Database Backup Handle
}; };
} // namespace SQLite } // namespace SQLite

View File

@ -78,8 +78,8 @@ extern const int OPEN_NOFOLLOW; // SQLITE_OPEN_NOFOLLOW
extern const int OK; ///< SQLITE_OK (used by check() bellow) extern const int OK; ///< SQLITE_OK (used by check() bellow)
extern const char* VERSION; ///< SQLITE_VERSION string from the sqlite3.h used at compile time extern const char* const VERSION; ///< SQLITE_VERSION string from the sqlite3.h used at compile time
extern const int VERSION_NUMBER; ///< SQLITE_VERSION_NUMBER from the sqlite3.h used at compile time extern const int VERSION_NUMBER; ///< SQLITE_VERSION_NUMBER from the sqlite3.h used at compile time
/// Return SQLite version string using runtime call to the compiled library /// Return SQLite version string using runtime call to the compiled library
const char* getLibVersion() noexcept; const char* getLibVersion() noexcept;
@ -328,7 +328,7 @@ public:
* *
* @return the sqlite result code. * @return the sqlite result code.
*/ */
int tryExec(const std::string aQueries) noexcept int tryExec(const std::string& aQueries) noexcept
{ {
return tryExec(aQueries.c_str()); return tryExec(aQueries.c_str());
} }
@ -389,7 +389,7 @@ public:
* *
* @throw SQLite::Exception in case of error * @throw SQLite::Exception in case of error
*/ */
bool tableExists(const char* apTableName); bool tableExists(const char* apTableName) const;
/** /**
* @brief Shortcut to test if a table exists. * @brief Shortcut to test if a table exists.
@ -402,7 +402,7 @@ public:
* *
* @throw SQLite::Exception in case of error * @throw SQLite::Exception in case of error
*/ */
bool tableExists(const std::string& aTableName) bool tableExists(const std::string& aTableName) const
{ {
return tableExists(aTableName.c_str()); return tableExists(aTableName.c_str());
} }
@ -552,7 +552,7 @@ public:
static Header getHeaderInfo(const std::string& aFilename); static Header getHeaderInfo(const std::string& aFilename);
// Parse SQLite header data from a database file. // Parse SQLite header data from a database file.
Header getHeaderInfo() Header getHeaderInfo() const
{ {
return getHeaderInfo(mFilename); return getHeaderInfo(mFilename);
} }

View File

@ -66,7 +66,7 @@ class Savepoint {
* Exception is thrown in case of error, then the Savepoint is NOT * Exception is thrown in case of error, then the Savepoint is NOT
* initiated. * initiated.
*/ */
Savepoint(Database& aDatabase, std::string name); Savepoint(Database& aDatabase, const std::string& name);
// Savepoint is non-copyable // Savepoint is non-copyable
Savepoint(const Savepoint&) = delete; Savepoint(const Savepoint&) = delete;
@ -88,8 +88,8 @@ class Savepoint {
void rollback(); void rollback();
private: private:
Database& mDatabase; ///< Reference to the SQLite Database Connection Database& mDatabase; ///< Reference to the SQLite Database Connection
std::string msName; ///< Name of the Savepoint std::string msName; ///< Name of the Savepoint
bool mbReleased; ///< True when release has been called bool mbReleased{ false }; ///< True when release has been called
}; };
} // namespace SQLite } // namespace SQLite

View File

@ -74,18 +74,14 @@ public:
Statement(aDatabase, aQuery.c_str()) Statement(aDatabase, aQuery.c_str())
{} {}
/**
* @brief Move an SQLite statement.
*
* @param[in] aStatement Statement to move
*/
Statement(Statement&& aStatement) noexcept;
Statement& operator=(Statement&& aStatement) noexcept = default;
// Statement is non-copyable // Statement is non-copyable
Statement(const Statement&) = delete; Statement(const Statement&) = delete;
Statement& operator=(const Statement&) = delete; Statement& operator=(const Statement&) = delete;
Statement(Statement&& aStatement) noexcept;
Statement& operator=(Statement&& aStatement) noexcept = default;
// TODO: Change Statement move constructor to default
/// Finalize and unregister the SQL query from the SQLite Database Connection. /// Finalize and unregister the SQL query from the SQLite Database Connection.
/// The finalization will be done by the destructor of the last shared pointer /// The finalization will be done by the destructor of the last shared pointer
~Statement() = default; ~Statement() = default;
@ -705,7 +701,7 @@ private:
int mColumnCount{0}; //!< Number of columns in the result of the prepared statement int mColumnCount{0}; //!< Number of columns in the result of the prepared statement
bool mbHasRow{false}; //!< true when a row has been fetched with executeStep() bool mbHasRow{false}; //!< true when a row has been fetched with executeStep()
bool mbDone{false}; //!< true when the last executeStep() had no more row to fetch bool mbDone{false}; //!< true when the last executeStep() had no more row to fetch
/// Map of columns index by name (mutable so getColumnIndex can be const) /// Map of columns index by name (mutable so getColumnIndex can be const)
mutable std::map<std::string, int> mColumnNames{}; mutable std::map<std::string, int> mColumnNames{};
}; };

View File

@ -87,8 +87,8 @@ public:
void commit(); void commit();
private: private:
Database& mDatabase; ///< Reference to the SQLite Database Connection Database& mDatabase; ///< Reference to the SQLite Database Connection
bool mbCommited; ///< True when commit has been called bool mbCommited{ false }; ///< True when commit has been called
}; };

View File

@ -24,10 +24,10 @@ Backup::Backup(Database& aDestDatabase,
Database& aSrcDatabase, Database& aSrcDatabase,
const char* apSrcDatabaseName) const char* apSrcDatabaseName)
{ {
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(), mpSQLiteBackup.reset(sqlite3_backup_init(aDestDatabase.getHandle(),
apDestDatabaseName, apDestDatabaseName,
aSrcDatabase.getHandle(), aSrcDatabase.getHandle(),
apSrcDatabaseName); apSrcDatabaseName));
if (nullptr == mpSQLiteBackup) if (nullptr == mpSQLiteBackup)
{ {
// If an error occurs, the error code and message are attached to the destination database connection. // If an error occurs, the error code and message are attached to the destination database connection.
@ -48,19 +48,10 @@ Backup::Backup(Database &aDestDatabase, Database &aSrcDatabase) :
{ {
} }
// Release resource for SQLite database backup
Backup::~Backup()
{
if (mpSQLiteBackup)
{
sqlite3_backup_finish(mpSQLiteBackup);
}
}
// Execute backup step with a given number of source pages to be copied // Execute backup step with a given number of source pages to be copied
int Backup::executeStep(const int aNumPage /* = -1 */) int Backup::executeStep(const int aNumPage /* = -1 */)
{ {
const int res = sqlite3_backup_step(mpSQLiteBackup, aNumPage); const int res = sqlite3_backup_step(mpSQLiteBackup.get(), 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); throw SQLite::Exception(sqlite3_errstr(res), res);
@ -69,15 +60,24 @@ int Backup::executeStep(const int aNumPage /* = -1 */)
} }
// Get the number of remaining source pages to be copied in this backup process // Get the number of remaining source pages to be copied in this backup process
int Backup::getRemainingPageCount() int Backup::getRemainingPageCount() const
{ {
return sqlite3_backup_remaining(mpSQLiteBackup); return sqlite3_backup_remaining(mpSQLiteBackup.get());
} }
// Get the number of total source pages to be copied in this backup process // Get the number of total source pages to be copied in this backup process
int Backup::getTotalPageCount() int Backup::getTotalPageCount() const
{ {
return sqlite3_backup_pagecount(mpSQLiteBackup); return sqlite3_backup_pagecount(mpSQLiteBackup.get());
}
// Release resource for SQLite database backup
void SQLite::Backup::Deleter::operator()(sqlite3_backup* apBackup)
{
if (apBackup)
{
sqlite3_backup_finish(apBackup);
}
} }
} // namespace SQLite } // namespace SQLite

View File

@ -78,7 +78,7 @@ double Column::getDouble() const noexcept
const char* Column::getText(const char* apDefaultValue /* = "" */) const noexcept const char* Column::getText(const char* apDefaultValue /* = "" */) const noexcept
{ {
auto pText = reinterpret_cast<const char*>(sqlite3_column_text(mStmtPtr.get(), mIndex)); auto pText = reinterpret_cast<const char*>(sqlite3_column_text(mStmtPtr.get(), mIndex));
return (pText?pText:apDefaultValue); return (pText ? pText : apDefaultValue);
} }
// Return a pointer to the blob value (*not* NULL terminated) of the column specified by its index starting at 0 // Return a pointer to the blob value (*not* NULL terminated) of the column specified by its index starting at 0

View File

@ -27,6 +27,7 @@
namespace SQLite namespace SQLite
{ {
const int OK = SQLITE_OK;
const int OPEN_READONLY = SQLITE_OPEN_READONLY; const int OPEN_READONLY = SQLITE_OPEN_READONLY;
const int OPEN_READWRITE = SQLITE_OPEN_READWRITE; const int OPEN_READWRITE = SQLITE_OPEN_READWRITE;
const int OPEN_CREATE = SQLITE_OPEN_CREATE; const int OPEN_CREATE = SQLITE_OPEN_CREATE;
@ -42,10 +43,8 @@ const int OPEN_NOFOLLOW = SQLITE_OPEN_NOFOLLOW;
const int OPEN_NOFOLLOW = 0; const int OPEN_NOFOLLOW = 0;
#endif #endif
const int OK = SQLITE_OK; const char* const VERSION = SQLITE_VERSION;
const int VERSION_NUMBER = SQLITE_VERSION_NUMBER;
const char* VERSION = SQLITE_VERSION;
const int VERSION_NUMBER = SQLITE_VERSION_NUMBER;
// Return SQLite version string using runtime call to the compiled library // Return SQLite version string using runtime call to the compiled library
const char* getLibVersion() noexcept const char* getLibVersion() noexcept
@ -142,7 +141,7 @@ Column Database::execAndGet(const char* apQuery)
} }
// Shortcut to test if a table exists. // Shortcut to test if a table exists.
bool Database::tableExists(const char* apTableName) bool Database::tableExists(const char* apTableName) const
{ {
Statement query(*this, "SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?"); Statement query(*this, "SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?");
query.bind(1, apTableName); query.bind(1, apTableName);
@ -439,8 +438,8 @@ void Database::backup(const char* apFilename, BackupType aType)
Database otherDatabase(apFilename, SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); Database otherDatabase(apFilename, SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
// For a 'Save' operation, data is copied from the current Database to the other. A 'Load' is the reverse. // For a 'Save' operation, data is copied from the current Database to the other. A 'Load' is the reverse.
Database& src = (aType == Save ? *this : otherDatabase); Database& src = (aType == BackupType::Save ? *this : otherDatabase);
Database& dest = (aType == Save ? otherDatabase : *this); Database& dest = (aType == BackupType::Save ? otherDatabase : *this);
// Set up the backup procedure to copy between the "main" databases of each connection // Set up the backup procedure to copy between the "main" databases of each connection
Backup bkp(dest, src); Backup bkp(dest, src);

View File

@ -18,8 +18,8 @@
namespace SQLite { namespace SQLite {
// Begins the SQLite savepoint // Begins the SQLite savepoint
Savepoint::Savepoint(Database& aDatabase, std::string aName) Savepoint::Savepoint(Database& aDatabase, const std::string& aName)
: mDatabase(aDatabase), msName(aName), mbReleased(false) { : mDatabase(aDatabase), msName(aName) {
// workaround because you cannot bind to SAVEPOINT // workaround because you cannot bind to SAVEPOINT
// escape name for use in query // escape name for use in query
Statement stmt(mDatabase, "SELECT quote(?)"); Statement stmt(mDatabase, "SELECT quote(?)");

View File

@ -21,8 +21,7 @@ namespace SQLite
// Begins the SQLite transaction // Begins the SQLite transaction
Transaction::Transaction(Database& aDatabase, TransactionBehavior behavior) : Transaction::Transaction(Database& aDatabase, TransactionBehavior behavior) :
mDatabase(aDatabase), mDatabase(aDatabase)
mbCommited(false)
{ {
const char *stmt; const char *stmt;
switch (behavior) { switch (behavior) {
@ -43,8 +42,7 @@ Transaction::Transaction(Database& aDatabase, TransactionBehavior behavior) :
// Begins the SQLite transaction // Begins the SQLite transaction
Transaction::Transaction(Database &aDatabase) : Transaction::Transaction(Database &aDatabase) :
mDatabase(aDatabase), mDatabase(aDatabase)
mbCommited(false)
{ {
mDatabase.exec("BEGIN"); mDatabase.exec("BEGIN");
} }