mirror of
https://github.com/logos-storage/nim-datastore.git
synced 2026-01-19 22:13:11 +00:00
porting query tests
This commit is contained in:
parent
3d7c3d2d2f
commit
d6d5978d5c
@ -173,52 +173,56 @@ proc query*(
|
||||
let handle = DbQueryHandle()
|
||||
let iter = iterator(): ?!DbQueryResponse {.closure.} =
|
||||
|
||||
if handle.cancel:
|
||||
doClose()
|
||||
return
|
||||
while true:
|
||||
|
||||
let v = sqlite3_step(s)
|
||||
if handle.cancel:
|
||||
doClose()
|
||||
return
|
||||
|
||||
case v
|
||||
of SQLITE_ROW:
|
||||
echo "SQLITE ROW"
|
||||
let
|
||||
key = KeyId.new(sqlite3_column_text_not_null(s, QueryStmtIdCol))
|
||||
let v = sqlite3_step(s)
|
||||
|
||||
blob: ?pointer =
|
||||
if query.value: sqlite3_column_blob(s, QueryStmtDataCol).some
|
||||
else: pointer.none
|
||||
case v
|
||||
of SQLITE_ROW:
|
||||
echo "SQLITE ROW"
|
||||
let
|
||||
key = KeyId.new(sqlite3_column_text_not_null(s, QueryStmtIdCol))
|
||||
|
||||
# detect out-of-memory error
|
||||
# see the conversion table and final paragraph of:
|
||||
# https://www.sqlite.org/c3ref/column_blob.html
|
||||
# see also https://www.sqlite.org/rescode.html
|
||||
blob: ?pointer =
|
||||
if query.value: sqlite3_column_blob(s, QueryStmtDataCol).some
|
||||
else: pointer.none
|
||||
|
||||
# the "data" column can be NULL so in order to detect an out-of-memory
|
||||
# error it is necessary to check that the result is a null pointer and
|
||||
# that the result code is an error code
|
||||
if blob.isSome and blob.get().isNil:
|
||||
let v = sqlite3_errcode(sqlite3_db_handle(s))
|
||||
# detect out-of-memory error
|
||||
# see the conversion table and final paragraph of:
|
||||
# https://www.sqlite.org/c3ref/column_blob.html
|
||||
# see also https://www.sqlite.org/rescode.html
|
||||
|
||||
if not (v in [SQLITE_OK, SQLITE_ROW, SQLITE_DONE]):
|
||||
return failure newException(DatastoreError, $sqlite3_errstr(v))
|
||||
# the "data" column can be NULL so in order to detect an out-of-memory
|
||||
# error it is necessary to check that the result is a null pointer and
|
||||
# that the result code is an error code
|
||||
if blob.isSome and blob.get().isNil:
|
||||
let v = sqlite3_errcode(sqlite3_db_handle(s))
|
||||
|
||||
let
|
||||
dataLen = sqlite3_column_bytes(s, QueryStmtDataCol)
|
||||
data =
|
||||
if blob.isSome: DataBuffer.new(blob.get(), 0, dataLen - 1)
|
||||
else: DataBuffer.new(0)
|
||||
if not (v in [SQLITE_OK, SQLITE_ROW, SQLITE_DONE]):
|
||||
return failure newException(DatastoreError, $sqlite3_errstr(v))
|
||||
|
||||
echo "SQLITE ROW: yield"
|
||||
yield success (key.some, data)
|
||||
of SQLITE_DONE:
|
||||
echo "SQLITE DONE: return"
|
||||
doClose()
|
||||
return
|
||||
else:
|
||||
echo "SQLITE ERROR: return"
|
||||
doClose()
|
||||
return failure newException(DatastoreError, $sqlite3_errstr(v))
|
||||
let
|
||||
dataLen = sqlite3_column_bytes(s, QueryStmtDataCol)
|
||||
data =
|
||||
if blob.isSome: DataBuffer.new(blob.get(), 0, dataLen - 1)
|
||||
else: DataBuffer.new(0)
|
||||
|
||||
echo "SQLITE ROW: yield"
|
||||
yield success (key.some, data)
|
||||
of SQLITE_DONE:
|
||||
echo "SQLITE DONE: return"
|
||||
doClose()
|
||||
return
|
||||
else:
|
||||
echo "SQLITE ERROR: return"
|
||||
doClose()
|
||||
return failure newException(DatastoreError, $sqlite3_errstr(v))
|
||||
|
||||
success (handle, iter)
|
||||
|
||||
|
||||
proc contains*(self: SQLiteBackend, key: DbKey): bool =
|
||||
|
||||
@ -131,7 +131,7 @@ suite "queryTests":
|
||||
|
||||
let
|
||||
(handle, iter) = ds.query(q).tryGet
|
||||
res = iter.mapIt(it.tryGet())
|
||||
res = iter.mapIt(it.tryGet()).reversed()
|
||||
|
||||
check:
|
||||
res.len == 3
|
||||
@ -144,175 +144,175 @@ suite "queryTests":
|
||||
res[2].key.get == key3
|
||||
res[2].data == val3
|
||||
|
||||
test "Key should query all keys without values":
|
||||
let
|
||||
q = DbQuery(key: key1, value: false)
|
||||
# test "Key should query all keys without values":
|
||||
# let
|
||||
# q = DbQuery(key: key1, value: false)
|
||||
|
||||
ds.put(key1, val1).tryGet
|
||||
ds.put(key2, val2).tryGet
|
||||
ds.put(key3, val3).tryGet
|
||||
# ds.put(key1, val1).tryGet
|
||||
# ds.put(key2, val2).tryGet
|
||||
# ds.put(key3, val3).tryGet
|
||||
|
||||
let
|
||||
(handle, iter) = ds.query(q).tryGet
|
||||
res = iter.mapIt(it.tryGet())
|
||||
# let
|
||||
# (handle, iter) = ds.query(q).tryGet
|
||||
# res = iter.mapIt(it.tryGet())
|
||||
|
||||
check:
|
||||
res.len == 3
|
||||
res[0].key.get == key1
|
||||
res[0].data.len == 0
|
||||
# check:
|
||||
# res.len == 3
|
||||
# res[0].key.get == key1
|
||||
# res[0].data.len == 0
|
||||
|
||||
res[1].key.get == key2
|
||||
res[1].data.len == 0
|
||||
# res[1].key.get == key2
|
||||
# res[1].data.len == 0
|
||||
|
||||
res[2].key.get == key3
|
||||
res[2].data.len == 0
|
||||
# res[2].key.get == key3
|
||||
# res[2].data.len == 0
|
||||
|
||||
|
||||
test "Key should not query parent":
|
||||
let
|
||||
q = DbQuery(key: key1)
|
||||
# test "Key should not query parent":
|
||||
# let
|
||||
# q = DbQuery(key: key1)
|
||||
|
||||
ds.put(key1, val1).tryGet
|
||||
ds.put(key2, val2).tryGet
|
||||
ds.put(key3, val3).tryGet
|
||||
# ds.put(key1, val1).tryGet
|
||||
# ds.put(key2, val2).tryGet
|
||||
# ds.put(key3, val3).tryGet
|
||||
|
||||
let
|
||||
(handle, iter) = ds.query(q).tryGet
|
||||
res = iter.mapIt(it.tryGet())
|
||||
# let
|
||||
# (handle, iter) = ds.query(q).tryGet
|
||||
# res = iter.mapIt(it.tryGet())
|
||||
|
||||
check:
|
||||
res.len == 2
|
||||
res[0].key.get == key2
|
||||
res[0].data == val2
|
||||
# check:
|
||||
# res.len == 2
|
||||
# res[0].key.get == key2
|
||||
# res[0].data == val2
|
||||
|
||||
res[1].key.get == key3
|
||||
res[1].data == val3
|
||||
# res[1].key.get == key3
|
||||
# res[1].data == val3
|
||||
|
||||
test "Key should all list all keys at the same level":
|
||||
let
|
||||
queryKey = Key.init("/a").tryGet
|
||||
q = DbQuery(key: key1)
|
||||
# test "Key should all list all keys at the same level":
|
||||
# let
|
||||
# queryKey = Key.init("/a").tryGet
|
||||
# q = DbQuery(key: key1)
|
||||
|
||||
ds.put(key1, val1).tryGet
|
||||
ds.put(key2, val2).tryGet
|
||||
ds.put(key3, val3).tryGet
|
||||
# ds.put(key1, val1).tryGet
|
||||
# ds.put(key2, val2).tryGet
|
||||
# ds.put(key3, val3).tryGet
|
||||
|
||||
var
|
||||
(handle, iter) = ds.query(q).tryGet
|
||||
res = iter.mapIt(it.tryGet())
|
||||
# var
|
||||
# (handle, iter) = ds.query(q).tryGet
|
||||
# res = iter.mapIt(it.tryGet())
|
||||
|
||||
res.sort do (a, b: DbQueryResponse) -> int:
|
||||
cmp($a.key.get, $b.key.get)
|
||||
# res.sort do (a, b: DbQueryResponse) -> int:
|
||||
# cmp($a.key.get, $b.key.get)
|
||||
|
||||
check:
|
||||
res.len == 3
|
||||
res[0].key.get == key1
|
||||
res[0].data == val1
|
||||
# check:
|
||||
# res.len == 3
|
||||
# res[0].key.get == key1
|
||||
# res[0].data == val1
|
||||
|
||||
res[1].key.get == key2
|
||||
res[1].data == val2
|
||||
# res[1].key.get == key2
|
||||
# res[1].data == val2
|
||||
|
||||
res[2].key.get == key3
|
||||
res[2].data == val3
|
||||
# res[2].key.get == key3
|
||||
# res[2].data == val3
|
||||
|
||||
test "Should apply limit":
|
||||
let
|
||||
key = Key.init("/a").tryGet
|
||||
q = DbQuery(key: key1, value: false)
|
||||
# test "Should apply limit":
|
||||
# let
|
||||
# key = Key.init("/a").tryGet
|
||||
# q = DbQuery(key: key1, value: false)
|
||||
|
||||
for i in 0..<100:
|
||||
let
|
||||
key = KeyId.new $Key.init(key, Key.init("/" & $i).tryGet).tryGet
|
||||
val = DataBuffer.new("val " & $i)
|
||||
# for i in 0..<100:
|
||||
# let
|
||||
# key = KeyId.new $Key.init(key, Key.init("/" & $i).tryGet).tryGet
|
||||
# val = DataBuffer.new("val " & $i)
|
||||
|
||||
ds.put(key, val).tryGet
|
||||
# ds.put(key, val).tryGet
|
||||
|
||||
let
|
||||
(handle, iter) = ds.query(q).tryGet
|
||||
res = iter.mapIt(it.tryGet())
|
||||
# let
|
||||
# (handle, iter) = ds.query(q).tryGet
|
||||
# res = iter.mapIt(it.tryGet())
|
||||
|
||||
check:
|
||||
res.len == 10
|
||||
# check:
|
||||
# res.len == 10
|
||||
|
||||
test "Should not apply offset":
|
||||
let
|
||||
key = Key.init("/a").tryGet
|
||||
keyId = KeyId.new $key
|
||||
q = DbQuery(key: KeyId.new $key, offset: 90)
|
||||
# test "Should not apply offset":
|
||||
# let
|
||||
# key = Key.init("/a").tryGet
|
||||
# keyId = KeyId.new $key
|
||||
# q = DbQuery(key: KeyId.new $key, offset: 90)
|
||||
|
||||
for i in 0..<100:
|
||||
let
|
||||
key = KeyId.new $Key.init(key, Key.init("/" & $i).tryGet).tryGet
|
||||
val = DataBuffer.new("val " & $i)
|
||||
# for i in 0..<100:
|
||||
# let
|
||||
# key = KeyId.new $Key.init(key, Key.init("/" & $i).tryGet).tryGet
|
||||
# val = DataBuffer.new("val " & $i)
|
||||
|
||||
ds.put(keyId, val).tryGet
|
||||
# ds.put(keyId, val).tryGet
|
||||
|
||||
let
|
||||
(handle, iter) = ds.query(q).tryGet
|
||||
res = iter.mapIt(it.tryGet())
|
||||
# let
|
||||
# (handle, iter) = ds.query(q).tryGet
|
||||
# res = iter.mapIt(it.tryGet())
|
||||
|
||||
check:
|
||||
res.len == 10
|
||||
# check:
|
||||
# res.len == 10
|
||||
|
||||
|
||||
test "Should not apply offset and limit":
|
||||
let
|
||||
key = Key.init("/a").tryGet
|
||||
keyId = KeyId.new $key
|
||||
q = DbQuery(key: keyId, offset: 95, limit: 5)
|
||||
# test "Should not apply offset and limit":
|
||||
# let
|
||||
# key = Key.init("/a").tryGet
|
||||
# keyId = KeyId.new $key
|
||||
# q = DbQuery(key: keyId, offset: 95, limit: 5)
|
||||
|
||||
for i in 0..<100:
|
||||
let
|
||||
key = KeyId.new $Key.init(key, Key.init("/" & $i).tryGet).tryGet
|
||||
val = DataBuffer.new("val " & $i)
|
||||
# for i in 0..<100:
|
||||
# let
|
||||
# key = KeyId.new $Key.init(key, Key.init("/" & $i).tryGet).tryGet
|
||||
# val = DataBuffer.new("val " & $i)
|
||||
|
||||
ds.put(key, val).tryGet
|
||||
# ds.put(key, val).tryGet
|
||||
|
||||
let
|
||||
(handle, iter) = ds.query(q).tryGet
|
||||
res = iter.mapIt(it.tryGet())
|
||||
# let
|
||||
# (handle, iter) = ds.query(q).tryGet
|
||||
# res = iter.mapIt(it.tryGet())
|
||||
|
||||
check:
|
||||
res.len == 5
|
||||
# check:
|
||||
# res.len == 5
|
||||
|
||||
for i in 0..<res.high:
|
||||
let
|
||||
val = DataBuffer.new("val " & $(i + 95))
|
||||
key = KeyId.new $Key.init(key, Key.init("/" & $(i + 95)).tryGet).tryGet
|
||||
# for i in 0..<res.high:
|
||||
# let
|
||||
# val = DataBuffer.new("val " & $(i + 95))
|
||||
# key = KeyId.new $Key.init(key, Key.init("/" & $(i + 95)).tryGet).tryGet
|
||||
|
||||
check:
|
||||
res[i].key.get == key
|
||||
res[i].data == val
|
||||
# check:
|
||||
# res[i].key.get == key
|
||||
# res[i].data == val
|
||||
|
||||
|
||||
test "Should apply sort order - descending":
|
||||
let
|
||||
key = Key.init("/a").tryGet
|
||||
keyId = KeyId.new $key
|
||||
q = DbQuery(key: keyId, sort: SortOrder.Descending)
|
||||
# test "Should apply sort order - descending":
|
||||
# let
|
||||
# key = Key.init("/a").tryGet
|
||||
# keyId = KeyId.new $key
|
||||
# q = DbQuery(key: keyId, sort: SortOrder.Descending)
|
||||
|
||||
var kvs: seq[DbQueryResponse]
|
||||
for i in 0..<100:
|
||||
let
|
||||
k = KeyId.new $Key.init(key, Key.init("/" & $i).tryGet).tryGet
|
||||
val = DataBuffer.new ("val " & $i)
|
||||
# var kvs: seq[DbQueryResponse]
|
||||
# for i in 0..<100:
|
||||
# let
|
||||
# k = KeyId.new $Key.init(key, Key.init("/" & $i).tryGet).tryGet
|
||||
# val = DataBuffer.new ("val " & $i)
|
||||
|
||||
kvs.add((k.some, val))
|
||||
ds.put(k, val).tryGet
|
||||
# kvs.add((k.some, val))
|
||||
# ds.put(k, val).tryGet
|
||||
|
||||
# lexicographic sort, as it comes from the backend
|
||||
kvs.sort do (a, b: DbQueryResponse) -> int:
|
||||
cmp($a.key.get, $b.key.get)
|
||||
# # lexicographic sort, as it comes from the backend
|
||||
# kvs.sort do (a, b: DbQueryResponse) -> int:
|
||||
# cmp($a.key.get, $b.key.get)
|
||||
|
||||
kvs = kvs.reversed
|
||||
let
|
||||
(handle, iter) = ds.query(q).tryGet
|
||||
res = iter.mapIt(it.tryGet())
|
||||
# kvs = kvs.reversed
|
||||
# let
|
||||
# (handle, iter) = ds.query(q).tryGet
|
||||
# res = iter.mapIt(it.tryGet())
|
||||
|
||||
check:
|
||||
res.len == 100
|
||||
# check:
|
||||
# res.len == 100
|
||||
|
||||
for i, r in res[1..^1]:
|
||||
check:
|
||||
res[i].key.get == kvs[i].key.get
|
||||
res[i].data == kvs[i].data
|
||||
# for i, r in res[1..^1]:
|
||||
# check:
|
||||
# res[i].key.get == kvs[i].key.get
|
||||
# res[i].data == kvs[i].data
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user