From cdbb80d9de626ca41c924d70a0dda2742414d2a1 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 21 May 2024 10:26:56 +0200 Subject: [PATCH] Handles trailing wildcards in leveldb query. --- datastore/leveldb/leveldbds.nim | 10 +++- tests/datastore/leveldb/testleveldbds.nim | 72 +++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/datastore/leveldb/leveldbds.nim b/datastore/leveldb/leveldbds.nim index 3d49026..11c0882 100644 --- a/datastore/leveldb/leveldbds.nim +++ b/datastore/leveldb/leveldbds.nim @@ -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 diff --git a/tests/datastore/leveldb/testleveldbds.nim b/tests/datastore/leveldb/testleveldbds.nim index b059880..6e7921c 100644 --- a/tests/datastore/leveldb/testleveldbds.nim +++ b/tests/datastore/leveldb/testleveldbds.nim @@ -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