From 4a963cc480bb5a78e20380131ba886a7a23b0782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 16 Jun 2017 09:49:08 +0200 Subject: At startup, upgrade all database tables by adding missing columns --- src/database/table.hpp | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src/database/table.hpp') diff --git a/src/database/table.hpp b/src/database/table.hpp index dc871c3..411ac6a 100644 --- a/src/database/table.hpp +++ b/src/database/table.hpp @@ -7,6 +7,26 @@ #include #include +#include + +using namespace std::string_literals; + +std::set get_all_columns_from_table(sqlite3* db, const std::string& table_name); + +template +void add_column_to_table(sqlite3* db, const std::string& table_name) +{ + const std::string name = ColumnType::name; + std::string query{"ALTER TABLE "s + table_name + " ADD " + ColumnType::name + " " + TypeToSQLType::type}; + log_debug(query); + char* error; + const auto result = sqlite3_exec(db, query.data(), nullptr, nullptr, &error); + if (result != SQLITE_OK) + { + log_error("Error adding column ", name, " to table ", table_name, ": ", error); + sqlite3_free(error); + } +} template class Table @@ -21,6 +41,12 @@ class Table name(std::move(name)) {} + void upgrade(sqlite3* db) + { + const auto existing_columns = get_all_columns_from_table(db, this->name); + add_column_if_not_exists(db, existing_columns); + } + void create(sqlite3* db) { std::string res{"CREATE TABLE IF NOT EXISTS "}; @@ -58,6 +84,23 @@ class Table } private: + + template + typename std::enable_if::type + add_column_if_not_exists(sqlite3* db, const std::set& existing_columns) + { + using ColumnType = typename std::remove_reference(std::declval()))>::type; + if (existing_columns.count(ColumnType::name) != 1) + { + add_column_to_table(db, this->name); + } + add_column_if_not_exists(db, existing_columns); + } + template + typename std::enable_if::type + add_column_if_not_exists(sqlite3*, const std::set&) + {} + template typename std::enable_if::type add_column_create(std::string& str) -- cgit v1.2.3