18#if SQLITE_THREADSAFE != 1
19#error "The project must be built for sqlite multithreading! Set the SQLITE_THREADSAFE=1"
23 namespace fs = std::filesystem;
60 throw sqlite_exception(
"Database connection already exists and no configuration update required.");
72 config_locker.unlock();
87 throw sqlite_exception(
"An unspecified error occurred in the database operation.");
111 while (
m_future.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout) {
112 std::this_thread::sleep_for(std::chrono::milliseconds(1));
118 }
catch(
const std::exception &e) {
151 template<
typename Func>
161 }
catch(
const std::exception &e) {
202 std::exception_ptr ex,
203 const std::vector<SqliteStmt*>& stmts,
204 const std::string& message =
"Unknown error occurred.")
const {
206 for (
auto* stmt : stmts) {
208 stmt->clear_bindings();
211 std::rethrow_exception(ex);
215 }
catch (
const std::exception& e) {
242 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
243 std::wstring wide_path = converter.from_bytes(config.
db_path);
244 std::filesystem::path file_path(wide_path);
246 std::filesystem::path file_path(config.
db_path);
248 fs::path parent_dir = file_path.parent_path();
249 if (!std::filesystem::exists(parent_dir)) {
251 if (!std::filesystem::create_directories(parent_dir, ec)) {
252 throw std::runtime_error(
"Failed to create directories for path: " + config.
db_path);
262 flags |= config.
read_only ? SQLITE_OPEN_READONLY : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
263 flags |= config.
use_uri ? SQLITE_OPEN_URI : 0;
264 flags |= config.
in_memory ? SQLITE_OPEN_MEMORY : 0;
265 flags |= SQLITE_OPEN_FULLMUTEX;
267 const char* db_name = config.
in_memory ?
":memory:" : config.
db_path.c_str();
268 if ((err = sqlite3_open_v2(db_name, &
m_sqlite_db, flags,
nullptr)) != SQLITE_OK) {
269 std::string error_message =
"Cannot open database: ";
271 error_message +=
" (Error code: ";
272 error_message += std::to_string(err);
273 error_message +=
")";
302 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.
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.
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.