14#if SQLITE_THREADSAFE != 1
15#error "The project must be built for sqlite multithreading! Set the SQLITE_THREADSAFE=1"
19 namespace fs = std::filesystem;
56 throw sqlite_exception(
"Database connection already exists and no configuration update required.");
68 config_locker.unlock();
83 throw sqlite_exception(
"An unspecified error occurred in the database operation.");
107 while (
m_future.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout) {
108 std::this_thread::sleep_for(std::chrono::milliseconds(1));
114 }
catch(
const std::exception &e) {
147 template<
typename Func>
157 }
catch(
const std::exception &e) {
198 std::exception_ptr ex,
199 const std::vector<SqliteStmt*>& stmts,
200 const std::string& message =
"Unknown error occurred.")
const {
202 for (
auto* stmt : stmts) {
204 stmt->clear_bindings();
207 std::rethrow_exception(ex);
211 }
catch (
const std::exception& e) {
236 fs::path file_path(config.
db_path);
237 fs::path parent_dir = file_path.parent_path();
238 if (parent_dir.empty())
return;
239 if (!fs::exists(parent_dir)) {
240 if (!fs::create_directories(parent_dir)) {
241 throw sqlite_exception(
"Failed to create directories for path: " + parent_dir.string());
251 flags |= config.
read_only ? SQLITE_OPEN_READONLY : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
252 flags |= config.
use_uri ? SQLITE_OPEN_URI : 0;
253 flags |= config.
in_memory ? SQLITE_OPEN_MEMORY : 0;
254 flags |= SQLITE_OPEN_FULLMUTEX;
256 const char* db_name = config.
in_memory ?
":memory:" : config.
db_path.c_str();
257 if ((err = sqlite3_open_v2(db_name, &
m_sqlite_db, flags,
nullptr)) != SQLITE_OK) {
258 std::string error_message =
"Cannot open database: ";
260 error_message +=
" (Error code: ";
261 error_message += std::to_string(err);
262 error_message +=
")";
291 m_future = std::async(std::launch::async,
Contains the declaration of Config class for SQLite database configuration.
Declaration of the SqliteStmt class for managing SQLite prepared statements.
Utility functions for working with SQLite in sqlite_containers.
Base class for SQLite database management.
void connect()
Connects to the database using the current configuration. Initializes a connection to the database by...
std::shared_future< void > m_future
void begin(const TransactionMode &mode=TransactionMode::DEFERRED)
Begins a database transaction.
Config get_config() const
Gets the current configuration of the database.
void commit()
Commits the current transaction.
void db_init(const Config &config)
Initializes the database with the given configuration. Sets database parameters such as busy timeout,...
virtual void db_create_table(const Config &config)=0
Creates tables in the database. Must be implemented in derived classes.
std::atomic< bool > m_config_update
virtual void on_db_close()
Called before the database is closed. Can be overridden in derived classes.
std::mutex m_config_mutex
virtual void process()
Processes asynchronous database requests (can be overridden).
std::array< SqliteStmt, 3 > m_stmt_begin
void db_rollback()
Rolls back the current transaction.
void db_open(const Config &config)
Opens the database with the specified configuration.
virtual void on_db_open()
Called after the database is opened. Can be overridden in derived classes.
void db_commit()
Commits the current transaction.
void disconnect()
Disconnects from the database.
void connect(const Config &config)
Connects to the database with the given configuration.
BaseDB()=default
Default constructor.
void execute_in_transaction(Func operation, const TransactionMode &mode)
Executes an operation inside a transaction.
void db_begin(const TransactionMode &mode=TransactionMode::DEFERRED)
Begins a transaction with the given mode.
void rollback()
Rolls back the current transaction.
void set_config(const Config &config)
Sets the configuration for the database.
void db_create_directories(const Config &config)
Creates necessary directories for the database. This method checks if the parent directory of the dat...
virtual ~BaseDB()
Destructor. Disconnects from the database if connected.
std::mutex m_sqlite_mutex
SqliteStmt m_stmt_rollback
void db_handle_exception(std::exception_ptr ex, const std::vector< SqliteStmt * > &stmts, const std::string &message="Unknown error occurred.") const
Handles an exception by resetting and clearing bindings of prepared SQL statements.
Configuration class for SQLite database settings.
int wal_autocheckpoint
WAL auto-checkpoint threshold.
std::string db_path
Path to the SQLite database file.
int analysis_limit
Maximum number of rows to analyze.
AutoVacuumMode auto_vacuum_mode
SQLite auto-vacuum mode.
JournalMode journal_mode
SQLite journal mode.
bool read_only
Whether the database is in read-only mode.
int user_version
User-defined version number for the database schema.
SynchronousMode synchronous
SQLite synchronous mode.
bool use_uri
Whether to use URI for opening the database.
bool use_async
Whether to use asynchronous write.
bool in_memory
Whether the database should be in-memory.
LockingMode locking_mode
SQLite locking mode.
int busy_timeout
Timeout in milliseconds for busy handler.
int page_size
SQLite page size.
int cache_size
SQLite cache size (in pages).
Class for managing SQLite prepared statements.
void execute(sqlite3 *sqlite_db)
Executes the prepared statement.
void init(sqlite3 *sqlite_db, const char *query)
Initializes the statement.
Exception class for SQLite errors.
std::string to_string(const JournalMode &mode)
Converts JournalMode enum to string representation.
void execute(sqlite3_stmt *stmt)
Executes a SQLite statement.
TransactionMode
Defines SQLite transaction modes.
@ DEFERRED
Waits to lock the database until a write operation is requested.