Skip to content
Closed
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
345 commits
Select commit Hold shift + click to select a range
64434b7
stylechecks workaround
elcritch Aug 30, 2023
da83b04
remove stylechecks workaround
elcritch Aug 30, 2023
a95cd9c
bump required nim version
elcritch Aug 30, 2023
b1a5b9c
implementing query type
elcritch Aug 30, 2023
52286b8
query iterator using items is breaks when the DS isn't blocking
elcritch Aug 30, 2023
ed508b4
query iterator using items is breaks when the DS isn't blocking
elcritch Aug 30, 2023
9b004cd
query iterator using items is breaks when the DS isn't blocking
elcritch Aug 30, 2023
8fccc77
query iterator using items is breaks when the DS isn't blocking
elcritch Aug 30, 2023
3a9ee98
query iterator using items is breaks when the DS isn't blocking
elcritch Aug 30, 2023
221d193
query iterator using items is breaks when the DS isn't blocking
elcritch Aug 30, 2023
2d2b663
compiler really doesn't like this
elcritch Aug 30, 2023
1f00125
fix compiler issue -- wasn't detecting discard on result correctly
elcritch Aug 30, 2023
0caa606
fix test
elcritch Aug 31, 2023
619d3e9
add tests for new ds'es
elcritch Aug 31, 2023
24ce85e
add tests for new ds'es
elcritch Aug 31, 2023
f2bfe7a
add tests for new ds'es
elcritch Aug 31, 2023
2a04a36
add tests for new ds'es
elcritch Aug 31, 2023
1760ae2
set manual version of chronos
elcritch Aug 31, 2023
e84ccb2
add taskpools
elcritch Aug 31, 2023
6c3b0d6
fix unitest2 import
dryajov Sep 7, 2023
146cbcb
wip
dryajov Sep 8, 2023
b7454d6
foreign buffer
dryajov Sep 11, 2023
9bbf3ed
use shared table
dryajov Sep 12, 2023
13e89bc
adding semaphore for async backpresure
dryajov Sep 12, 2023
184420c
re-adding databuf
dryajov Sep 12, 2023
5adc7c9
this would never work
dryajov Sep 12, 2023
4c48383
reworked with less copying
dryajov Sep 12, 2023
2829ac8
remove useless async annotation
dryajov Sep 12, 2023
d6c4d97
add $ operator
dryajov Sep 13, 2023
19954c6
quick and dirty query
dryajov Sep 13, 2023
776c58f
re-added query and added raises (do they work?)
dryajov Sep 13, 2023
7a9bc11
make concurrent (but don't need anymore)
dryajov Sep 13, 2023
6a3882f
reverted query back (it works as is)
dryajov Sep 13, 2023
88eb96e
don't use toSeq
dryajov Sep 13, 2023
6c86d2b
make sure all tests pass
dryajov Sep 13, 2023
f003812
remove asyncsemaphore
dryajov Sep 14, 2023
af31030
enable sqllite threading tests
dryajov Sep 14, 2023
3500913
adding semaphore
dryajov Sep 14, 2023
221e93f
remove asyncsemaphore
dryajov Sep 15, 2023
e39bd53
wip
dryajov Sep 15, 2023
812b4fd
use foreach iterator
dryajov Sep 15, 2023
6d5c471
add sqlite query tests
dryajov Sep 15, 2023
a96de2c
fix
dryajov Sep 15, 2023
59f1f0b
add semaphore tests
dryajov Sep 15, 2023
25678b2
change iter constructore back to new
dryajov Sep 15, 2023
a17e9fe
remove memdb (not needed)
dryajov Sep 15, 2023
b2cb1fd
remove memdb tests
dryajov Sep 15, 2023
0fde28a
move assert into lock
dryajov Sep 15, 2023
71c704f
adding todo
dryajov Sep 15, 2023
600dca6
adding serialization to query iter
dryajov Sep 15, 2023
783ecc3
fix databuffer tests
dryajov Sep 15, 2023
7f6d95b
adding databuffer tests
dryajov Sep 15, 2023
20d7234
re-enable missing key check
dryajov Sep 15, 2023
1713c76
adding back async semaphore
dryajov Sep 15, 2023
d151c01
enable cancellations
dryajov Sep 15, 2023
9e27eec
adding chronicles and generating lock file
dryajov Sep 15, 2023
f6acaa6
add async semaphore tests
dryajov Sep 15, 2023
bee79ff
added (ugly!) locking capabilities
dryajov Sep 15, 2023
84681cd
make all tests pass
dryajov Sep 15, 2023
f849c1c
re-export threaded datastore
dryajov Sep 15, 2023
52d6a85
fixing dumb error in trace
dryajov Sep 15, 2023
7306a0b
simplify locking
dryajov Sep 18, 2023
ed09b9c
re-enable tests
dryajov Sep 18, 2023
75fa37f
avoid duplicating code
dryajov Sep 18, 2023
2c5186e
use baseAddr
dryajov Sep 18, 2023
d5a1b34
remove ptr to Datastore in TaskCtx, it's a ref
dryajov Sep 19, 2023
3d33820
change logscope
dryajov Sep 20, 2023
0beb3d3
handle error passing and conversion better
dryajov Sep 20, 2023
bb304a2
fix broken key not found test
dryajov Sep 20, 2023
181168d
fix tired ds
dryajov Sep 20, 2023
14f8c3a
check for nil ctx and set iter.finished correctly
dryajov Sep 20, 2023
7ceccf9
get rid of unsafeAddr everywhere
dryajov Sep 20, 2023
2eb120b
make path threadvar
dryajov Sep 20, 2023
81372c9
duh
dryajov Sep 20, 2023
3d84781
copy data and keys to thread local gc
dryajov Sep 20, 2023
9013a0c
GC_fullcollect() in tests to check mem consistency
dryajov Sep 20, 2023
215d334
avoid segfault on fullcollect
dryajov Sep 20, 2023
84bbfa6
refactor sqliteds
elcritch Sep 21, 2023
ea3546f
refactor sqliteds
elcritch Sep 21, 2023
1833155
add key/value
elcritch Sep 21, 2023
f7a933a
openArray
elcritch Sep 21, 2023
77efc50
openArray
elcritch Sep 21, 2023
1627e4d
add null tests
elcritch Sep 21, 2023
b388d24
openArray compare
elcritch Sep 21, 2023
29ff227
databuffer type
elcritch Sep 21, 2023
ab5f8da
databuffer type
elcritch Sep 21, 2023
8b4f388
databuffer type
elcritch Sep 21, 2023
8800a2c
databuffer type
elcritch Sep 21, 2023
10d4031
refactoring to non-async
elcritch Sep 21, 2023
5752eb0
refactoring to non-async
elcritch Sep 21, 2023
357ab44
refactoring to non-async
elcritch Sep 21, 2023
61bdc6b
fix test
elcritch Sep 21, 2023
3b66afb
fix test
elcritch Sep 21, 2023
d35bbea
fix test
elcritch Sep 21, 2023
9362fcb
fix test
elcritch Sep 21, 2023
8b49490
fix test
elcritch Sep 21, 2023
76b952c
fix test
elcritch Sep 21, 2023
cf2cbd3
fix test
elcritch Sep 21, 2023
937e1b7
test generic
elcritch Sep 21, 2023
8c71655
add index
elcritch Sep 21, 2023
4d26f70
key batch
elcritch Sep 21, 2023
398342b
key batch
elcritch Sep 21, 2023
9243b6b
key batch
elcritch Sep 21, 2023
8fe5e3d
key batch
elcritch Sep 21, 2023
d165ff2
tests
elcritch Sep 21, 2023
bab5cb9
tests
elcritch Sep 21, 2023
6745c29
tests
elcritch Sep 21, 2023
25bb865
tests
elcritch Sep 21, 2023
b224c1c
cleanup
elcritch Sep 21, 2023
113f59c
don't store string
elcritch Sep 22, 2023
06cb6fc
rename to SQLiteBackend
elcritch Sep 22, 2023
8356f6c
re-add async frontend
elcritch Sep 22, 2023
4750ac6
implementing query
elcritch Sep 22, 2023
cbb38a5
trying to fixup query
elcritch Sep 22, 2023
3ae1c60
porting query tests
elcritch Sep 22, 2023
a339bb3
porting query tests
elcritch Sep 22, 2023
3d7c3d2
porting query tests
elcritch Sep 22, 2023
d6d5978
porting query tests
elcritch Sep 22, 2023
0971986
porting query tests
elcritch Sep 22, 2023
185f162
porting query tests
elcritch Sep 22, 2023
10ab970
changes
elcritch Sep 25, 2023
0a86a34
change to non-closure iterator
elcritch Sep 25, 2023
f8ba1e7
change to non-closure iterator
elcritch Sep 25, 2023
598f63c
change to non-closure iterator
elcritch Sep 25, 2023
7bb11c0
change to non-closure iterator
elcritch Sep 25, 2023
f0fc8ce
change to non-closure iterator
elcritch Sep 25, 2023
0efc7f6
change to non-closure iterator
elcritch Sep 25, 2023
85352e8
change to non-closure iterator
elcritch Sep 25, 2023
0336b93
change to non-closure iterator
elcritch Sep 26, 2023
92dcbf7
change to non-closure iterator
elcritch Sep 26, 2023
269aec6
change to generics
elcritch Sep 26, 2023
24ca5f9
change to generics
elcritch Sep 26, 2023
9fe9951
change to generics
elcritch Sep 26, 2023
dbfb54f
change to generics
elcritch Sep 26, 2023
04a30da
change to generics
elcritch Sep 26, 2023
f9e5992
query fixes
elcritch Sep 26, 2023
3b30cc8
query fixes
elcritch Sep 26, 2023
ca108f5
query fixes
elcritch Sep 26, 2023
ccd5d64
query fixes
elcritch Sep 26, 2023
1f23fe5
query fixes
elcritch Sep 26, 2023
62c9e7c
query fixes
elcritch Sep 26, 2023
ebed992
query fixes
elcritch Sep 26, 2023
77173a5
query fixes
elcritch Sep 26, 2023
a16cdaa
query fixes
elcritch Sep 26, 2023
2e2da52
query fixes
elcritch Sep 26, 2023
206751a
query fixes
elcritch Sep 26, 2023
2de2650
query fixes
elcritch Sep 26, 2023
d3eb55f
query fixes
elcritch Sep 26, 2023
289a844
query fixes
elcritch Sep 26, 2023
a637e66
query fixes
elcritch Sep 26, 2023
84cdc1d
query fixes
elcritch Sep 26, 2023
0c72ad8
query fixes
elcritch Sep 26, 2023
73ec70f
query fixes
elcritch Sep 26, 2023
2861eba
simple iterator
elcritch Sep 26, 2023
7710dd7
updates
elcritch Sep 26, 2023
be94266
updates
elcritch Sep 26, 2023
c25eb3a
updates
elcritch Sep 26, 2023
46a2912
updates
elcritch Sep 26, 2023
1a6065b
updates
elcritch Sep 26, 2023
37dbd1c
simplifying
elcritch Sep 26, 2023
2aa8cfa
simplifying
elcritch Sep 26, 2023
575d973
simplifying
elcritch Sep 26, 2023
77e53d2
simplifying
elcritch Sep 26, 2023
53eedd9
simplifying
elcritch Sep 26, 2023
8e573bd
simplifying
elcritch Sep 26, 2023
cbad3c1
simplifying
elcritch Sep 26, 2023
cdb55c0
simplifying
elcritch Sep 26, 2023
d8d6ad7
integrate setups
elcritch Sep 26, 2023
0926eaf
integrate setups
elcritch Sep 26, 2023
73df678
integrate setups
elcritch Sep 26, 2023
f159eff
integrate setups
elcritch Sep 26, 2023
8eef3e6
integrate setups
elcritch Sep 26, 2023
9c7c47e
integrate setups
elcritch Sep 26, 2023
0bd6bd5
integrate setups
elcritch Sep 26, 2023
fddbb99
await all
elcritch Sep 26, 2023
ca9edb2
await all
elcritch Sep 26, 2023
d34cbd7
integrate setups
elcritch Sep 26, 2023
b2de461
setup query
elcritch Sep 26, 2023
8595878
setup query
elcritch Sep 26, 2023
ca14322
setup query
elcritch Sep 26, 2023
7a0c660
setup query
elcritch Sep 26, 2023
7a4b9ac
setup query
elcritch Sep 26, 2023
86ee5d9
setup query
elcritch Sep 26, 2023
57e2a70
setup query
elcritch Sep 26, 2023
8699cfe
setup query
elcritch Sep 26, 2023
f8f0a72
setup query
elcritch Sep 26, 2023
2600d24
setup query end
elcritch Sep 26, 2023
33ca434
setup query end
elcritch Sep 26, 2023
173d426
setup query end
elcritch Sep 26, 2023
4be88df
setup query end
elcritch Sep 26, 2023
77a147c
setup query end
elcritch Sep 26, 2023
b6baefc
setup query end
elcritch Sep 26, 2023
eec66c9
setup query end
elcritch Sep 26, 2023
911de83
setup query end
elcritch Sep 26, 2023
9c6f2fc
setup query
elcritch Sep 26, 2023
5796d4d
setup query
elcritch Sep 26, 2023
abfd12f
setup query
elcritch Sep 26, 2023
892ec38
fixup databuffer
elcritch Sep 26, 2023
555f1fe
fixup databuffer
elcritch Sep 26, 2023
61e8fd4
fixup databuffer
elcritch Sep 26, 2023
6e9325e
testing
elcritch Sep 26, 2023
54a0412
testing
elcritch Sep 26, 2023
c31f189
testing
elcritch Sep 26, 2023
36e6679
fixup backend types
elcritch Sep 27, 2023
cfc743c
result types
elcritch Sep 27, 2023
e75081f
result types
elcritch Sep 27, 2023
c1f5d43
result types
elcritch Sep 27, 2023
da740f1
result types
elcritch Sep 27, 2023
b8dad8b
result types
elcritch Sep 27, 2023
1aec1a4
result types
elcritch Sep 27, 2023
d0ee284
result types
elcritch Sep 27, 2023
f59cf06
test query
elcritch Sep 27, 2023
b4ce286
test query
elcritch Sep 27, 2023
690b3d4
test query
elcritch Sep 27, 2023
8aa3618
test query
elcritch Sep 27, 2023
4b4403b
test query
elcritch Sep 27, 2023
a4c3574
test query
elcritch Sep 27, 2023
6c95c29
test query
elcritch Sep 27, 2023
4e63ca4
test query
elcritch Sep 27, 2023
d411b56
test query
elcritch Sep 27, 2023
24748cd
test query
elcritch Sep 27, 2023
be70ddb
test query
elcritch Sep 27, 2023
b746a26
test query
elcritch Sep 27, 2023
70b5956
test query
elcritch Sep 27, 2023
02de983
test query
elcritch Sep 27, 2023
0fedfcf
test query - it runs!
elcritch Sep 27, 2023
6b90743
test query - it runs!
elcritch Sep 27, 2023
f4d0705
test query - it runs!
elcritch Sep 27, 2023
9cd0ae7
test query - it runs!
elcritch Sep 27, 2023
f8446de
test query - it runs!
elcritch Sep 27, 2023
317d42c
test query - it runs!
elcritch Sep 27, 2023
dacc28a
fix occasional deadlock
elcritch Sep 27, 2023
5c2cc57
fix occasional deadlock
elcritch Sep 27, 2023
4ff162e
fix occasional deadlock
elcritch Sep 27, 2023
7169a7d
fix occasional deadlock
elcritch Sep 27, 2023
2d84385
cleanup
elcritch Sep 27, 2023
55b118c
cleanup
elcritch Sep 27, 2023
2255ea1
Revert "cleanup"
elcritch Sep 27, 2023
c67b61a
cleanup
elcritch Sep 27, 2023
e2b6005
cleanup
elcritch Sep 27, 2023
76590d4
cleanup
elcritch Sep 27, 2023
c7284b3
cleanup
elcritch Sep 27, 2023
bf360f4
Merge branch 'master' into threadpool-refactor
elcritch Sep 27, 2023
686ea8e
cleanup
elcritch Sep 27, 2023
25e16f9
docs
elcritch Sep 27, 2023
c168c8e
docs
elcritch Sep 27, 2023
064a585
Merge branch 'threadpool-refactor' of github.com:codex-storage/nim-da…
elcritch Sep 27, 2023
10bee68
docs
elcritch Sep 27, 2023
d1f503f
reduce thread count
elcritch Sep 27, 2023
6a4e460
queryLocks can be done at FsDs backend level
elcritch Sep 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ coverage
datastore.nims
nimcache
TODO
nim.cfg
nimble.develop
nimble.paths
4 changes: 4 additions & 0 deletions config.nims
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ when (NimMajor, NimMinor) == (1, 2):

when (NimMajor, NimMinor) > (1, 2):
switch("hint", "XCannotRaiseY:off")
# begin Nimble config (version 2)
when withDir(thisDir(), system.fileExists("nimble.paths")):
include "nimble.paths"
# end Nimble config
4 changes: 2 additions & 2 deletions datastore.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ./datastore/datastore
import ./datastore/fsds
import ./datastore/sql
# import ./datastore/sql
import ./datastore/mountedds
import ./datastore/tieredds

export datastore, fsds, mountedds, tieredds, sql
export datastore, fsds, mountedds, tieredds
10 changes: 7 additions & 3 deletions datastore.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ author = "Status Research & Development GmbH"
description = "Simple, unified API for multiple data stores"
license = "Apache License 2.0 or MIT"

requires "nim >= 1.2.0",
requires "nim >= 1.6.14",
"asynctest >= 0.3.1 & < 0.4.0",
"chronos",
"chronos#0277b65be2c7a365ac13df002fba6e172be55537",
"questionable >= 0.10.3 & < 0.11.0",
"sqlite3_abi",
"stew",
"unittest2",
"upraises >= 0.1.0 & < 0.2.0"
"pretty",
"threading",
"taskpools",
"upraises >= 0.1.0 & < 0.2.0",
"chronicles"

task coverage, "generates code coverage report":
var (output, exitCode) = gorgeEx("which lcov")
Expand Down
67 changes: 67 additions & 0 deletions datastore/backend.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import std/algorithm
import std/options

import pkg/questionable/results

import ./threads/databuffer
import ./types

export databuffer, types, SortOrder

## Types for datastore backends.
##
## These should be syncrhonous and work with both GC types
## and DataBuffer's. This makes it easier to make them threadsafe.
##

type
DbQueryResponse*[K, V] = tuple[key: Option[K], data: V]

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

KeyId* = object
## serialized Key ID, equivalent to `key.id()`
data*: DataBuffer

## Accepted backend key and value types
DbKey* = string | KeyId
DbVal* = seq[byte] | DataBuffer

DbBatchEntry*[K, V] = tuple[key: K, data: V]

DbQueryHandle*[K, V, T] = object
query*: DbQuery[K]
cancel*: bool
closed*: bool
env*: T

proc dbQuery*[K](
key: K,
value = false,
sort = SortOrder.Ascending,
offset = 0,
limit = -1
): DbQuery[K] =
DbQuery[K](key: key, value: value, sort: sort, offset: offset, limit: limit)

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)

