OpenCPN Partial API docs
Loading...
Searching...
No Matches
navobj_db_migrator.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2026 by David S. Register *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 **************************************************************************/
17
25#include <stdexcept>
26#include <algorithm>
27
28DbMigrator::DbMigrator(sqlite3* db) : db_(db) {}
29
30void DbMigrator::addMigration(int version, MigrationFn fn) {
31 migrations_.push_back({version, fn});
32}
33
34int DbMigrator::getUserVersion() {
35 sqlite3_stmt* stmt;
36 int version = 0;
37
38 if (sqlite3_prepare_v2(db_, "PRAGMA user_version;", -1, &stmt, nullptr) ==
39 SQLITE_OK) {
40 if (sqlite3_step(stmt) == SQLITE_ROW) {
41 version = sqlite3_column_int(stmt, 0);
42 }
43 }
44 sqlite3_finalize(stmt);
45 return version;
46}
47
48void DbMigrator::setUserVersion(int v) {
49 exec("PRAGMA user_version = " + std::to_string(v) + ";");
50}
51
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";
56 sqlite3_free(errMsg);
57 throw std::runtime_error(err);
58 }
59}
60
61void DbMigrator::begin() { exec("BEGIN TRANSACTION;"); }
62void DbMigrator::commit() { exec("COMMIT;"); }
63void DbMigrator::rollback() { exec("ROLLBACK;"); }
64
65void DbMigrator::migrate() {
66 std::sort(migrations_.begin(), migrations_.end(),
67 [](const Migration& a, const Migration& b) {
68 return a.version < b.version;
69 });
70
71 int current = getUserVersion();
72
73 for (const auto& m : migrations_) {
74 if (m.version > current) {
75 begin();
76 try {
77 m.fn(db_);
78 setUserVersion(m.version);
79 commit();
80 } catch (...) {
81 rollback();
82 throw;
83 }
84 }
85 }
86}
MySQL schema update facility.