feat: implement db provider

This commit is contained in:
Samsonium
2026-09-29 14:46:44 +03:00
parent e756bb1d73
commit 62f844a582
7 changed files with 181 additions and 6 deletions
+16
View File
@@ -3,12 +3,15 @@ project(magic_scrolls)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(SQLite3 REQUIRED)
file(GLOB_RECURSE sources file(GLOB_RECURSE sources
"${CMAKE_SOURCE_DIR}/src/*.cpp") "${CMAKE_SOURCE_DIR}/src/*.cpp")
add_executable(magic_scrolls ${sources}) add_executable(magic_scrolls ${sources})
target_include_directories(magic_scrolls PUBLIC "${CMAKE_SOURCE_DIR}/include") target_include_directories(magic_scrolls PUBLIC "${CMAKE_SOURCE_DIR}/include")
target_link_libraries(magic_scrolls PRIVATE SQLite::SQLite3)
# ------- # -------
enable_testing() enable_testing()
@@ -17,10 +20,23 @@ add_executable(event_bus_test
tests/engine/event_bus_test.cpp tests/engine/event_bus_test.cpp
src/engine/core/event_bus.cpp src/engine/core/event_bus.cpp
) )
add_executable(db_provider_test
tests/engine/db_provider_test.cpp
src/engine/core/engine.cpp
src/engine/core/engine_db_provider.cpp
)
target_include_directories(event_bus_test PUBLIC "${CMAKE_SOURCE_DIR}/include") target_include_directories(event_bus_test PUBLIC "${CMAKE_SOURCE_DIR}/include")
target_link_libraries(event_bus_test PRIVATE SQLite::SQLite3)
target_include_directories(db_provider_test PUBLIC "${CMAKE_SOURCE_DIR}/include")
target_link_libraries(db_provider_test PRIVATE SQLite::SQLite3)
add_test( add_test(
NAME "Event Bus" NAME "Event Bus"
COMMAND event_bus_test COMMAND event_bus_test
) )
add_test(
NAME "Database Provider"
COMMAND db_provider_test
)
+5 -2
View File
@@ -1,8 +1,9 @@
#ifndef __MCS_ENGINE_HPP__ #ifndef __MCS_ENGINE_HPP__
#define __MCS_ENGINE_HPP__ #define __MCS_ENGINE_HPP__
#include "engine/core/engine_module.hpp" #include <engine/core/engine_module.hpp>
#include "engine/core/engine_module_api.hpp" #include <engine/core/engine_module_api.hpp>
#include <engine/core/engine_db_provider.hpp>
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <vector> #include <vector>
@@ -24,6 +25,8 @@ public:
MscEventBus &getBus() override; MscEventBus &getBus() override;
std::unordered_map<std::string, std::uint16_t> getLoadedModules() const override; std::unordered_map<std::string, std::uint16_t> getLoadedModules() const override;
MscEngineModule &getModule(const std::string &name) override; MscEngineModule &getModule(const std::string &name) override;
std::unique_ptr<MscEngineDBProvider> createDBProvider() override;
std::unique_ptr<MscEngineDBProvider> createDBProvider(const std::string &filepath) override;
}; };
#endif // __MCS_ENGINE_HPP__ #endif // __MCS_ENGINE_HPP__
@@ -0,0 +1,30 @@
#ifndef __MSC_ENGINE_DB_PROVIDER_HPP__
#define __MSC_ENGINE_DB_PROVIDER_HPP__
#include <sqlite3.h>
#include <string>
/// @brief Engine database provider
class MscEngineDBProvider
{
public:
~MscEngineDBProvider();
/// @brief Create inmemory database
MscEngineDBProvider();
/// @brief Create file database
explicit MscEngineDBProvider(const std::string &filepath);
/// @brief Execute SQL statement
/// @param sql statement
void execute(const std::string &sql);
MscEngineDBProvider(const MscEngineDBProvider &) = delete;
MscEngineDBProvider &operator=(const MscEngineDBProvider &) = delete;
private:
sqlite3 *_db = nullptr;
};
#endif // __MSC_ENGINE_DB_PROVIDER_HPP__
+13 -4
View File
@@ -2,24 +2,33 @@
#define __MSC_ENGINE_MODULE_API_HPP__ #define __MSC_ENGINE_MODULE_API_HPP__
#include <engine/core/engine_bus.hpp> #include <engine/core/engine_bus.hpp>
#include <engine/core/engine_module.hpp> #include <engine/core/engine_db_provider.hpp>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <memory>
class MscEngineModule;
class IMscEngineModuleAPI class IMscEngineModuleAPI
{ {
public: public:
virtual ~IMscEngineModuleAPI() = default; virtual ~IMscEngineModuleAPI() = default;
/// Get access to engine event bus /// @brief Get access to engine event bus
virtual MscEventBus &getBus() = 0; virtual MscEventBus &getBus() = 0;
/// Get access to loaded module list /// @brief Get access to loaded module list
virtual std::unordered_map<std::string, std::uint16_t> getLoadedModules() const = 0; virtual std::unordered_map<std::string, std::uint16_t> getLoadedModules() const = 0;
/// Access module by its name /// @brief Access module by its name
virtual MscEngineModule &getModule(const std::string &name) = 0; virtual MscEngineModule &getModule(const std::string &name) = 0;
/// @brief Create database provider with in-memory database
virtual std::unique_ptr<MscEngineDBProvider> createDBProvider() = 0;
/// @brief Create database provider with file database
virtual std::unique_ptr<MscEngineDBProvider> createDBProvider(const std::string &filepath) = 0;
}; };
#endif // __MSC_ENGINE_MODULE_API_HPP__ #endif // __MSC_ENGINE_MODULE_API_HPP__
+10
View File
@@ -84,3 +84,13 @@ MscEngineModule &MscEngine::getModule(const std::string &name)
throw std::runtime_error("Module not found: " + name); throw std::runtime_error("Module not found: " + name);
} }
std::unique_ptr<MscEngineDBProvider> MscEngine::createDBProvider()
{
return std::make_unique<MscEngineDBProvider>();
}
std::unique_ptr<MscEngineDBProvider> MscEngine::createDBProvider(const std::string &filepath)
{
return std::make_unique<MscEngineDBProvider>(filepath);
}
+45
View File
@@ -0,0 +1,45 @@
#include <engine/core/engine_db_provider.hpp>
#include <stdexcept>
MscEngineDBProvider::MscEngineDBProvider() : MscEngineDBProvider(":memory:")
{
}
MscEngineDBProvider::MscEngineDBProvider(const std::string &filepath)
{
const int result = sqlite3_open(filepath.c_str(), &_db);
if (result != SQLITE_OK)
{
const std::string message = _db != nullptr
? sqlite3_errmsg(_db)
: "unknown SQLite error";
if (_db != nullptr)
{
sqlite3_close(_db);
_db = nullptr;
}
throw std::runtime_error("Failed to open SQLite database: " + message);
}
}
MscEngineDBProvider::~MscEngineDBProvider()
{
if (_db != nullptr)
sqlite3_close(_db);
}
void MscEngineDBProvider::execute(const std::string &sql)
{
char *errorMessage = nullptr;
const int result = sqlite3_exec(_db, sql.c_str(), nullptr, nullptr, &errorMessage);
if (result == SQLITE_OK)
return;
std::string message(errorMessage);
sqlite3_free(errorMessage);
throw std::runtime_error("Failed to execute SQL: " + message);
}
+62
View File
@@ -0,0 +1,62 @@
#include <cassert>
#include <vector>
#include <stdexcept>
#include <engine/core/engine.hpp>
#include <engine/core/engine_db_provider.hpp>
/// @brief Проверка на создание экземпляра
void testProviderCreation()
{
MscEngine engine({});
auto dbp1 = engine.createDBProvider();
assert(dbp1.get() != nullptr);
}
/// @brief Проверка на создание экземпляра с некорректным путём файла
void testIncorrectFilePath()
{
MscEngine engine({});
try
{
engine.createDBProvider("/i/am/an/incorrect/path/to/file.txt");
assert(false);
}
catch (const std::runtime_error &error)
{
}
}
/// @brief Проверка на успешное выполнение корректного выражения
void testValidStatement()
{
MscEngine engine({});
auto dbp = engine.createDBProvider();
dbp.get()->execute("SELECT 'hello, world' AS message;");
}
void testInvalidStatement()
{
MscEngine engine({});
auto dbp = engine.createDBProvider();
try
{
dbp.get()->execute("SELECT * FROM nonexistentdatabase ABC");
assert(false);
}
catch (const std::runtime_error &error)
{
}
}
int main()
{
testProviderCreation();
testIncorrectFilePath();
testValidStatement();
testInvalidStatement();
return 0;
}