template toVal*(tp: typedesc[DataBuffer], id: openArray[byte]): DataBuffer = DataBuffer.new(id)
template toVal*(tp: typedesc[seq[byte]], id: openArray[byte]): seq[byte] = @(id)

proc new*(tp: typedesc[KeyId], id: cstring): KeyId =
KeyId(data: DataBuffer.new(id.toOpenArray(0, id.len()-1)))

proc new*(tp: typedesc[KeyId], id: string): KeyId =
KeyId(data: DataBuffer.new(id))

template toOpenArray*(x: DbKey): openArray[char] =
x.data.toOpenArray(char)
27 changes: 16 additions & 11 deletions datastore/datastore.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,37 @@ push: {.upraises: [].}
type
BatchEntry* = tuple[key: Key, data: seq[byte]]

method has*(self: Datastore, key: Key): Future[?!bool] {.base, locks: "unknown".} =
method has*(self: Datastore, key: Key): Future[?!bool] {.base, locks: "unknown", raises: [].} =
raiseAssert("Not implemented!")

method delete*(self: Datastore, key: Key): Future[?!void] {.base, locks: "unknown".} =
method delete*(self: Datastore, key: Key): Future[?!void] {.base, locks: "unknown", raises: [].} =
raiseAssert("Not implemented!")

