rename sql tests

This commit is contained in:
Dmitriy Ryajov 2022-09-16 21:15:43 -06:00
parent 5d29ad905d
commit c7df334836
No known key found for this signature in database
GPG Key ID: DA8C680CE7C657A4

View File

@ -1,586 +0,0 @@
import std/algorithm
import std/options
import std/os
import pkg/asynctest/unittest2
import pkg/chronos
import pkg/stew/results
import ../../datastore/sqlite_datastore
import ./templates
suite "SQLiteDatastore":
var
ds: SQLiteDatastore
# assumes tests/test_all is run from project root, e.g. with `nimble test`
let
basePath = "tests" / "test_data"
basePathAbs = getCurrentDir() / basePath
filename = "test_store" & dbExt
dbPathAbs = basePathAbs / filename
setup:
removeDir(basePathAbs)
require(not dirExists(basePathAbs))
createDir(basePathAbs)
teardown:
if not ds.isNil: ds.close
ds = nil
removeDir(basePathAbs)
require(not dirExists(basePathAbs))
asyncTest "new":
var
dsRes = SQLiteDatastore.new(basePathAbs, filename, readOnly = true)
# for `readOnly = true` to succeed the database file must already exist
check: dsRes.isErr
dsRes = SQLiteDatastore.new(basePathAbs / "missing", filename)
check: dsRes.isErr
dsRes = SQLiteDatastore.new(basePathAbs, filename)
check:
dsRes.isOk
fileExists(dbPathAbs)
dsRes.get.close
removeDir(basePathAbs)
assert not dirExists(basePathAbs)
createDir(basePathAbs)
dsRes = SQLiteDatastore.new(basePath, filename)
check:
dsRes.isOk
fileExists(dbPathAbs)
dsRes.get.close
# for `readOnly = true` to succeed the database file must already exist, so
# the existing file (per previous step) is not deleted prior to the next
# invocation of `SQLiteDatastore.new`
dsRes = SQLiteDatastore.new(basePath, filename, readOnly = true)
check: dsRes.isOk
dsRes.get.close
removeDir(basePathAbs)
assert not dirExists(basePathAbs)
createDir(basePathAbs)
dsRes = SQLiteDatastore.new(memory)
check: dsRes.isOk
dsRes.get.close
dsRes = SQLiteDatastore.new(memory, readOnly = true)
check: dsRes.isErr
asyncTest "accessors":
ds = SQLiteDatastore.new(basePath).get
check:
parentDir(ds.dbPath) == basePathAbs
not ds.env.isNil
asyncTest "helpers":
ds = SQLiteDatastore.new(basePath).get
ds.close
check:
ds.env.isNil
timestamp(10.123_456) == 10_123_456.int64
asyncTest "put":
let
key = Key.init("a:b/c/d:e").get
# for `readOnly = true` to succeed the database file must already exist
ds = SQLiteDatastore.new(basePathAbs, filename).get
ds.close
ds = SQLiteDatastore.new(basePathAbs, filename, readOnly = true).get
var
bytes: seq[byte]
timestamp = timestamp()
putRes = await ds.put(key, bytes, timestamp)
check: putRes.isErr
ds.close
removeDir(basePathAbs)
assert not dirExists(basePathAbs)
createDir(basePathAbs)
ds = SQLiteDatastore.new(basePathAbs, filename).get
timestamp = timestamp()
putRes = await ds.put(key, bytes, timestamp)
check: putRes.isOk
let
prequeryRes = NoParamsStmt.prepare(
ds.env, "SELECT timestamp AS foo, id AS baz, data AS bar FROM " &
tableName & ";")
assert prequeryRes.isOk
let
prequery = prequeryRes.get
idCol = idCol(RawStmtPtr(prequery), 1)
dataCol = dataCol(RawStmtPtr(prequery), 2)
timestampCol = timestampCol(RawStmtPtr(prequery), 0)
var
qId: string
qData: seq[byte]
qTimestamp: int64
rowCount = 0
proc onData(s: RawStmtPtr) {.closure.} =
qId = idCol()
qData = dataCol()
qTimestamp = timestampCol()
inc rowCount
var
qRes = prequery.query((), onData)
assert qRes.isOk
check:
qRes.get
qId == key.id
qData == bytes
qTimestamp == timestamp
rowCount == 1
bytes = @[1.byte, 2.byte, 3.byte]
timestamp = timestamp()
putRes = await ds.put(key, bytes, timestamp)
check: putRes.isOk
rowCount = 0
qRes = prequery.query((), onData)
assert qRes.isOk
check:
qRes.get
qId == key.id
qData == bytes
qTimestamp == timestamp
rowCount == 1
bytes = @[4.byte, 5.byte, 6.byte]
timestamp = timestamp()
putRes = await ds.put(key, bytes, timestamp)
check: putRes.isOk
rowCount = 0
qRes = prequery.query((), onData)
assert qRes.isOk
check:
qRes.get
qId == key.id
qData == bytes
qTimestamp == timestamp
rowCount == 1
prequery.dispose
asyncTest "delete":
let
bytes = @[1.byte, 2.byte, 3.byte]
var
key = Key.init("a:b/c/d:e").get
# for `readOnly = true` to succeed the database file must already exist
ds = SQLiteDatastore.new(basePathAbs, filename).get
ds.close
ds = SQLiteDatastore.new(basePathAbs, filename, readOnly = true).get
var
delRes = await ds.delete(key)
check: delRes.isErr
ds.close
removeDir(basePathAbs)
assert not dirExists(basePathAbs)
createDir(basePathAbs)
ds = SQLiteDatastore.new(basePathAbs, filename).get
let
putRes = await ds.put(key, bytes)
assert putRes.isOk
let
query = "SELECT * FROM " & tableName & ";"
var
rowCount = 0
proc onData(s: RawStmtPtr) {.closure.} =
inc rowCount
var
qRes = ds.env.query(query, onData)
assert qRes.isOk
check: rowCount == 1
delRes = await ds.delete(key)
check: delRes.isOk
rowCount = 0
qRes = ds.env.query(query, onData)
assert qRes.isOk
check:
delRes.isOk
rowCount == 0
key = Key.init("X/Y/Z").get
delRes = await ds.delete(key)
check: delRes.isOk
asyncTest "contains":
let
bytes = @[1.byte, 2.byte, 3.byte]
var
key = Key.init("a:b/c/d:e").get
ds = SQLiteDatastore.new(basePathAbs, filename).get
let
putRes = await ds.put(key, bytes)
assert putRes.isOk
var
containsRes = await ds.contains(key)
check:
containsRes.isOk
containsRes.get == true
key = Key.init("X/Y/Z").get
containsRes = await ds.contains(key)
check:
containsRes.isOk
containsRes.get == false
asyncTest "get":
ds = SQLiteDatastore.new(basePathAbs, filename).get
var
bytes: seq[byte]
key = Key.init("a:b/c/d:e").get
putRes = await ds.put(key, bytes)
assert putRes.isOk
var
getRes = await ds.get(key)
getOpt = getRes.get
check: getOpt.isSome and getOpt.get == bytes
bytes = @[1.byte, 2.byte, 3.byte]
putRes = await ds.put(key, bytes)
assert putRes.isOk
getRes = await ds.get(key)
getOpt = getRes.get
check: getOpt.isSome and getOpt.get == bytes
key = Key.init("X/Y/Z").get
assert not (await ds.contains(key)).get
getRes = await ds.get(key)
getOpt = getRes.get
check: getOpt.isNone
asyncTest "query":
ds = SQLiteDatastore.new(basePathAbs, filename).get
var
key1 = Key.init("a").get
key2 = Key.init("a/b").get
key3 = Key.init("a/b:c").get
key4 = Key.init("a:b").get
key5 = Key.init("a:b/c").get
key6 = Key.init("a:b/c:d").get
key7 = Key.init("A").get
key8 = Key.init("A/B").get
key9 = Key.init("A/B:C").get
key10 = Key.init("A:B").get
key11 = Key.init("A:B/C").get
key12 = Key.init("A:B/C:D").get
bytes1 = @[1.byte, 2.byte, 3.byte]
bytes2 = @[4.byte, 5.byte, 6.byte]
bytes3: seq[byte] = @[]
bytes4 = bytes1
bytes5 = bytes2
bytes6 = bytes3
bytes7 = bytes1
bytes8 = bytes2
bytes9 = bytes3
bytes10 = bytes1
bytes11 = bytes2
bytes12 = bytes3
queryKey = Key.init("*").get
var
putRes = await ds.put(key1, bytes1)
assert putRes.isOk
putRes = await ds.put(key2, bytes2)
assert putRes.isOk
putRes = await ds.put(key3, bytes3)
assert putRes.isOk
putRes = await ds.put(key4, bytes4)
assert putRes.isOk
putRes = await ds.put(key5, bytes5)
assert putRes.isOk
putRes = await ds.put(key6, bytes6)
assert putRes.isOk
putRes = await ds.put(key7, bytes7)
assert putRes.isOk
putRes = await ds.put(key8, bytes8)
assert putRes.isOk
putRes = await ds.put(key9, bytes9)
assert putRes.isOk
putRes = await ds.put(key10, bytes10)
assert putRes.isOk
putRes = await ds.put(key11, bytes11)
assert putRes.isOk
putRes = await ds.put(key12, bytes12)
assert putRes.isOk
var
kds: seq[QueryResponse]
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
# see https://sqlite.org/lang_select.html#the_order_by_clause
# If a SELECT statement that returns more than one row does not have an
# ORDER BY clause, the order in which the rows are returned is undefined.
check: kds.sortedByIt(it.key.id) == @[
(key: key1, data: bytes1),
(key: key2, data: bytes2),
(key: key3, data: bytes3),
(key: key4, data: bytes4),
(key: key5, data: bytes5),
(key: key6, data: bytes6),
(key: key7, data: bytes7),
(key: key8, data: bytes8),
(key: key9, data: bytes9),
(key: key10, data: bytes10),
(key: key11, data: bytes11),
(key: key12, data: bytes12)
].sortedByIt(it.key.id)
kds = @[]
queryKey = Key.init("a*").get
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
check: kds.sortedByIt(it.key.id) == @[
(key: key1, data: bytes1),
(key: key2, data: bytes2),
(key: key3, data: bytes3),
(key: key4, data: bytes4),
(key: key5, data: bytes5),
(key: key6, data: bytes6)
].sortedByIt(it.key.id)
kds = @[]
queryKey = Key.init("A*").get
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
check: kds.sortedByIt(it.key.id) == @[
(key: key7, data: bytes7),
(key: key8, data: bytes8),
(key: key9, data: bytes9),
(key: key10, data: bytes10),
(key: key11, data: bytes11),
(key: key12, data: bytes12)
].sortedByIt(it.key.id)
kds = @[]
queryKey = Key.init("a/?").get
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
check: kds.sortedByIt(it.key.id) == @[
(key: key2, data: bytes2)
].sortedByIt(it.key.id)
kds = @[]
queryKey = Key.init("A/?").get
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
check: kds.sortedByIt(it.key.id) == @[
(key: key8, data: bytes8)
].sortedByIt(it.key.id)
kds = @[]
queryKey = Key.init("*/?").get
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
check: kds.sortedByIt(it.key.id) == @[
(key: key2, data: bytes2),
(key: key5, data: bytes5),
(key: key8, data: bytes8),
(key: key11, data: bytes11)
].sortedByIt(it.key.id)
kds = @[]
queryKey = Key.init("[Aa]/?").get
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
check: kds.sortedByIt(it.key.id) == @[
(key: key2, data: bytes2),
(key: key8, data: bytes8)
].sortedByIt(it.key.id)
kds = @[]
# SQLite's GLOB operator, akin to Unix file globbing syntax, is greedy re:
# wildcard "*". So a pattern such as "a:*[^/]" will not restrict results to
# "/a:b", i.e. it will match on "/a:b", "/a:b/c" and "/a:b/c:d".
queryKey = Key.init("a:*[^/]").get
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
check: kds.sortedByIt(it.key.id) == @[
(key: key4, data: bytes4),
(key: key5, data: bytes5),
(key: key6, data: bytes6)
].sortedByIt(it.key.id)
kds = @[]
queryKey = Key.init("a:*[Bb]").get
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
check: kds.sortedByIt(it.key.id) == @[
(key: key4, data: bytes4)
].sortedByIt(it.key.id)
kds = @[]
var
deleteRes = await ds.delete(key1)
assert deleteRes.isOk
deleteRes = await ds.delete(key2)
assert deleteRes.isOk
deleteRes = await ds.delete(key3)
assert deleteRes.isOk
deleteRes = await ds.delete(key4)
assert deleteRes.isOk
deleteRes = await ds.delete(key5)
assert deleteRes.isOk
deleteRes = await ds.delete(key6)
assert deleteRes.isOk
deleteRes = await ds.delete(key7)
assert deleteRes.isOk
deleteRes = await ds.delete(key8)
assert deleteRes.isOk
deleteRes = await ds.delete(key9)
assert deleteRes.isOk
deleteRes = await ds.delete(key10)
assert deleteRes.isOk
deleteRes = await ds.delete(key11)
assert deleteRes.isOk
deleteRes = await ds.delete(key12)
assert deleteRes.isOk
let
emptyKds: seq[QueryResponse] = @[]
for kd in ds.query(Query.init(queryKey)):
let
(key, data) = await kd
kds.add (key, data)
check: kds == emptyKds