export module routemon:database; import std; import :sqlite3; namespace routemon::database { static constexpr std::int64_t expected_database_version = 1; export class connection { sqlite3::connection dbc_; explicit connection(sqlite3::connection dbc) : dbc_{std::move(dbc)} {} friend auto open(std::string const& filename) -> std::shared_ptr; public: // Nothing here yet }; export auto open(std::string const& filename) -> std::shared_ptr { auto dbc = sqlite3::open(filename); try { auto version = std::optional{}; dbc.query("SELECT version FROM migration;").scan_single(version); if (!version) throw std::runtime_error{"failed to fetch database migration version"}; if (version != expected_database_version) { throw std::runtime_error{std::format( "database migration version ({}) does not match expected " "version ({}), consider running migrations", *version, expected_database_version)}; } } catch (std::exception const& e) { throw std::runtime_error{std::format( "failed to query database version: {}", e.what())}; } return std::shared_ptr{new connection{std::move(dbc)}}; } } // namespace routemon::database