#include "database.h" #include #include Database::Database(const std::string& dbname) : db_(nullptr) { const int errCode = sqlite3_open(dbname.c_str(), &db_); if (errCode) { throw std::runtime_error("Could not open database file."); } sqlite3_db_config(db_, SQLITE_DBCONFIG_ENABLE_FKEY); } Database::~Database() { sqlite3_close(db_); } void Database::exec(const std::string& sql) { char* errMsg; const int errCode = sqlite3_exec(db_, sql.c_str(), nullptr, nullptr, &errMsg); if (errCode) { std::string errMsgString(errMsg); // Make a C++ string of the errMsg, so that we can call // sqlite3_free() before throwing the exception sqlite3_free(errMsg); throw std::runtime_error("Error in SQL execution: " + errMsgString); } } void Database::init() { std::string sqlCreateSellers{"CREATE TABLE IF NOT EXISTS sellers (" "id TEXT PRIMARY KEY NOT NULL, " "seller_no INTEGER, " "first_name TEXT, " "last_name TEXT, " "offered_articles INTEGER, " "UNIQUE (seller_no)" ");"}; std::string sqlCreateArticles{ "CREATE TABLE IF NOT EXISTS articles (" "id TEXT PRIMARY KEY NOT NULL, " "seller_id TEXT NOT NULL, " "source_no INTEGER NOT NULL, " "article_no INTEGER NOT NULL, " "description TEXT, " "price INTEGER NOT NULL, " "UNIQUE (source_no, article_no), " "FOREIGN KEY (seller_id) REFERENCES sellers(id) ON DELETE CASCADE, " "CHECK (article_no BETWEEN 0 AND 99999)" ");"}; beginTransaction(); exec(sqlCreateSellers); exec(sqlCreateArticles); endTransaction(); } void Database::beginTransaction() { exec("BEGIN TRANSACTION"); } void Database::endTransaction() { exec("END TRANSACTION"); }