157 lines
3.2 KiB
C
157 lines
3.2 KiB
C
|
|
#pragma once
|
||
|
|
|
||
|
|
#include "sqlite3.h"
|
||
|
|
#include <qstring.h>
|
||
|
|
#include <stdexcept>
|
||
|
|
|
||
|
|
class SQLiteException : public std::runtime_error
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
explicit SQLiteException(const char* msg)
|
||
|
|
: std::runtime_error(msg)
|
||
|
|
{}
|
||
|
|
};
|
||
|
|
|
||
|
|
class SQLiteConnection;
|
||
|
|
|
||
|
|
class SQLitePreparedStatement
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
SQLitePreparedStatement() = default;
|
||
|
|
SQLitePreparedStatement(const SQLitePreparedStatement &) = delete;
|
||
|
|
SQLitePreparedStatement(SQLitePreparedStatement&& rhs);
|
||
|
|
SQLitePreparedStatement &operator=(SQLitePreparedStatement&& rhs);
|
||
|
|
|
||
|
|
~SQLitePreparedStatement();
|
||
|
|
|
||
|
|
void Open(SQLiteConnection &db, const char *query);
|
||
|
|
void Open(SQLiteConnection &db, const QString &query);
|
||
|
|
|
||
|
|
void Bind(int index, const char *s, int length = 0);
|
||
|
|
void Bind(int index, const QString &s);
|
||
|
|
void Bind(int index, int v);
|
||
|
|
|
||
|
|
const char* ColumnCharPtr(int col);
|
||
|
|
QString ColumnText(int col);
|
||
|
|
int ColumnInteger(int col);
|
||
|
|
|
||
|
|
bool Step();
|
||
|
|
|
||
|
|
void Reset()
|
||
|
|
{
|
||
|
|
sqlite3_reset(pStatement);
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
sqlite3_stmt *pStatement = nullptr;
|
||
|
|
|
||
|
|
void Free()
|
||
|
|
{
|
||
|
|
if (pStatement != nullptr)
|
||
|
|
{
|
||
|
|
sqlite3_finalize(pStatement);
|
||
|
|
pStatement = nullptr;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
class SQLiteTransaction
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
explicit SQLiteTransaction(SQLiteConnection &db);
|
||
|
|
SQLiteTransaction(const SQLiteTransaction&&) = delete;
|
||
|
|
|
||
|
|
~SQLiteTransaction();
|
||
|
|
|
||
|
|
void Commit();
|
||
|
|
void Rollback();
|
||
|
|
private:
|
||
|
|
SQLiteConnection &db;
|
||
|
|
bool inTransaction = false;
|
||
|
|
void UncheckedRollback();
|
||
|
|
};
|
||
|
|
|
||
|
|
class SQLiteConnection
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
SQLiteConnection() = default;
|
||
|
|
SQLiteConnection(const SQLiteConnection&) = delete;
|
||
|
|
|
||
|
|
SQLiteConnection(SQLiteConnection&& rhs);
|
||
|
|
|
||
|
|
SQLiteConnection& operator=(const SQLiteConnection &) = delete;
|
||
|
|
|
||
|
|
SQLiteConnection& operator=(SQLiteConnection && rhs);
|
||
|
|
|
||
|
|
~SQLiteConnection()
|
||
|
|
{
|
||
|
|
if (pDb)
|
||
|
|
{
|
||
|
|
sqlite3_close(pDb);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void Open(const char *filename)
|
||
|
|
{
|
||
|
|
int result = sqlite3_open(filename, &pDb);
|
||
|
|
CheckResult(result);
|
||
|
|
}
|
||
|
|
|
||
|
|
void Open(QString filename)
|
||
|
|
{
|
||
|
|
int result = sqlite3_open16((void*)filename.data(), &pDb);
|
||
|
|
CheckResult(result);
|
||
|
|
}
|
||
|
|
|
||
|
|
void CheckResult(int result)
|
||
|
|
{
|
||
|
|
if (result == SQLITE_OK)
|
||
|
|
return;
|
||
|
|
|
||
|
|
if (pDb == nullptr)
|
||
|
|
{
|
||
|
|
const char * msg = sqlite3_errstr(result);
|
||
|
|
throw SQLiteException(msg);
|
||
|
|
}
|
||
|
|
const char * msg = sqlite3_errmsg(pDb);
|
||
|
|
throw SQLiteException(msg);
|
||
|
|
}
|
||
|
|
|
||
|
|
SQLitePreparedStatement Prepare(const char* query)
|
||
|
|
{
|
||
|
|
SQLitePreparedStatement stmt;
|
||
|
|
stmt.Open(*this, query);
|
||
|
|
return stmt;
|
||
|
|
}
|
||
|
|
|
||
|
|
SQLitePreparedStatement Prepare(const QString &query)
|
||
|
|
{
|
||
|
|
SQLitePreparedStatement stmt;
|
||
|
|
stmt.Open(*this, query);
|
||
|
|
return stmt;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Exec(const char* query)
|
||
|
|
{
|
||
|
|
SQLitePreparedStatement stmt = Prepare(query);
|
||
|
|
stmt.Step();
|
||
|
|
}
|
||
|
|
|
||
|
|
void Exec(QString query)
|
||
|
|
{
|
||
|
|
SQLitePreparedStatement stmt = Prepare(query.toUtf8().constData());
|
||
|
|
stmt.Step();
|
||
|
|
}
|
||
|
|
|
||
|
|
int64_t LastInsertRowId()
|
||
|
|
{
|
||
|
|
return sqlite3_last_insert_rowid(pDb);
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
sqlite3 *pDb = nullptr;
|
||
|
|
|
||
|
|
friend class SQLitePreparedStatement;
|
||
|
|
};
|