29int getUserVersion(sqlite3* db) {
30 sqlite3_stmt* stmt =
nullptr;
33 const char* sql =
"PRAGMA user_version;";
35 int rc = sqlite3_prepare_v2(db, sql, -1, &stmt,
nullptr);
36 if (rc != SQLITE_OK) {
40 rc = sqlite3_step(stmt);
41 if (rc == SQLITE_ROW) {
42 version = sqlite3_column_int(stmt, 0);
45 sqlite3_finalize(stmt);
49void setUserVersion(sqlite3* db,
int v) {
50 std::string sql =
"PRAGMA user_version = " + std::to_string(v) +
";";
52 char* errMsg =
nullptr;
53 int rc = sqlite3_exec(db, sql.c_str(),
nullptr,
nullptr, &errMsg);
55 if (rc != SQLITE_OK) {
56 std::string err = errMsg ? errMsg :
"Failed to set user_version";
58 throw std::runtime_error(err);
62inline bool columnInPrimaryKey(sqlite3* db,
const std::string& table,
63 const std::string& column) {
64 std::string sql =
"PRAGMA table_info(" + table +
");";
67 if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt,
nullptr) != SQLITE_OK)
72 while (sqlite3_step(stmt) == SQLITE_ROW) {
74 reinterpret_cast<const char*
>(sqlite3_column_text(stmt, 1));
75 int pk = sqlite3_column_int(stmt, 5);
77 if (name == column && pk > 0) {
83 sqlite3_finalize(stmt);
87bool needsMigration_0_1(sqlite3* db) {
88 int version = getUserVersion(db);
92 columnInPrimaryKey(db,
"routepoints_link",
"route_guid");
94 columnInPrimaryKey(db,
"routepoints_link",
"point_guid");
96 columnInPrimaryKey(db,
"routepoints_link",
"point_order");
97 return hasRouteGuid && hasPointGuid && !hasPointOrder;
105std::string SchemaUpdate_0_1(sqlite3* db, wxFrame* frame) {
108 if (needsMigration_0_1(db)) {
111 migrator.addMigration(1, [](sqlite3* db) {
112 char* errMsg =
nullptr;
114 const char* sql = R
"(
115 CREATE TABLE routepoints_link_new (
119 PRIMARY KEY (route_guid, point_order),
120 FOREIGN KEY (route_guid) REFERENCES routes(guid) ON DELETE CASCADE
123 INSERT INTO routepoints_link_new
125 FROM routepoints_link t
128 FROM routepoints_link t2
129 WHERE t.route_guid = t2.route_guid
130 AND t.point_order = t2.point_order
133 DROP TABLE routepoints_link;
135 ALTER TABLE routepoints_link_new RENAME TO routepoints_link;
138 if (sqlite3_exec(db, sql,
nullptr,
nullptr, &errMsg) != SQLITE_OK) {
139 std::string err = errMsg ? errMsg :
"";
140 sqlite3_free(errMsg);
141 throw std::runtime_error(err);
147 }
catch (
const std::runtime_error& e) {
149 return (std::string(
"Migration 0->1 failed: ") + e.what());
150 }
catch (
const std::exception& e) {
152 return (std::string(
"Unexpected error on migration 0->1: ") + e.what());
155 return (
"Unknown non-standard exception during migration");
MySQL based storage for routes, tracks, etc.
MySQL schema update facility.
navobj_db_util.h – MySQL support utilities