Giuliano Mega 92af582d97
fix: close pending iterators before closing LevelDB store (#83)
This adds tracking of open iterators to leveldbds so that when one attempts to close it, iterators are disposed of first. It also adds automatic disposal if iterators are completely consumed.

fixes #82
2026-02-06 16:24:11 -03:00

58 lines
1.4 KiB
Nim

{.push raises: [].}
import pkg/chronos
import pkg/questionable
import pkg/questionable/results
import ./key
import ./types
type
SortOrder* {.pure.} = enum
Assending,
Descending
Query* = object
key*: Key # 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
QueryResponse* = tuple[key: ?Key, data: seq[byte]]
QueryEndedError* = object of DatastoreError
GetNext* = proc(): Future[?!QueryResponse] {.async: (raises: [CancelledError]), gcsafe, closure.}
IterDispose* = proc(): Future[?!void] {.async: (raises: [CancelledError]), gcsafe.}
QueryIter* = ref object
finished*: bool
disposed*: bool
next*: GetNext
dispose*: IterDispose
iterator items*(q: QueryIter): Future[?!QueryResponse] =
while not q.finished:
yield q.next()
proc defaultDispose(): Future[?!void] {.gcsafe, async: (raises: [CancelledError]).} =
return success()
proc new*(T: type QueryIter, dispose = defaultDispose): T =
QueryIter(dispose: dispose)
proc init*(
T: type Query,
key: Key,
value = true,
sort = SortOrder.Assending,
offset = 0,
limit = -1): T =
T(
key: key,
value: value,
sort: sort,
offset: offset,
limit: limit)