#pragma once #include #include #include struct sqlite3; namespace db { struct User { int64_t pid = 0; std::string username; std::string password_hash; std::string salt; }; class Database { public: explicit Database(const std::string& path); ~Database(); Database(const Database&) = delete; Database& operator=(const Database&) = delete; bool open_ok() const { return db_ != nullptr; } const std::string& last_error() const { return err_; } // returns pid on success std::optional create_user(const std::string& username, const std::string& password_hash, const std::string& salt); std::optional find_user_by_name(const std::string& username); std::optional find_user_by_pid(int64_t pid); bool store_token(const std::string& token, int64_t pid, int64_t created_at, int64_t expires_at); std::optional pid_for_token(const std::string& token); void purge_expired_tokens(int64_t now); private: bool exec(const char* sql); sqlite3* db_ = nullptr; std::string err_; }; } // namespace db