method delete*(self: Datastore, keys: seq[Key]): Future[?!void] {.base, locks: "unknown".} =
method delete*(self: Datastore, keys: seq[Key]): Future[?!void] {.base, locks: "unknown", raises: [].} =
raiseAssert("Not implemented!")

method get*(self: Datastore, key: Key): Future[?!seq[byte]] {.base, locks: "unknown".} =
method get*(self: Datastore, key: Key): Future[?!seq[byte]] {.base, locks: "unknown", raises: [].} =
raiseAssert("Not implemented!")

method put*(self: Datastore, key: Key, data: seq[byte]): Future[?!void] {.base, locks: "unknown".} =
method put*(self: Datastore, key: Key, data: seq[byte]): Future[?!void] {.base, locks: "unknown", raises: [].} =
raiseAssert("Not implemented!")

method put*(self: Datastore, batch: seq[BatchEntry]): Future[?!void] {.base, locks: "unknown".} =
method put*(self: Datastore, batch: seq[BatchEntry]): Future[?!void] {.base, locks: "unknown", raises: [].} =
raiseAssert("Not implemented!")

method close*(self: Datastore): Future[?!void] {.base, async, locks: "unknown".} =
method close*(self: Datastore): Future[?!void] {.base, locks: "unknown", raises: [].} =
raiseAssert("Not implemented!")

