From 92dcbf70ae017170e82e1d1d36cb4a83be10f309 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 25 Sep 2023 17:49:17 -0700 Subject: [PATCH] change to non-closure iterator --- datastore/backend.nim | 13 ++++++++----- datastore/sql/sqliteds.nim | 18 +++++++++--------- tests/datastore/sql/testsqliteds.nim | 19 +++++++++++-------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/datastore/backend.nim b/datastore/backend.nim index c213456..80204cf 100644 --- a/datastore/backend.nim +++ b/datastore/backend.nim @@ -20,17 +20,17 @@ type DbKey* = string | KeyId DbVal* = seq[byte] | DataBuffer - DbBatchEntry* = tuple[key: string, data: seq[byte]] | tuple[key: KeyId, data: DataBuffer] + DbBatchEntry*[K, V] = tuple[key: K, data: V] - DbQuery* = object - key*: KeyId # Key to be queried + DbQuery*[K] = object + key*: K # Key to be queried value*: bool # Flag to indicate if data should be returned limit*: int # Max items to return - not available in all backends offset*: int # Offset from which to start querying - not available in all backends sort*: SortOrder # Sort order - not available in all backends - DbQueryHandle*[T] = object - query*: DbQuery + DbQueryHandle*[K, T] = object + query*: DbQuery[K] cancel*: bool closed*: bool env*: T @@ -39,6 +39,9 @@ type proc `$`*(id: KeyId): string = $(id.data) +proc toKey*(tp: typedesc[KeyId], id: cstring): KeyId = KeyId.new(id) +proc toKey*(tp: typedesc[string], id: cstring): string = $(id) + proc new*(tp: typedesc[KeyId], id: cstring): KeyId = ## copy cstring including null terminator KeyId(data: DataBuffer.new(id.toOpenArray(0, id.len()-1))) diff --git a/datastore/sql/sqliteds.nim b/datastore/sql/sqliteds.nim index 0494097..0f763d1 100644 --- a/datastore/sql/sqliteds.nim +++ b/datastore/sql/sqliteds.nim @@ -39,7 +39,7 @@ proc has*[K,V](self: SQLiteBackend[K,V], key: DbKey): ?!bool = return success exists -proc delete*[K,V](self: SQLiteBackend[K,V], key: DbKey): ?!void = +proc delete*[K,V](self: SQLiteBackend[K,V], key: K): ?!void = return self.db.deleteStmt.exec((key)) proc delete*[K,V](self: SQLiteBackend[K,V], keys: openArray[DbKey]): ?!void = @@ -58,7 +58,7 @@ proc delete*[K,V](self: SQLiteBackend[K,V], keys: openArray[DbKey]): ?!void = return success() -proc get*[K,V](self: SQLiteBackend[K,V], key: KeyId): ?!seq[byte] = +proc get*[K,V](self: SQLiteBackend[K,V], key: K): ?!seq[byte] = # see comment in ./filesystem_datastore re: finer control of memory # allocation in `proc get`, could apply here as well if bytes were read # incrementally with `sqlite3_blob_read` @@ -78,7 +78,7 @@ proc get*[K,V](self: SQLiteBackend[K,V], key: KeyId): ?!seq[byte] = return success bytes -proc put*[K,V](self: SQLiteBackend[K,V], key: KeyId, data: DataBuffer): ?!void = +proc put*[K,V](self: SQLiteBackend[K,V], key: K, data: V): ?!void = return self.db.putStmt.exec((key, data, timestamp())) proc put*[K,V](self: SQLiteBackend[K,V], batch: openArray[DbBatchEntry]): ?!void = @@ -106,7 +106,7 @@ proc close*[K,V](self: SQLiteBackend[K,V]): ?!void = proc query*[K,V]( self: SQLiteBackend[K,V], query: DbQuery -): Result[DbQueryHandle[RawStmtPtr], ref CatchableError] = +): Result[DbQueryHandle[K, RawStmtPtr], ref CatchableError] = var queryStr = if query.value: @@ -151,16 +151,16 @@ proc query*[K,V]( if not (v == SQLITE_OK): return failure newException(DatastoreError, $sqlite3_errstr(v)) - success DbQueryHandle[RawStmtPtr](query: query, env: s) + success DbQueryHandle[K, RawStmtPtr](query: query, env: s) -proc close*(handle: var DbQueryHandle[RawStmtPtr]) = +proc close*[K](handle: var DbQueryHandle[K, RawStmtPtr]) = if not handle.closed: handle.closed = true discard sqlite3_reset(handle.env) discard sqlite3_clear_bindings(handle.env) handle.env.dispose() -iterator iter*(handle: var DbQueryHandle[RawStmtPtr]): ?!DbQueryResponse = +iterator iter*[K](handle: var DbQueryHandle[K, RawStmtPtr]): ?!DbQueryResponse = while not handle.cancel: let v = sqlite3_step(handle.env) @@ -168,7 +168,7 @@ iterator iter*(handle: var DbQueryHandle[RawStmtPtr]): ?!DbQueryResponse = case v of SQLITE_ROW: let - key = KeyId.new(sqlite3_column_text_not_null(handle.env, QueryStmtIdCol)) + key = K.toKey(sqlite3_column_text_not_null(handle.env, QueryStmtIdCol)) blob: ?pointer = if handle.query.value: sqlite3_column_blob(handle.env, QueryStmtDataCol).some @@ -222,7 +222,7 @@ proc newSQLiteBackend*[K,V]( if readOnly: SQLITE_OPEN_READONLY else: SQLITE_OPEN_READWRITE or SQLITE_OPEN_CREATE - success SQLiteBackend[K,V](db: ? SQLiteDsDb[KeyId,DataBuffer].open(path, flags)) + success SQLiteBackend[K,V](db: ? SQLiteDsDb[K,V].open(path, flags)) proc newSQLiteBackend*[K,V]( diff --git a/tests/datastore/sql/testsqliteds.nim b/tests/datastore/sql/testsqliteds.nim index dd931fd..c8767d5 100644 --- a/tests/datastore/sql/testsqliteds.nim +++ b/tests/datastore/sql/testsqliteds.nim @@ -14,12 +14,12 @@ import pkg/datastore/key import ../dscommontests import ../querycommontests -proc testBasic[K, V, B]( - ds: SQLiteBackend, +proc testBasic[K, V]( + ds: SQLiteBackend[K,V], key: K, bytes: V, otherBytes: V, - batch: B, + batch: seq[DbBatchEntry[K, V]], ) = test "put": @@ -60,14 +60,17 @@ proc testBasic[K, V, B]( check: not ds.has(k).tryGet test "handle missing key": - let key = KeyId.new Key.init("/missing/key").tryGet().id() + when K is KeyId: + let key = KeyId.new Key.init("/missing/key").tryGet().id() + elif K is string: + let key = $KeyId.new Key.init("/missing/key").tryGet().id() expect(DatastoreKeyNotFound): discard ds.get(key).tryGet() # non existing key suite "Test Basic SQLiteDatastore": let - ds = newSQLiteBackend[KeyId, DataBuffer](path=Memory).tryGet() + ds = newSQLiteBackend[string, seq[byte]](path=Memory).tryGet() keyFull = Key.init("a:b/c/d:e").tryGet() key = keyFull.id() bytes = "some bytes".toBytes @@ -81,7 +84,7 @@ suite "Test Basic SQLiteDatastore": suiteTeardown: ds.close().tryGet() - # testBasic(ds, key, bytes, otherBytes, batch) + testBasic(ds, key, bytes, otherBytes, batch) suite "Test DataBuffer SQLiteDatastore": let @@ -123,7 +126,7 @@ suite "queryTests": test "Key should query all keys and all it's children": let - q = DbQuery(key: key1, value: true) + q = DbQuery[KeyId](key: key1, value: true) ds.put(key1, val1).tryGet ds.put(key2, val2).tryGet @@ -146,7 +149,7 @@ suite "queryTests": test "query should cancel": let - q = DbQuery(key: key1, value: true) + q = DbQuery[KeyId](key: key1, value: true) ds.put(key1, val1).tryGet ds.put(key2, val2).tryGet