diff --git a/src/core/database.cpp b/src/core/database.cpp index a80cf0d..4a97e48 100644 --- a/src/core/database.cpp +++ b/src/core/database.cpp @@ -1,11 +1,13 @@ #include "database.h" +#include #include #include Database::Database(const std::string& dbname) : db_(nullptr) { - const int errCode = sqlite3_open(dbname.c_str(), &db_); + dbname_ = dbname; + const int errCode = sqlite3_open(dbname_.c_str(), &db_); if (errCode) { throw std::runtime_error("Could not open database file."); } @@ -26,8 +28,11 @@ void Database::exec(const std::string& sql) } } -void Database::init() +void Database::createNew() { + std::string sqlCreateKima2{"CREATE TABLE IF NOT EXISTS kima2 (" + "version INTEGER NOT NULL);" + "INSERT INTO kima2 (version) VALUES (1);"}; std::string sqlCreateSellers{"CREATE TABLE IF NOT EXISTS sellers (" "id TEXT PRIMARY KEY NOT NULL, " "seller_no INTEGER, " @@ -51,11 +56,73 @@ void Database::init() ");"}; beginTransaction(); + exec(sqlCreateKima2); exec(sqlCreateSellers); exec(sqlCreateArticles); endTransaction(); } +void Database::init() +{ + int version = getVersion(); + + switch (version) { + case 0: + createNew(); + break; + // perhaps handle upgrades for db schema here... + default: + // Do nothing because we are up-to-date. + break; + } +} + +int Database::getVersion() +{ + int retCode{}; + sqlite3_stmt* stmt; + + // Check if there's already a kima2 table available. + // If not, return version == 0. + retCode = sqlite3_prepare_v2( + db_, "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='kima2';", -1, &stmt, + nullptr); + if (retCode != SQLITE_OK) + throw std::string(sqlite3_errmsg(db_)); + retCode = sqlite3_step(stmt); + if (retCode != SQLITE_ROW && retCode != SQLITE_DONE) { + std::string errMsg(sqlite3_errmsg(db_)); + sqlite3_finalize(stmt); + throw errMsg; + } else if (retCode != SQLITE_DONE) { + int count = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + if (count == 0) + return 0; // no kima2 table, so version is 0 + } + + // Now that we know that the kima2 table is present, read and return the schema version. + retCode = sqlite3_prepare_v2(db_, "SELECT version FROM kima2", -1, &stmt, nullptr); + if (retCode != SQLITE_OK) + throw std::string(sqlite3_errmsg(db_)); + + retCode = sqlite3_step(stmt); + + if (retCode != SQLITE_ROW && retCode != SQLITE_DONE) { + std::string errMsg(sqlite3_errmsg(db_)); + sqlite3_finalize(stmt); + throw errMsg; + } else if (retCode == SQLITE_DONE) { + sqlite3_finalize(stmt); + return 0; // no version entry, so version is 0 + } + + int version = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + + return version; +} + void Database::beginTransaction() { exec("BEGIN TRANSACTION"); } void Database::endTransaction() { exec("END TRANSACTION"); } \ No newline at end of file diff --git a/src/core/database.h b/src/core/database.h index c0b4de4..ff6f3d8 100644 --- a/src/core/database.h +++ b/src/core/database.h @@ -16,8 +16,11 @@ public: void init(); private: sqlite3 *db_; + std::string dbname_; void beginTransaction(); void endTransaction(); + void createNew(); + int getVersion(); }; #endif // DATABASE_H \ No newline at end of file