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:
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);
+}