#ifndef BIERGARTEN_PIPELINE_INCLUDES_SERVICES_DATABASE_SQLITE_STATEMENT_HELPERS_H_ #define BIERGARTEN_PIPELINE_INCLUDES_SERVICES_DATABASE_SQLITE_STATEMENT_HELPERS_H_ /** * @file services/sqlite_statement_helpers.h * @brief Declarations for statement-level SQLite helper functions and * constants. */ #include #include #include #include #include "services/database/sqlite_handle_types.h" namespace sqlite_export_service_internal { inline constexpr std::string_view kCreateCitiesTableSql = R"sql( CREATE TABLE IF NOT EXISTS cities ( id INTEGER PRIMARY KEY AUTOINCREMENT, city TEXT NOT NULL, state_province TEXT NOT NULL, iso3166_2 TEXT NOT NULL, country TEXT NOT NULL, iso3166_1 TEXT NOT NULL, local_languages_json TEXT NOT NULL, latitude REAL NOT NULL, longitude REAL NOT NULL, UNIQUE(city, state_province, iso3166_2, country, latitude, longitude) ); )sql"; inline constexpr std::string_view kCreateBreweriesTableSql = R"sql( CREATE TABLE IF NOT EXISTS breweries ( id INTEGER PRIMARY KEY AUTOINCREMENT, city_id INTEGER NOT NULL, name_en TEXT NOT NULL, description_en TEXT NOT NULL, name_local TEXT NOT NULL, description_local TEXT NOT NULL, postal_code TEXT NOT NULL, FOREIGN KEY(city_id) REFERENCES cities(id) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_breweries_city_id ON breweries(city_id); )sql"; inline constexpr std::string_view kCreateUsersTableSql = R"sql( CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, city_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(city_id) REFERENCES cities(id) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_users_city_id ON users(city_id); )sql"; inline constexpr std::string_view kInsertCitySql = R"sql( INSERT INTO cities ( city, state_province, iso3166_2, country, iso3166_1, local_languages_json, latitude, longitude ) VALUES (?, ?, ?, ?, ?, ?, ?, ?); )sql"; inline constexpr std::string_view kInsertBrewerySql = R"sql( INSERT INTO breweries ( city_id, name_en, description_en, name_local, description_local, postal_code ) VALUES (?, ?, ?, ?, ?, ?); )sql"; inline constexpr std::string_view kInsertUserSql = R"sql( INSERT INTO users ( city_id, first_name, last_name, gender, username, bio, activity_weight, email, date_of_birth ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); )sql"; // sqlite3_bind_*() parameter indices are 1-based, matching the "?" // placeholder order in the SQL above. enum CityBindIndex { kCityNameBindIndex = 1, kCityStateProvinceBindIndex, kCityIso31662BindIndex, kCityCountryBindIndex, kCityIso31661BindIndex, kCityLanguagesBindIndex, kCityLatitudeBindIndex, kCityLongitudeBindIndex, }; enum BreweryBindIndex { kBreweryCityIdBindIndex = 1, kBreweryEnglishNameBindIndex, kBreweryEnglishDescriptionBindIndex, kBreweryLocalNameBindIndex, kBreweryLocalDescriptionBindIndex, kBreweryPostalCodeBindIndex, }; enum UserBindIndex { kUserCityIdBindIndex = 1, kUserFirstNameBindIndex, kUserLastNameBindIndex, kUserGenderBindIndex, kUserUsernameBindIndex, kUserBioBindIndex, kUserActivityWeightBindIndex, kUserEmailBindIndex, kUserDateOfBirthBindIndex, }; SqliteStatementHandle PrepareStatement(const SqliteDatabaseHandle& db_handle, std::string_view sql, const char* action); void ResetStatement(SqliteStatementHandle& statement); void Bind(const SqliteStatementHandle& statement, const BoundParam& param); void Bind(const SqliteStatementHandle& statement, const BoundParam& param); void Bind(const SqliteStatementHandle& statement, const BoundParam& param); void StepStatement(const SqliteDatabaseHandle& db_handle, const SqliteStatementHandle& statement, std::string_view action); sqlite3_int64 LastInsertRowId(const SqliteDatabaseHandle& db_handle); std::string SerializeVector(const std::vector& str_vec); } // namespace sqlite_export_service_internal #endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_DATABASE_SQLITE_STATEMENT_HELPERS_H_