method query*(
self: Datastore,
query: Query): Future[?!QueryIter] {.base, gcsafe.} =
method query*(self: Datastore,
query: Query
): Future[?!QueryIter] {.base, gcsafe, raises: [].} =

raiseAssert("Not implemented!")

proc contains*(self: Datastore, key: Key): Future[bool] {.async.} =
method queryIter*(self: Datastore,
query: Query
): ?!(iterator(): ?!QueryResponse) {.base, gcsafe, raises: [].} =
raiseAssert("Not implemented!")

proc contains*(self: Datastore, key: Key): Future[bool] {.async, raises: [].} =
return (await self.has(key)) |? false
16 changes: 16 additions & 0 deletions datastore/fsds.nim
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ method put*(
return success()

proc dirWalker(path: string): iterator: string {.gcsafe.} =
var localPath {.threadvar.}: string

localPath = path
return iterator(): string =
try:
for p in path.walkDirRec(yieldFilter = {pcFile}, relative = true):
Expand Down Expand Up @@ -188,10 +191,23 @@ method query*(
var
iter = QueryIter.new()

var lock = newAsyncLock() # serialize querying under threads
proc next(): Future[?!QueryResponse] {.async.} =
defer:
if lock.locked:
lock.release()

if lock.locked:
return failure (ref DatastoreError)(msg: "Should always await query features")

let
path = walker()

if iter.finished:
return failure "iterator is finished"

await lock.acquire()

if finished(walker):
iter.finished = true
return success (Key.none, EmptyBytes)
Expand Down
45 changes: 19 additions & 26 deletions datastore/query.nim
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import pkg/upraises
import std/algorithm
import pkg/chronos
import pkg/questionable
import pkg/questionable/results

import ./key
import ./types
import ./backend

export types
export options, SortOrder

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
## Front end types
Query* = DbQuery[Key]

QueryResponse* = tuple[key: ?Key, data: seq[byte]]
QueryEndedError* = object of DatastoreError
QueryResponse* = DbQueryResponse[Key, seq[byte]]

GetNext* = proc(): Future[?!QueryResponse] {.upraises: [], gcsafe, closure.}
GetNext* = proc(): Future[?!QueryResponse] {.upraises: [], gcsafe.}
IterDispose* = proc(): Future[?!void] {.upraises: [], gcsafe.}
QueryIter* = ref object
finished*: bool
Expand All @@ -38,17 +35,13 @@ proc defaultDispose(): Future[?!void] {.upraises: [], gcsafe, async.} =
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)
proc init*(T: type Query,
key: Key,
value = true,
sort = SortOrder.Ascending,
offset = 0,
limit = -1): Query =
dbQuery[Key](key, value, sort, offset, limit)

proc toKey*(key: KeyId): Key {.inline, raises: [].} =
Key.init($key.data).expect("expected valid key here for but got `" & $key.data & "`")
101 changes: 100 additions & 1 deletion datastore/sql.nim
Original file line number Diff line number Diff line change
@@ -1,3 +1,102 @@
import std/times
import std/options

import pkg/chronos
import pkg/questionable
import pkg/questionable/results
import pkg/sqlite3_abi
from pkg/stew/results as stewResults import isErr
import pkg/upraises

import std/sequtils
import ../datastore
import ./backend
import ./sql/sqliteds

export sqliteds
export datastore, sqliteds

push: {.upraises: [].}

type
SQLiteDatastore* = ref object of Datastore
db: SQLiteBackend[KeyId, DataBuffer]

proc path*(self: SQLiteDatastore): string =
self.db.path()

proc readOnly*(self: SQLiteDatastore): bool =
self.db.readOnly()

method has*(self: SQLiteDatastore,
key: Key): Future[?!bool] {.async.} =
return self.db.has(KeyId.new key.id())

method delete*(self: SQLiteDatastore,
key: Key): Future[?!void] {.async.} =
return self.db.delete(KeyId.new key.id())

method delete*(self: SQLiteDatastore,
keys: seq[Key]): Future[?!void] {.async.} =
let dkeys = keys.mapIt(KeyId.new it.id())
return self.db.delete(dkeys)

method get*(self: SQLiteDatastore,
key: Key): Future[?!seq[byte]] {.async.} =
self.db.get(KeyId.new key.id()).map() do(d: DataBuffer) -> seq[byte]:
d.toSeq()

method put*(self: SQLiteDatastore,
key: Key,
data: seq[byte]): Future[?!void] {.async.} =
self.db.put(KeyId.new key.id(), DataBuffer.new data)

method put*(self: SQLiteDatastore,
batch: seq[BatchEntry]): Future[?!void] {.async.} =
var dbatch: seq[tuple[key: KeyId, data: DataBuffer]]
for entry in batch:
dbatch.add((KeyId.new entry.key.id(), DataBuffer.new entry.data))
self.db.put(dbatch)

method close*(self: SQLiteDatastore): Future[?!void] {.async.} =
self.db.close()

method queryIter*(
self: SQLiteDatastore,
query: Query
): ?!(iterator(): ?!QueryResponse) =

let dbquery = dbQuery(
key= KeyId.new query.key.id(),
value= query.value,
limit= query.limit,
offset= query.offset,
sort= query.sort,
)
var qhandle = ? self.db.query(dbquery)

let iter = iterator(): ?!QueryResponse =
for resp in qhandle.iter():
without qres =? resp, err:
yield QueryResponse.failure err
let k = qres.key.map() do(k: KeyId) -> Key:
Key.init($k).expect("valid key")
let v: seq[byte] = qres.data.toSeq()
yield success (k, v)

success iter

proc new*(
T: type SQLiteDatastore,
path: string,
readOnly = false): ?!SQLiteDatastore =

success SQLiteDatastore(
db: ? newSQLiteBackend[KeyId, DataBuffer](path, readOnly))

proc new*(
T: type SQLiteDatastore,
db: SQLiteBackend[KeyId, DataBuffer]): ?!T =

success T(
db: db,
readOnly: db.readOnly)
Loading