reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit bba76f9dffba9b0332644d724413fafe23ce10bf
parent 84f56a613e1cdd241d8fcd33765974c531b03cae
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Mon, 18 Jan 2016 14:59:01 -0500

write code for database migrations

Diffstat:
Msrc/database.cpp | 20+++++++++++++++++++-
Msrc/database.hpp | 6++++--
Msrc/registry.cpp | 37++++++++++++++++++++++++++-----------
Msrc/registry.hpp | 3+++
Mtest/database.cpp | 8++++++++
5 files changed, 60 insertions(+), 14 deletions(-)

diff --git a/src/database.cpp b/src/database.cpp @@ -46,6 +46,19 @@ Database::~Database() sqlite3_close(m_db); } +int Database::version() const +{ + int version = 0; + + Statement stmt("PRAGMA user_version", this); + stmt.exec([&] { + version = stmt.intColumn(0); + return false; + }); + + return version; +} + Statement *Database::prepare(const char *sql) { Statement *stmt = new Statement(sql, this); @@ -65,7 +78,7 @@ reapack_error Database::lastError() const return reapack_error(sqlite3_errmsg(m_db)); } -Statement::Statement(const char *sql, Database *db) +Statement::Statement(const char *sql, const Database *db) : m_db(db) { if(sqlite3_prepare_v2(db->m_db, sql, -1, &m_stmt, nullptr) != SQLITE_OK) @@ -113,6 +126,11 @@ void Statement::exec(const ExecCallback &callback) } } +int Statement::intColumn(const int index) const +{ + return sqlite3_column_int(m_stmt, index); +} + uint64_t Statement::uint64Column(const int index) const { return (uint64_t)sqlite3_column_int64(m_stmt, index); diff --git a/src/database.hpp b/src/database.hpp @@ -35,6 +35,7 @@ public: Database(const std::string &filename = std::string()); ~Database(); + int version() const; Statement *prepare(const char *sql); void exec(const char *sql); @@ -56,16 +57,17 @@ public: void exec(); void exec(const ExecCallback &); + int intColumn(const int index) const; uint64_t uint64Column(const int index) const; std::string stringColumn(const int index) const; private: friend Database; - Statement(const char *sql, Database *db); + Statement(const char *sql, const Database *db); ~Statement(); - Database *m_db; + const Database *m_db; sqlite3_stmt *m_stmt; }; diff --git a/src/registry.cpp b/src/registry.cpp @@ -29,17 +29,7 @@ using namespace std; Registry::Registry(const Path &path) : m_db(path.join()) { - m_db.exec( - "PRAGMA foreign_keys = ON;" - - "CREATE TABLE IF NOT EXISTS entries (" - " remote TEXT NOT NULL," - " category TEXT NOT NULL," - " package TEXT NOT NULL," - " version INTEGER NOT NULL," - " UNIQUE(remote, category, package)" - ");" - ); + migrate(); m_insertEntry = m_db.prepare( "INSERT OR REPLACE INTO entries " @@ -56,6 +46,31 @@ Registry::Registry(const Path &path) m_db.exec("BEGIN EXCLUSIVE TRANSACTION"); } +void Registry::migrate() +{ + switch(m_db.version()) { + case 0: + // new database! + m_db.exec( + "PRAGMA user_version = 1;" + + "CREATE TABLE entries (" + " remote TEXT NOT NULL," + " category TEXT NOT NULL," + " package TEXT NOT NULL," + " version INTEGER NOT NULL," + " UNIQUE(remote, category, package)" + ");" + ); + break; + case 1: + // current schema version + break; + default: + throw reapack_error("database was created with a newer version of ReaPack"); + } +} + void Registry::push(Version *ver) { Package *pkg = ver->package(); diff --git a/src/registry.hpp b/src/registry.hpp @@ -51,6 +51,9 @@ public: QueryResult query(Package *) const; private: + int version(); + void migrate(); + Database m_db; Statement *m_insertEntry; Statement *m_findEntry; diff --git a/test/database.cpp b/test/database.cpp @@ -94,3 +94,11 @@ TEST_CASE("bing values and clear", M) { REQUIRE(string(e.what()) == "NOT NULL constraint failed: test.value"); } } + +TEST_CASE("version", M) { + Database db; + REQUIRE(db.version() == 0); + + db.exec("PRAGMA user_version = 1"); + REQUIRE(db.version() == 1); +}