Handles trailing wildcards in leveldb query.

This commit is contained in:
Ben 2024-05-21 10:26:56 +02:00
parent fc5a6551da
commit cdbb80d9de
No known key found for this signature in database
GPG Key ID: 541B9D8C9F1426A1
2 changed files with 81 additions and 1 deletions

View File

@ -4,6 +4,7 @@ import std/options
import std/tables
import std/os
import std/strformat
import std/strutils
import pkg/leveldbstatic
import pkg/chronos
@ -74,6 +75,13 @@ method close*(self: LevelDbDatastore): Future[?!void] {.async.} =
except LevelDbException as e:
return failure("LevelDbDatastore.close exception: " & $e.msg)
proc getQueryString(query: Query): string =
result = $(query.key)
let toTrim = ["/*", "\\*"]
for trim in toTrim:
if result.endswith(trim):
result = result.replace(trim, "")
method query*(
self: LevelDbDatastore,
query: Query): Future[?!QueryIter] {.async, gcsafe.} =
@ -84,7 +92,7 @@ method query*(
var
iter = QueryIter()
dbIter = self.db.queryIter(
prefix = $(query.key),
prefix = getQueryString(query),
keysOnly = not query.value,
skip = query.offset,
limit = query.limit

View File

@ -60,3 +60,75 @@ suite "Test LevelDB Typed Query":
(await ds.close()).tryGet
typedDsQueryTests(ds)
suite "LevelDB Query: keys should disregard trailing wildcards":
let tempDir = getTempDir() / "testleveldbds"
var
ds: LevelDbDatastore
key1: Key
key2: Key
key3: Key
val1: seq[byte]
val2: seq[byte]
val3: seq[byte]
setupAll:
key1 = Key.init("/a").tryGet
key2 = Key.init("/a/b").tryGet
key3 = Key.init("/a/b/c").tryGet
val1 = "value for 1".toBytes
val2 = "value for 2".toBytes
val3 = "value for 3".toBytes
setup:
createdir(tempDir)
ds = LevelDbDatastore.new(tempDir).tryGet()
(await ds.put(key1, val1)).tryGet
(await ds.put(key2, val2)).tryGet
(await ds.put(key3, val3)).tryGet
teardown:
(await ds.close()).tryGet
removeDir(tempDir)
test "Forward":
let
q = Query.init(Key.init("/a/*").tryGet)
iter = (await ds.query(q)).tryGet
res = (await allFinished(toSeq(iter)))
.mapIt( it.read.tryGet )
.filterIt( it.key.isSome )
check:
res.len == 3
res[0].key.get == key1
res[0].data == val1
res[1].key.get == key2
res[1].data == val2
res[2].key.get == key3
res[2].data == val3
(await iter.dispose()).tryGet
test "Backwards":
let
q = Query.init(Key.init("/a\\*").tryGet)
iter = (await ds.query(q)).tryGet
res = (await allFinished(toSeq(iter)))
.mapIt( it.read.tryGet )
.filterIt( it.key.isSome )
check:
res.len == 3
res[0].key.get == key1
res[0].data == val1
res[1].key.get == key2
res[1].data == val2
res[2].key.get == key3
res[2].data == val3
(await iter.dispose()).tryGet