mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 17:47:22 +00:00
Pipeline: Add LLM and mocked user generation to the pipeline (#230)
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
class IExportService {
|
||||
public:
|
||||
IExportService() = default;
|
||||
|
||||
/// @brief Virtual destructor for polymorphic cleanup.
|
||||
virtual ~IExportService() = default;
|
||||
|
||||
IExportService(const IExportService&) = delete;
|
||||
@@ -25,7 +23,9 @@ class IExportService {
|
||||
IExportService(IExportService&&) = delete;
|
||||
IExportService& operator=(IExportService&&) = delete;
|
||||
|
||||
/// @brief Prepares the export destination for a new run.
|
||||
/**
|
||||
* @brief Prepares the export destination for a new run.
|
||||
*/
|
||||
virtual void Initialize() = 0;
|
||||
|
||||
/**
|
||||
@@ -33,9 +33,18 @@ class IExportService {
|
||||
*
|
||||
* @param brewery Generated brewery payload to store.
|
||||
*/
|
||||
virtual uint64_t ProcessRecord(const GeneratedBrewery& brewery) = 0;
|
||||
virtual uint64_t ProcessRecord(const BreweryRecord& brewery) = 0;
|
||||
|
||||
/// @brief Finalizes the export destination.
|
||||
/**
|
||||
* @brief Persists one generated user record.
|
||||
*
|
||||
* @param user Generated user payload to store.
|
||||
*/
|
||||
virtual uint64_t ProcessRecord(const UserRecord& user) = 0;
|
||||
|
||||
/**
|
||||
* @brief Finalizes the export destination.
|
||||
*/
|
||||
virtual void Finalize() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "sqlite_handle_types.h"
|
||||
#include "services/database/sqlite_handle_types.h"
|
||||
|
||||
namespace sqlite_export_service_internal {
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "data_model/models.h"
|
||||
#include "../datetime/date_time_provider.h"
|
||||
#include "export_service.h"
|
||||
#include "sqlite_export_service_helpers.h"
|
||||
#include "services/database/export_service.h"
|
||||
#include "services/database/sqlite_export_service_helpers.h"
|
||||
#include "services/datetime/date_time_provider.h"
|
||||
|
||||
/**
|
||||
* @brief Persists generated brewery records into a fresh SQLite database.
|
||||
@@ -30,7 +30,8 @@ class SqliteExportService final : public IExportService {
|
||||
SqliteExportService& operator=(SqliteExportService&&) = delete;
|
||||
|
||||
void Initialize() override;
|
||||
uint64_t ProcessRecord(const GeneratedBrewery& brewery) override;
|
||||
uint64_t ProcessRecord(const BreweryRecord& brewery) override;
|
||||
uint64_t ProcessRecord(const UserRecord& user) override;
|
||||
void Finalize() override;
|
||||
|
||||
private:
|
||||
@@ -46,6 +47,15 @@ class SqliteExportService final : public IExportService {
|
||||
[[nodiscard]] std::filesystem::path BuildDatabasePath() const;
|
||||
[[nodiscard]] static std::string BuildLocationKey(const Location& location);
|
||||
|
||||
/**
|
||||
* @brief Returns the row id for @p location, inserting it first if it has
|
||||
* not already been seen during this run.
|
||||
*
|
||||
* Shared by both ProcessRecord() overloads so breweries and users
|
||||
* referencing the same location resolve to the same row.
|
||||
*/
|
||||
[[nodiscard]] sqlite3_int64 ResolveLocationId(const Location& location);
|
||||
|
||||
std::unique_ptr<IDateTimeProvider> date_time_provider_;
|
||||
std::filesystem::path output_path_;
|
||||
std::string run_timestamp_utc_;
|
||||
@@ -53,6 +63,7 @@ class SqliteExportService final : public IExportService {
|
||||
SqliteDatabaseHandle db_handle_;
|
||||
SqliteStatementHandle insert_location_stmt_;
|
||||
SqliteStatementHandle insert_brewery_stmt_;
|
||||
SqliteStatementHandle insert_user_stmt_;
|
||||
bool transaction_open_ = false;
|
||||
std::unordered_map<std::string, sqlite3_int64> location_cache_;
|
||||
};
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
/* Umbrella header for backward compatibility. */
|
||||
|
||||
#include "sqlite_connection_helpers.h"
|
||||
#include "sqlite_handle_types.h"
|
||||
#include "sqlite_statement_helpers.h"
|
||||
#include "services/database/sqlite_connection_helpers.h"
|
||||
#include "services/database/sqlite_handle_types.h"
|
||||
#include "services/database/sqlite_statement_helpers.h"
|
||||
|
||||
#endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_DATABASE_SQLITE_EXPORT_SERVICE_HELPERS_H_
|
||||
|
||||
@@ -24,8 +24,10 @@ using SqliteDatabaseHandle = std::unique_ptr<sqlite3, SqliteDatabaseDeleter>;
|
||||
using SqliteStatementHandle =
|
||||
std::unique_ptr<sqlite3_stmt, SqliteStatementDeleter>;
|
||||
|
||||
// Represents a parameter that is bound to a prepared SQLite statement.
|
||||
// N.B. indices are 1 based.
|
||||
template <typename T>
|
||||
struct BindParam {
|
||||
struct BoundParam {
|
||||
int index;
|
||||
T value;
|
||||
std::string_view action;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "sqlite_handle_types.h"
|
||||
#include "services/database/sqlite_handle_types.h"
|
||||
|
||||
namespace sqlite_export_service_internal {
|
||||
|
||||
@@ -50,6 +50,26 @@ CREATE INDEX IF NOT EXISTS idx_breweries_location_id ON breweries(location_id);
|
||||
|
||||
)sql";
|
||||
|
||||
inline constexpr std::string_view kCreateUsersTableSql = R"sql(
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
location_id INTEGER NOT NULL,
|
||||
first_name TEXT NOT NULL,
|
||||
last_name TEXT NOT NULL,
|
||||
gender TEXT NOT NULL,
|
||||
username TEXT NOT NULL,
|
||||
bio TEXT NOT NULL,
|
||||
activity_weight REAL NOT NULL,
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
date_of_birth TEXT NOT NULL,
|
||||
FOREIGN KEY(location_id) REFERENCES locations(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_users_location_id ON users(location_id);
|
||||
|
||||
)sql";
|
||||
|
||||
inline constexpr std::string_view kInsertLocationSql = R"sql(
|
||||
INSERT INTO locations (
|
||||
city,
|
||||
@@ -73,20 +93,52 @@ INSERT INTO breweries (
|
||||
) VALUES (?, ?, ?, ?, ?);
|
||||
)sql";
|
||||
|
||||
inline constexpr int kLocationCityBindIndex = 1;
|
||||
inline constexpr int kLocationStateProvinceBindIndex = 2;
|
||||
inline constexpr int kLocationIso31662BindIndex = 3;
|
||||
inline constexpr int kLocationCountryBindIndex = 4;
|
||||
inline constexpr int kLocationIso31661BindIndex = 5;
|
||||
inline constexpr int kLocationLanguagesBindIndex = 6;
|
||||
inline constexpr int kLocationLatitudeBindIndex = 7;
|
||||
inline constexpr int kLocationLongitudeBindIndex = 8;
|
||||
inline constexpr std::string_view kInsertUserSql = R"sql(
|
||||
INSERT INTO users (
|
||||
location_id,
|
||||
first_name,
|
||||
last_name,
|
||||
gender,
|
||||
username,
|
||||
bio,
|
||||
activity_weight,
|
||||
email,
|
||||
date_of_birth
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
)sql";
|
||||
|
||||
inline constexpr int kBreweryLocationIdBindIndex = 1;
|
||||
inline constexpr int kBreweryEnglishNameBindIndex = 2;
|
||||
inline constexpr int kBreweryEnglishDescriptionBindIndex = 3;
|
||||
inline constexpr int kBreweryLocalNameBindIndex = 4;
|
||||
inline constexpr int kBreweryLocalDescriptionBindIndex = 5;
|
||||
// sqlite3_bind_*() parameter indices are 1-based, matching the "?"
|
||||
// placeholder order in the SQL above.
|
||||
enum LocationBindIndex {
|
||||
kLocationCityBindIndex = 1,
|
||||
kLocationStateProvinceBindIndex,
|
||||
kLocationIso31662BindIndex,
|
||||
kLocationCountryBindIndex,
|
||||
kLocationIso31661BindIndex,
|
||||
kLocationLanguagesBindIndex,
|
||||
kLocationLatitudeBindIndex,
|
||||
kLocationLongitudeBindIndex,
|
||||
};
|
||||
|
||||
enum BreweryBindIndex {
|
||||
kBreweryLocationIdBindIndex = 1,
|
||||
kBreweryEnglishNameBindIndex,
|
||||
kBreweryEnglishDescriptionBindIndex,
|
||||
kBreweryLocalNameBindIndex,
|
||||
kBreweryLocalDescriptionBindIndex,
|
||||
};
|
||||
|
||||
enum UserBindIndex {
|
||||
kUserLocationIdBindIndex = 1,
|
||||
kUserFirstNameBindIndex,
|
||||
kUserLastNameBindIndex,
|
||||
kUserGenderBindIndex,
|
||||
kUserUsernameBindIndex,
|
||||
kUserBioBindIndex,
|
||||
kUserActivityWeightBindIndex,
|
||||
kUserEmailBindIndex,
|
||||
kUserDateOfBirthBindIndex,
|
||||
};
|
||||
|
||||
SqliteStatementHandle PrepareStatement(const SqliteDatabaseHandle& db_handle,
|
||||
std::string_view sql,
|
||||
@@ -95,13 +147,13 @@ SqliteStatementHandle PrepareStatement(const SqliteDatabaseHandle& db_handle,
|
||||
void ResetStatement(SqliteStatementHandle& statement);
|
||||
|
||||
void Bind(const SqliteStatementHandle& statement,
|
||||
const BindParam<std::string_view>& param);
|
||||
const BoundParam<std::string_view>& param);
|
||||
|
||||
void Bind(const SqliteStatementHandle& statement,
|
||||
const BindParam<double>& param);
|
||||
const BoundParam<double>& param);
|
||||
|
||||
void Bind(const SqliteStatementHandle& statement,
|
||||
const BindParam<sqlite3_int64>& param);
|
||||
const BoundParam<sqlite3_int64>& param);
|
||||
|
||||
void StepStatement(const SqliteDatabaseHandle& db_handle,
|
||||
const SqliteStatementHandle& statement,
|
||||
|
||||
Reference in New Issue
Block a user