nwaku/waku/v2/node/storage/migration.nim

81 lines
2.4 KiB
Nim

import
stew/results,
chronicles
import
./sqlite,
./migration/migration_types,
./migration/migration_utils
export
migration_types,
migration_utils
logScope:
topics = "storage.migration"
const USER_VERSION* = 7 # increase this when there is an update in the database schema
proc migrate*(db: SqliteDatabase, path: string, targetVersion: int64 = USER_VERSION): DatabaseResult[void] =
## Compares the user_version of the db with the targetVersion
## runs migration scripts if the user_version is outdated (does not support down migration)
## path points to the directory holding the migrations scripts
## once the db is updated, it sets the user_version to the tragetVersion
# read database version
let userVersionRes = db.getUserVersion()
if userVersionRes.isErr():
debug "failed to get user_version", error=userVersionRes.error
let userVersion = userVersionRes.value
debug "current database user_version", userVersion=userVersion, targetVersion=targetVersion
if userVersion == targetVersion:
info "database is up to date"
return ok()
info "database user_version outdated. migrating.", userVersion=userVersion, targetVersion=targetVersion
# fetch migration scripts
let migrationScriptsRes = getScripts(path)
if migrationScriptsRes.isErr():
return err("failed to load migration scripts")
let migrationScripts = migrationScriptsRes.value
# filter scripts based on their versions
let scriptsRes = migrationScripts.filterScripts(userVersion, targetVersion)
if scriptsRes.isErr():
return err("failed to filter migration scripts")
let scripts = scriptsRes.value
if scripts.len == 0:
return err("no suitable migration scripts")
trace "migration scripts", scripts=scripts
# Run the migration scripts
for script in scripts:
for query in script.splitScript():
debug "executing migration statement", statement=query
let execRes = db.query(query, NoopRowHandler)
if execRes.isErr():
error "failed to execute migration statement", statement=query, error=execRes.error
return err("failed to execute migration statement")
debug "migration statement executed succesfully", statement=query
# Update user_version
let res = db.setUserVersion(targetVersion)
if res.isErr():
return err("failed to set the new user_version")
debug "database user_version updated", userVersion=targetVersion
ok()