mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-04-05 18:09:04 +00:00
103 lines
3.7 KiB
C++
103 lines
3.7 KiB
C++
#pragma once
|
|
|
|
#include <mutex>
|
|
#include <sqlite3.h>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
/// @struct Country
|
|
/// @brief Represents a country with geographic identifiers
|
|
struct Country {
|
|
int id;
|
|
std::string name;
|
|
std::string iso2; ///< 2-letter ISO code (e.g., "US", "CA")
|
|
std::string iso3; ///< 3-letter ISO code (e.g., "USA", "CAN")
|
|
};
|
|
|
|
/// @struct State
|
|
/// @brief Represents a state or province with geographic identifiers
|
|
struct State {
|
|
int id;
|
|
std::string name;
|
|
std::string iso2; ///< 2-letter state code (e.g., "CA", "ON")
|
|
int countryId;
|
|
};
|
|
|
|
/**
|
|
* @class SqliteDatabase
|
|
* @brief Thread-safe in-memory SQLite database wrapper for geographic data
|
|
*
|
|
* Manages a local in-memory SQLite database with countries, states, and cities.
|
|
* All write operations are serialized via mutex to enable safe concurrent
|
|
* access from multiple threads. Uses INSERT OR IGNORE for idempotent
|
|
* operations.
|
|
*
|
|
* Schema Relationships:
|
|
* countries (id, name, iso2, iso3)
|
|
* ↓ (one-to-many)
|
|
* states (id, country_id, name, iso2)
|
|
* ↓ (one-to-many)
|
|
* cities (id, state_id, country_id, name, latitude, longitude)
|
|
*/
|
|
class SqliteDatabase {
|
|
private:
|
|
sqlite3 *db = nullptr; ///< SQLite database connection handle
|
|
std::mutex dbMutex; ///< Protects all database operations from race conditions
|
|
|
|
/// @brief Creates the schema with three related tables and foreign keys
|
|
void InitializeSchema();
|
|
|
|
public:
|
|
/// @brief Destructor: safely closes the database connection
|
|
~SqliteDatabase();
|
|
|
|
/// @brief Opens an in-memory SQLite database and initializes the schema
|
|
void Initialize();
|
|
|
|
/// @brief Inserts a country record
|
|
/// @param id Unique country identifier
|
|
/// @param name Country name
|
|
/// @param iso2 2-letter ISO country code
|
|
/// @param iso3 3-letter ISO country code
|
|
/// @note Thread-safe: uses mutex lock. Idempotent: INSERT OR IGNORE prevents
|
|
/// duplicates
|
|
void InsertCountry(int id, const std::string &name, const std::string &iso2,
|
|
const std::string &iso3);
|
|
|
|
/// @brief Inserts a state/province record
|
|
/// @param id Unique state identifier
|
|
/// @param countryId Foreign key reference to parent country
|
|
/// @param name State/province name
|
|
/// @param iso2 2-letter state code (e.g., "CA", "ON")
|
|
/// @note Thread-safe and idempotent via mutex and INSERT OR IGNORE
|
|
void InsertState(int id, int countryId, const std::string &name,
|
|
const std::string &iso2);
|
|
|
|
/// @brief Inserts a city record with geographic coordinates
|
|
/// @param id Unique city identifier
|
|
/// @param stateId Foreign key reference to parent state
|
|
/// @param countryId Foreign key reference to parent country
|
|
/// @param name City name
|
|
/// @param latitude Geographic latitude coordinate (WGS84)
|
|
/// @param longitude Geographic longitude coordinate (WGS84)
|
|
/// @note Thread-safe and idempotent. Called by multithreaded JSON loader.
|
|
void InsertCity(int id, int stateId, int countryId, const std::string &name,
|
|
double latitude, double longitude);
|
|
|
|
/// @brief Queries all cities from the database
|
|
/// @return Vector of (city_id, city_name) pairs sorted alphabetically
|
|
std::vector<std::pair<int, std::string>> QueryCities();
|
|
|
|
/// @brief Queries all countries from the database with ISO codes
|
|
/// @param limit Maximum number of records to return (0 = all)
|
|
/// @return Vector of Country structs (includes id, name, iso2, iso3) sorted
|
|
/// alphabetically
|
|
std::vector<Country> QueryCountries(int limit = 0);
|
|
|
|
/// @brief Queries all states from the database with ISO codes
|
|
/// @param limit Maximum number of records to return (0 = all)
|
|
/// @return Vector of State structs (includes id, name, iso2, countryId)
|
|
/// sorted alphabetically
|
|
std::vector<State> QueryStates(int limit = 0);
|
|
};
|