Skip to content

Commit

Permalink
fix(sqlite): Properly set user_version to 7 so that the migration pro…
Browse files Browse the repository at this point in the history
…cedure is not started (#2031)
  • Loading branch information
Ivansete-status authored and vpavlin committed Sep 14, 2023
1 parent a4e7833 commit 638ff31
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion waku/waku_archive/driver/sqlite_driver/migrations.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import
std/[tables, strutils, os],
stew/results,
chronicles
chronicles,
sqlite3_abi # sqlite3_column_int64
import
../../../common/databases/db_sqlite,
../../../common/databases/common
Expand All @@ -18,6 +19,37 @@ const SchemaVersion* = 7 # increase this when there is an update in the database
template projectRoot: string = currentSourcePath.rsplit(DirSep, 1)[0] / ".." / ".." / ".." / ".."
const MessageStoreMigrationPath: string = projectRoot / "migrations" / "message_store"

proc isSchemaVersion7*(db: SqliteDatabase): DatabaseResult[bool] =
## Temporary proc created to analyse when the table actually belongs to the SchemaVersion 7.
##
## During many nwaku versions, 0.14.0 until 0.18.0, the SchemaVersion wasn't set or checked.
## Docker `nwaku` nodes that start working from these versions, 0.14.0 until 0.18.0, they started
## with this discrepancy: `user_version`== 0 (not set) but Message table with SchemaVersion 7.
##
## We found issues where `user_version` (SchemaVersion) was set to 0 in the database even though
## its scheme structure reflected SchemaVersion 7. In those cases, when `nwaku` re-started to
## apply the migration scripts (in 0.19.0) the node didn't start properly because it tried to
## migrate a database that already had the Schema structure #7, so it failed when changing the PK.
##
## TODO: This was added in version 0.20.0. We might remove this in version 0.30.0, as we
## could consider that many users use +0.20.0.

var pkColumns = newSeq[string]()
proc queryRowCallback(s: ptr sqlite3_stmt) =
let colName = cstring sqlite3_column_text(s, 0)
pkColumns.add($colName)

let query = """SELECT l.name FROM pragma_table_info("Message") as l WHERE l.pk != 0;"""
let res = db.query(query, queryRowCallback)
if res.isErr():
return err("failed to determine the current SchemaVersion: " & $res.error)

if pkColumns == @["pubsubTopic", "id", "storedAt"]:
return ok(true)

else:
info "Not considered schema version 7"
ok(false)

proc migrate*(db: SqliteDatabase, targetVersion = SchemaVersion): DatabaseResult[void] =
## Compares the `user_version` of the sqlite database with the provided `targetVersion`, then
Expand All @@ -30,6 +62,14 @@ proc migrate*(db: SqliteDatabase, targetVersion = SchemaVersion): DatabaseResult
## NOTE: Down migration it is not currently supported
debug "starting message store's sqlite database migration"

let userVersion = ? db.getUserVersion()
let isSchemaVersion7 = ? db.isSchemaVersion7()

if userVersion == 0'i64 and isSchemaVersion7:
info "We found user_version 0 but the database schema reflects the user_version 7"
## Force the correct schema version
? db.setUserVersion( 7 )

let migrationRes = migrate(db, targetVersion, migrationsScriptsDir=MessageStoreMigrationPath)
if migrationRes.isErr():
return err("failed to execute migration scripts: " & migrationRes.error)
Expand Down

0 comments on commit 638ff31

Please sign in to comment.