diff --git a/src/base/database/database_interfaces/SqliteInterface.cpp b/src/base/database/database_interfaces/SqliteInterface.cpp index c65c998..71ca453 100644 --- a/src/base/database/database_interfaces/SqliteInterface.cpp +++ b/src/base/database/database_interfaces/SqliteInterface.cpp @@ -1,6 +1,7 @@ #include "SqliteInterface.h" #include "FileLogger.h" +#include "Directory.h" SqliteInterface::SqliteInterface() : mSqliteDb(nullptr) @@ -20,8 +21,10 @@ std::unique_ptr SqliteInterface::Create() void SqliteInterface::open(Database* db) { + Directory::createIfNotExisting(db->getPath()); + const auto path = db->getPath().string(); - int rc = sqlite3_open(path.c_str(), &mSqliteDb); + int rc = ::sqlite3_open(path.c_str(), &mSqliteDb); if( rc ) { MLOG_ERROR("Can't open database: %s\n" << sqlite3_errmsg(mSqliteDb)); @@ -42,11 +45,19 @@ static int callback(void *, int argc, char **, char **) void SqliteInterface::run(const std::string& statement) { + MLOG_INFO("Running statement: " << statement); char *zErrMsg = 0; int rc = sqlite3_exec(mSqliteDb, statement.c_str(), callback, 0, &zErrMsg); if (rc != SQLITE_OK) { - MLOG_ERROR("SQL error: %s\n" << zErrMsg); + if (zErrMsg == nullptr) + { + MLOG_ERROR("Unknown sql error"); + } + else + { + MLOG_ERROR("SQL error: %s\n" << zErrMsg); + } sqlite3_free(zErrMsg); } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8c8bc9d..4ca4cf3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,7 @@ add_subdirectory(test_utils) +add_subdirectory(core) +add_subdirectory(database) add_subdirectory(fonts) add_subdirectory(geometry) add_subdirectory(graphics) @@ -13,8 +15,6 @@ set(TEST_MODULES audio compiler compression - core - database image ipc mesh diff --git a/test/core/CMakeLists.txt b/test/core/CMakeLists.txt index f4b5cdf..0d5346b 100644 --- a/test/core/CMakeLists.txt +++ b/test/core/CMakeLists.txt @@ -1,13 +1,15 @@ -set(CORE_UNIT_TEST_FILES - core/TestByteUtils.cpp - core/TestBitStream.cpp - core/TestDataStructures.cpp - core/TestTomlReader.cpp - core/TestStringUtils.cpp - PARENT_SCOPE - ) - -set(CORE_UNIT_TEST_DEPENDENCIES - core - PARENT_SCOPE - ) \ No newline at end of file +set(MODULE_NAME core) + +list(APPEND UNIT_TEST_FILES + TestByteUtils.cpp + TestBitStream.cpp + TestDataStructures.cpp + TestTomlReader.cpp + TestStringUtils.cpp +) + +set(UNIT_TEST_TARGET_NAME ${MODULE_NAME}_unit_tests) + +add_executable(${UNIT_TEST_TARGET_NAME} ${CMAKE_SOURCE_DIR}/test/test_runner.cpp ${UNIT_TEST_FILES}) +target_link_libraries(${UNIT_TEST_TARGET_NAME} PUBLIC test_utils core) +set_property(TARGET ${UNIT_TEST_TARGET_NAME} PROPERTY FOLDER test/${MODULE_NAME}) \ No newline at end of file diff --git a/test/database/CMakeLists.txt b/test/database/CMakeLists.txt index f39f5cd..308befb 100644 --- a/test/database/CMakeLists.txt +++ b/test/database/CMakeLists.txt @@ -1,9 +1,11 @@ -set(DATABASE_UNIT_TEST_FILES - database/TestDatabase.cpp - PARENT_SCOPE - ) - -set(DATABASE_UNIT_TEST_DEPENDENCIES - database - PARENT_SCOPE - ) \ No newline at end of file +set(MODULE_NAME database) + +list(APPEND UNIT_TEST_FILES + TestDatabase.cpp +) + +set(UNIT_TEST_TARGET_NAME ${MODULE_NAME}_unit_tests) + +add_executable(${UNIT_TEST_TARGET_NAME} ${CMAKE_SOURCE_DIR}/test/test_runner.cpp ${UNIT_TEST_FILES}) +target_link_libraries(${UNIT_TEST_TARGET_NAME} PUBLIC test_utils database) +set_property(TARGET ${UNIT_TEST_TARGET_NAME} PROPERTY FOLDER test/${MODULE_NAME}) \ No newline at end of file diff --git a/test/database/TestDatabase.cpp b/test/database/TestDatabase.cpp index 1d4aece..d09a009 100644 --- a/test/database/TestDatabase.cpp +++ b/test/database/TestDatabase.cpp @@ -3,11 +3,78 @@ #include "TestFramework.h" #include "TestUtils.h" +#include "FileLogger.h" + +class DbTable +{ +public: + enum class Type + { + INT, + VAR_CHAR255 + }; + + using Entry = std::pair; + + std::string mName; + std::vector mColumns; + + std::string toString(Type type) const + { + switch (type) + { + case Type::INT: + return "int"; + case Type::VAR_CHAR255: + return "varchar(255)"; + default: + return "varchar(255)"; + } + } + + std::string getCreateQuery() const + { + std::string query = "CREATE TABLE " + mName + " ( "; + std::size_t count = 0; + for (const auto& column : mColumns) + { + query += column.first + " " + toString(column.second); + if (count < mColumns.size() - 1) + { + query += ", "; + } + count++; + } + query += "); "; + return query; + } +}; + TEST_CASE(TestDatabaseManager, "database") { DatabaseManager db_manager; - db_manager.openDatabase(TestUtils::getTestOutputDir() / "test.db"); - std::string statement = "CREATE TABLE corporation;"; + const auto db_path = TestUtils::getTestOutputDir() / "test.db"; + db_manager.openDatabase(db_path); + + DbTable table; + table.mName = "Persons"; + table.mColumns = { + {"PersonID", DbTable::Type::INT}, + {"LastName", DbTable::Type::VAR_CHAR255}, + {"FirstName", DbTable::Type::VAR_CHAR255}, + {"Address", DbTable::Type::VAR_CHAR255}, + {"City", DbTable::Type::VAR_CHAR255} + }; + + std::string statement = table.getCreateQuery(); db_manager.run(statement); + + db_manager.onShutDown(); + + if (std::filesystem::exists(db_path)) + { + std::filesystem::remove(db_path); + } + }