nwaku/waku/v2/node/storage/migration/migration_utils.nim
Sanaz Taheri Boshrooyeh ddf93814fe
Persisting Waku message timestamp & implementing DB migration & convert receiver timestamp data type to float64 (#607)
* adds timestamp to waku message store impl

* stores timestamp as int64

* adds untitest

* stores timestamp as seq of bytes

* minor

* re-orders unittest

* changes receiver timestamp to float64

* unit test for receiver timestamps

* adds comments

* reorder a few lines

* updates changelog

* more updates on changelog

* WIP

* WIP

* adds migration

* more debug messages

* passes the path to the migration scripts from message store module

* adds migration result type

* replaces migrationScripts with migrationScriptsResult

* adds path calculation to the message store

* removes some tests binary file

* removes redundant imports

* comments out user_version assignment in sqlite  init

* more descriptive err messages

* clean up test file

* more info logs

* minor code format

* removes a todo

* minor updates

* remove a binary file

* unit tests for migration utils

* adds split script

* integrates split query to handle scripts with multiple commands

* updates migration script for v1

* updates the v1 migration script

* update user version

* updates script

* fixes a few bugs on the splitScript

* more debug logs

* adds float64 parameter support to sqlite3

* change in timestamp type in the script

* deletes float64 toBytes utils

* enables storage of timestamp as a real number in the sqlite db

* bump up script index

* comment edits

* removes migrate unit test

* adds todo and docstring

* updates changelog

* removes an unused item in .gitignore

* minor

* updates changelog

* organizes imports

* cleans up imports

* WIP

* updates script


fixes a few bugs on the splitScript


more debug logs


adds float64 parameter support to sqlite3


change in timestamp type in the script


deletes float64 toBytes utils

* edits migration util test

* remove an empty test file

* includes migration utils tests in

* deletes unused codes

* tides up imports

* adds range based filter to the filterMigrationScripts

* renames procs: removes Migration

* tides up imports

* edits docstring

* edits docstring

* edits docstring

* removes unused imports

* more clean up

* groups std imports

* updates changelog

* adds docstring for setUserVersion

* adds unittest for the migrate

* Update waku/v2/node/storage/message/waku_message_store.nim

Co-authored-by: RichΛrd <info@richardramos.me>

* Update waku/v2/node/storage/sqlite.nim

Co-authored-by: RichΛrd <info@richardramos.me>

* Update waku/v2/node/storage/sqlite.nim

Co-authored-by: RichΛrd <info@richardramos.me>

* removes split scripts

* fixes a naming issue

* fixes a bug

* fixes a typo

* adds a log re updated user_version

* fixes a proc naming mismatch

* fixes naming mismatch

* more descriptive var names

* adds migration script of the first user version

* moves migration to after persistMessages flag is checked

* deletes unused comment

* fixes a bug

* brings back split script

* adds unit tests for split scripts

* runs scripts one command at a time

* deletes a commented line

* relocates the migrate proc to sqlite.nim

* adds unit test for filter scripts

* adds filterScripts unittest testing varying zero-prefixed user versions

* minor

Co-authored-by: RichΛrd <info@richardramos.me>
2021-06-16 13:23:55 -07:00

64 lines
2.2 KiB
Nim

import
std/[os, algorithm, tables, strutils],
chronicles,
stew/results,
migration_types
proc getScripts*(migrationPath: string): MigrationScriptsResult[MigrationScripts] =
## the code in this procedure is an adaptation of https://github.com/status-im/nim-status/blob/21aebe41be03cb6450ea261793b800ed7d3e6cda/nim_status/migrations/sql_generate.nim#L4
var migrationScripts = MigrationScripts(migrationUp:initOrderedTable[string, string](), migrationDown:initOrderedTable[string, string]())
try:
for kind, path in walkDir(migrationPath):
let (_, name, ext) = splitFile(path)
if ext != ".sql": continue
let parts = name.split(".")
if parts.len < 2:
continue
let script = parts[0]
let direction = parts[1]
debug "name", script=script
case direction:
of "up":
migrationScripts.migrationUp[script] = readFile(path)
debug "up script", readScript=migrationScripts.migrationUp[script]
of "down":
migrationScripts.migrationDown[script] = readFile(path)
debug "down script", readScript=migrationScripts.migrationDown[script]
else:
debug "Invalid script: ", name
migrationScripts.migrationUp.sort(system.cmp)
migrationScripts.migrationDown.sort(system.cmp)
ok(migrationScripts)
except OSError, IOError:
return err("failed to load the migration scripts")
proc filterScripts*(migrationScripts: MigrationScripts, s: int64, e: int64 ): Result[seq[string], string] =
## returns migration scripts whose version fall between s and e (e is inclusive)
var scripts: seq[string]
try:
for name, script in migrationScripts.migrationUp:
let parts = name.split("_")
#TODO this should be int64
let ver = parseInt(parts[0])
# filter scripts based on their version
if s < ver and ver <= e:
scripts.add(script)
ok(scripts)
except ValueError:
return err("failed to filter scripts")
proc splitScript*(script: string): seq[string] =
## parses the script into its individual sql commands and returns them
var queries: seq[string] = @[]
for q in script.split(';'):
if isEmptyOrWhitespace(q): continue
let query = q.strip() & ";"
queries.add(query)
return queries