#pragma once #include <functional> #include <memory> #include <string> namespace libdb { extern "C" { #include <db.h> } } // namespace libdb namespace crepe { /** * \brief Berkeley DB facade * * Berkeley DB is a simple key-value database that stores arbitrary data as both key and value. * This facade uses STL strings as keys/values. */ class DB { public: /** * \param path The path of the database (created if nonexistant) * * \note If \p path is empty, the database is entirely in-memory */ DB(const std::string & path = ""); virtual ~DB() = default; public: /** * \brief Get a value from the database, or throw an exception * * \param key The value key * * \return The value * * \throws std::out_of_range if value is not found in DB * \throws std::runtime_error if other error occurs */ std::string get(const std::string & key); /** * \brief Set (create or overwrite) a value in the database * * \param key The value key * \param value The value to store * * \throws std::runtime_error if an error occurs */ void set(const std::string & key, const std::string & value); /** * \brief Check if a key exists in the database * * \param key The value key * * \returns True if the key exists, or false if it does not */ bool has(const std::string & key); private: //! RAII wrapper around \c DB struct std::unique_ptr<libdb::DB, std::function<void(libdb::DB *)>> db; //! RAII wrapper around \c DBC struct std::unique_ptr<libdb::DBC, std::function<void(libdb::DBC *)>> cursor; private: /** * \brief Convert an STL string to DBT (data base thang) * * \param thing Input data * \return \c DBT with the same data as input \c thing */ libdb::DBT to_thing(const std::string & thing) const noexcept; }; } // namespace crepe