mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 09:37:23 +00:00
96 lines
3.3 KiB
C++
96 lines
3.3 KiB
C++
/**
|
|
* @file services/sqlite/initialize.cc
|
|
* @brief SqliteExportService::Initialize() implementation.
|
|
*/
|
|
|
|
#include <filesystem>
|
|
#include <format>
|
|
#include <memory>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
|
|
#include "services/database/sqlite_export_service.h"
|
|
#include "services/database/sqlite_export_service_helpers.h"
|
|
|
|
std::filesystem::path SqliteExportService::BuildDatabasePath() const {
|
|
std::filesystem::path base_filename("biergarten_seed_" + run_timestamp_utc_ +
|
|
".sqlite");
|
|
std::filesystem::path candidate = output_path_ / base_filename;
|
|
|
|
for (int suffix = 1; std::filesystem::exists(candidate); ++suffix) {
|
|
candidate = output_path_ / std::filesystem::path(
|
|
std::format("biergarten_seed_{}-{}.sqlite",
|
|
run_timestamp_utc_, suffix));
|
|
}
|
|
|
|
return candidate;
|
|
}
|
|
|
|
void SqliteExportService::InitializeSchema() const {
|
|
sqlite_export_service_internal::ExecSql(
|
|
db_handle_, sqlite_export_service_internal::kCreateLocationsTableSql,
|
|
"Failed to create SQLite locations table");
|
|
sqlite_export_service_internal::ExecSql(
|
|
db_handle_, sqlite_export_service_internal::kCreateBreweriesTableSql,
|
|
"Failed to create SQLite breweries table");
|
|
sqlite_export_service_internal::ExecSql(
|
|
db_handle_, sqlite_export_service_internal::kCreateUsersTableSql,
|
|
"Failed to create SQLite users table");
|
|
}
|
|
|
|
void SqliteExportService::PrepareStatements() {
|
|
insert_location_stmt_ = sqlite_export_service_internal::PrepareStatement(
|
|
db_handle_, sqlite_export_service_internal::kInsertLocationSql,
|
|
"Failed to prepare SQLite location insert statement");
|
|
insert_brewery_stmt_ = sqlite_export_service_internal::PrepareStatement(
|
|
db_handle_, sqlite_export_service_internal::kInsertBrewerySql,
|
|
"Failed to prepare SQLite brewery insert statement");
|
|
insert_user_stmt_ = sqlite_export_service_internal::PrepareStatement(
|
|
db_handle_, sqlite_export_service_internal::kInsertUserSql,
|
|
"Failed to prepare SQLite user insert statement");
|
|
}
|
|
|
|
void SqliteExportService::RollbackAndCloseNoThrow() noexcept {
|
|
if (db_handle_ == nullptr) {
|
|
return;
|
|
}
|
|
|
|
if (transaction_open_) {
|
|
sqlite_export_service_internal::RollbackTransactionNoThrow(db_handle_);
|
|
transaction_open_ = false;
|
|
}
|
|
|
|
insert_user_stmt_.reset();
|
|
insert_brewery_stmt_.reset();
|
|
insert_location_stmt_.reset();
|
|
db_handle_.reset();
|
|
location_cache_.clear();
|
|
}
|
|
|
|
void SqliteExportService::Initialize() {
|
|
if (db_handle_ != nullptr) {
|
|
throw std::runtime_error("SQLite export service is already initialized");
|
|
}
|
|
|
|
run_timestamp_utc_ = date_time_provider_->GetUtcTimestamp();
|
|
database_path_ = BuildDatabasePath();
|
|
std::filesystem::create_directories(database_path_.parent_path());
|
|
|
|
db_handle_ = sqlite_export_service_internal::OpenDatabase(database_path_);
|
|
|
|
try {
|
|
sqlite_export_service_internal::ExecSql(
|
|
db_handle_, "PRAGMA foreign_keys = ON;",
|
|
"Failed to enable SQLite foreign keys");
|
|
InitializeSchema();
|
|
PrepareStatements();
|
|
sqlite_export_service_internal::ExecSql(
|
|
db_handle_, "BEGIN IMMEDIATE TRANSACTION;",
|
|
"Failed to begin SQLite transaction");
|
|
transaction_open_ = true;
|
|
} catch (...) {
|
|
RollbackAndCloseNoThrow();
|
|
throw;
|
|
}
|
|
}
|