mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 17:47:22 +00:00
Persist generated users to SQLite and code cleanup
This commit is contained in:
@@ -33,7 +33,7 @@ class MockGenerator final : public DataGenerator {
|
||||
*
|
||||
* @param city Enriched city the user is associated with.
|
||||
* @param persona Persona archetype.
|
||||
* @param name Sampled first/last name. Unused for mock generation.
|
||||
* @param name Sampled first/last name, copied directly into the result.
|
||||
* @return Generated user result.
|
||||
*/
|
||||
UserResult GenerateUser(const EnrichedCity& city, const UserPersona& persona,
|
||||
|
||||
@@ -119,7 +119,7 @@ struct UserPersona {
|
||||
* @brief LLM sampling parameters.
|
||||
*/
|
||||
struct SamplingOptions {
|
||||
/// @brief LLM sampling temperature (0.0 to 1.0, higher = more random).
|
||||
/// @brief LLM sampling temperature (higher = more random).
|
||||
float temperature = 1.0F;
|
||||
|
||||
/// @brief LLM nucleus sampling top-p parameter.
|
||||
|
||||
@@ -35,6 +35,13 @@ class IExportService {
|
||||
*/
|
||||
virtual uint64_t ProcessRecord(const GeneratedBrewery& brewery) = 0;
|
||||
|
||||
/**
|
||||
* @brief Persists one generated user record.
|
||||
*
|
||||
* @param user Generated user payload to store.
|
||||
*/
|
||||
virtual uint64_t ProcessRecord(const GeneratedUser& user) = 0;
|
||||
|
||||
/// @brief Finalizes the export destination.
|
||||
virtual void Finalize() = 0;
|
||||
};
|
||||
|
||||
@@ -31,6 +31,7 @@ class SqliteExportService final : public IExportService {
|
||||
|
||||
void Initialize() override;
|
||||
uint64_t ProcessRecord(const GeneratedBrewery& brewery) override;
|
||||
uint64_t ProcessRecord(const GeneratedUser& 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_;
|
||||
};
|
||||
|
||||
@@ -50,6 +50,27 @@ 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,
|
||||
password 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,6 +94,21 @@ INSERT INTO breweries (
|
||||
) VALUES (?, ?, ?, ?, ?);
|
||||
)sql";
|
||||
|
||||
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,
|
||||
password
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
)sql";
|
||||
|
||||
inline constexpr int kLocationCityBindIndex = 1;
|
||||
inline constexpr int kLocationStateProvinceBindIndex = 2;
|
||||
inline constexpr int kLocationIso31662BindIndex = 3;
|
||||
@@ -88,6 +124,17 @@ inline constexpr int kBreweryEnglishDescriptionBindIndex = 3;
|
||||
inline constexpr int kBreweryLocalNameBindIndex = 4;
|
||||
inline constexpr int kBreweryLocalDescriptionBindIndex = 5;
|
||||
|
||||
inline constexpr int kUserLocationIdBindIndex = 1;
|
||||
inline constexpr int kUserFirstNameBindIndex = 2;
|
||||
inline constexpr int kUserLastNameBindIndex = 3;
|
||||
inline constexpr int kUserGenderBindIndex = 4;
|
||||
inline constexpr int kUserUsernameBindIndex = 5;
|
||||
inline constexpr int kUserBioBindIndex = 6;
|
||||
inline constexpr int kUserActivityWeightBindIndex = 7;
|
||||
inline constexpr int kUserEmailBindIndex = 8;
|
||||
inline constexpr int kUserDateOfBirthBindIndex = 9;
|
||||
inline constexpr int kUserPasswordBindIndex = 10;
|
||||
|
||||
SqliteStatementHandle PrepareStatement(const SqliteDatabaseHandle& db_handle,
|
||||
std::string_view sql,
|
||||
const char* action);
|
||||
|
||||
@@ -35,6 +35,7 @@ enum class LogLevel {
|
||||
*/
|
||||
enum class PipelinePhase {
|
||||
Startup, ///< Initialization and validation.
|
||||
Enrichment, ///< Location/context enrichment (e.g. Wikipedia lookups).
|
||||
UserGeneration, ///< User profile generation.
|
||||
BreweryAndBeerGeneration, ///< Brewery and beer data generation.
|
||||
CheckinGeneration, ///< Checkin (visit) record generation.
|
||||
|
||||
Reference in New Issue
Block a user