225 lines
6.3 KiB
C++
225 lines
6.3 KiB
C++
#ifndef CSQLITEDB_H
|
|
#define CSQLITEDB_H
|
|
|
|
#include "sqlite3.h"
|
|
#include "CSQLiteException.h"
|
|
#include "GdCPP_Exports.h"
|
|
|
|
class GDCPP_API CSQLiteDB
|
|
{
|
|
friend class CSQLiteStatement;
|
|
public:
|
|
/// 构造一个实例,未打开数据库
|
|
CSQLiteDB() noexcept
|
|
: dbErrCode(0)
|
|
, mpSQLite(nullptr)
|
|
{
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Open the provided database UTF-8 filename.
|
|
*
|
|
* @param[in] apFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter)
|
|
* @param[in] aFlags flags for sqlite3_open_v2()
|
|
*
|
|
* 尽量使用后面的openRW()或openRO()
|
|
*/
|
|
int open(const char* apFilename, const int aFlags) noexcept;
|
|
int open(const std::string &apFilename, const int aFlags) noexcept;
|
|
|
|
inline int openRW(const char* apFilename){
|
|
return open(apFilename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
|
|
}
|
|
|
|
inline int openRW(const std::string& apFilename) {
|
|
return open(apFilename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
|
|
}
|
|
|
|
inline int openRW(const std::filesystem::path& apFilename) {
|
|
return open(apFilename.string(), SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
|
|
}
|
|
|
|
inline int openRO(const char* apFilename){
|
|
return open(apFilename, SQLITE_OPEN_READONLY);
|
|
}
|
|
inline int openRO(const std::string& apFilename) {
|
|
return open(apFilename, SQLITE_OPEN_READONLY);
|
|
}
|
|
inline int openRO(const std::filesystem::path& apFilename) {
|
|
return open(apFilename.string(), SQLITE_OPEN_READONLY);
|
|
}
|
|
|
|
int openInRam(const char* apFilename);
|
|
|
|
/**
|
|
* @brief Close the SQLite database connection.
|
|
*
|
|
* All SQLite statements must have been finalized before,
|
|
* so all Statement objects must have been unregistered.
|
|
*
|
|
* @warning assert in case of error
|
|
*/
|
|
virtual int close();
|
|
|
|
|
|
virtual ~CSQLiteDB()
|
|
{
|
|
close();
|
|
}
|
|
|
|
int errcode() {
|
|
return sqlite3_errcode(mpSQLite);
|
|
}
|
|
|
|
const char* errmsg() {
|
|
return sqlite3_errmsg(mpSQLite);
|
|
}
|
|
|
|
/**
|
|
* @brief Set a busy handler that sleeps for a specified amount of time when a table is locked.
|
|
*
|
|
* This is useful in multithreaded program to handle case where a table is locked for writing by a thread.
|
|
* Any other thread cannot access the table and will receive a SQLITE_BUSY error:
|
|
* setting a timeout will wait and retry up to the time specified before returning this SQLITE_BUSY error.
|
|
* Reading the value of timeout for current connection can be done with SQL query "PRAGMA busy_timeout;".
|
|
* Default busy timeout is 0ms.
|
|
*
|
|
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY
|
|
*
|
|
* @throw CSQLiteExceptionin case of error
|
|
*/
|
|
void setBusyTimeout(const int aBusyTimeoutMs);
|
|
|
|
/**
|
|
* @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 Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
|
|
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
|
|
* - 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] apQueries one or multiple UTF-8 encoded, semicolon-separate SQL statements
|
|
*
|
|
* @return number of rows modified by the *last* INSERT, UPDATE or DELETE statement (beware of multiple statements)
|
|
* @warning undefined for CREATE or DROP table: returns the value of a previous INSERT, UPDATE or DELETE statement.
|
|
*
|
|
* @throw CSQLiteExceptionin case of error
|
|
*/
|
|
int exec(const char* apQueries);
|
|
|
|
/**
|
|
* @brief Shortcut to test if a table exists.
|
|
*
|
|
* Table names are case sensitive.
|
|
*
|
|
* @param[in] apTableName an UTF-8 encoded case sensitive Table name
|
|
*
|
|
* @return true if the table exists.
|
|
*
|
|
* @throw CSQLiteException in case of error
|
|
*/
|
|
bool tableExists(const char* apTableName);
|
|
|
|
/**
|
|
* @brief Return raw pointer to SQLite Database Connection Handle.
|
|
*
|
|
* This is often needed to mix this wrapper with other libraries or for advance usage not supported by SQLiteCpp.
|
|
*/
|
|
inline sqlite3* getHandle() const noexcept // nothrow
|
|
{
|
|
return mpSQLite;
|
|
}
|
|
|
|
inline bool isOpened()
|
|
{
|
|
return mpSQLite!=nullptr;
|
|
}
|
|
|
|
int dbErrCode;
|
|
std::string dbErrMsg;
|
|
private:
|
|
/// @{ Database must be non-copyable
|
|
CSQLiteDB(const CSQLiteDB&);
|
|
CSQLiteDB& operator=(const CSQLiteDB&);
|
|
/// @}
|
|
|
|
/**
|
|
* @brief Check if aRet equal SQLITE_OK, else throw a CSQLiteException with the SQLite error message
|
|
*/
|
|
inline void check(const int aRet) const
|
|
{
|
|
if (SQLITE_OK != aRet)
|
|
{
|
|
throw CSQLiteException(mpSQLite, aRet);
|
|
}
|
|
}
|
|
|
|
protected:
|
|
sqlite3* mpSQLite; ///< Pointer to SQLite Database Connection Handle
|
|
std::string mFilename; ///< UTF-8 filename used to open the database
|
|
|
|
public:
|
|
// 获取数据库文件名
|
|
const std::string& getFilename() const
|
|
{
|
|
return mFilename;
|
|
}
|
|
|
|
// 以下与事务相关
|
|
// 标记是否启动了事务。true未启动事务
|
|
bool bInTransaction = false;
|
|
|
|
inline bool startTransaction()
|
|
{
|
|
ASSERT(!bInTransaction);
|
|
ASSERT(isOpened());
|
|
try
|
|
{
|
|
exec("BEGIN TRANSACTION");
|
|
bInTransaction = true;
|
|
return true;
|
|
}
|
|
catch (CSQLiteException&)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
inline bool Rollback()
|
|
{
|
|
ASSERT(bInTransaction);
|
|
ASSERT(isOpened());
|
|
try
|
|
{
|
|
int ret = exec("ROLLBACK");
|
|
bInTransaction = false;
|
|
return true;
|
|
}
|
|
catch (CSQLiteException&)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
inline bool Commit()
|
|
{
|
|
ASSERT(bInTransaction);
|
|
ASSERT(isOpened());
|
|
try
|
|
{
|
|
int ret = exec("COMMIT");
|
|
return true;
|
|
}
|
|
catch (CSQLiteException&)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif // CSQLITEDB_H
|