28DbMigrator::DbMigrator(sqlite3* db) : db_(db) {}
30void DbMigrator::addMigration(
int version, MigrationFn fn) {
31 migrations_.push_back({version, fn});
34int DbMigrator::getUserVersion() {
38 if (sqlite3_prepare_v2(db_,
"PRAGMA user_version;", -1, &stmt,
nullptr) ==
40 if (sqlite3_step(stmt) == SQLITE_ROW) {
41 version = sqlite3_column_int(stmt, 0);
44 sqlite3_finalize(stmt);
48void DbMigrator::setUserVersion(
int v) {
49 exec(
"PRAGMA user_version = " + std::to_string(v) +
";");
52void DbMigrator::exec(
const std::string& sql) {
53 char* errMsg =
nullptr;
54 if (sqlite3_exec(db_, sql.c_str(),
nullptr,
nullptr, &errMsg) != SQLITE_OK) {
55 std::string err = errMsg ? errMsg :
"Unknown SQL error";
57 throw std::runtime_error(err);
61void DbMigrator::begin() { exec(
"BEGIN TRANSACTION;"); }
62void DbMigrator::commit() { exec(
"COMMIT;"); }
63void DbMigrator::rollback() { exec(
"ROLLBACK;"); }
65void DbMigrator::migrate() {
66 std::sort(migrations_.begin(), migrations_.end(),
67 [](
const Migration& a,
const Migration& b) {
68 return a.version < b.version;
71 int current = getUserVersion();
73 for (
const auto& m : migrations_) {
74 if (m.version > current) {
78 setUserVersion(m.version);
MySQL schema update facility.