108 lines
2.6 KiB
Nim
Raw Permalink Normal View History

2023-09-20 17:12:19 -07:00
import std/times
import std/options
2022-09-19 17:13:20 -06:00
2023-09-20 17:12:19 -07:00
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
2023-09-21 17:52:06 -07:00
import std/sequtils
2023-09-20 17:12:19 -07:00
import ../datastore
2023-09-21 17:52:06 -07:00
import ./backend
import ./sql/sqliteds
2023-09-20 17:12:19 -07:00
2023-09-20 22:12:53 -07:00
export datastore
2023-09-20 17:12:19 -07:00
push: {.upraises: [].}
2023-09-21 17:52:06 -07:00
type
SQLiteDatastore* = ref object of Datastore
2023-09-25 20:37:34 -07:00
db: SQLiteBackend[KeyId, DataBuffer]
2023-09-20 17:12:19 -07:00
2023-09-21 17:52:06 -07:00
proc path*(self: SQLiteDatastore): string =
self.db.path()
2023-09-20 17:12:19 -07:00
2023-09-21 17:52:06 -07:00
proc readOnly*(self: SQLiteDatastore): bool =
self.db.readOnly()
2023-09-20 17:12:19 -07:00
2023-09-25 20:37:34 -07:00
method has*(self: SQLiteDatastore,
key: Key): Future[?!bool] {.async.} =
2023-09-21 17:52:06 -07:00
return self.db.has(KeyId.new key.id())
2023-09-20 17:12:19 -07:00
2023-09-25 20:37:34 -07:00
method delete*(self: SQLiteDatastore,
key: Key): Future[?!void] {.async.} =
2023-09-21 17:52:06 -07:00
return self.db.delete(KeyId.new key.id())
2023-09-20 17:12:19 -07:00
2023-09-25 20:37:34 -07:00
method delete*(self: SQLiteDatastore,
keys: seq[Key]): Future[?!void] {.async.} =
2023-09-21 17:52:06 -07:00
let dkeys = keys.mapIt(KeyId.new it.id())
return self.db.delete(dkeys)
2023-09-20 17:12:19 -07:00
2023-09-25 20:37:34 -07:00
method get*(self: SQLiteDatastore,
key: Key): Future[?!seq[byte]] {.async.} =
2023-09-21 17:52:06 -07:00
self.db.get(KeyId.new key.id())
2023-09-20 17:12:19 -07:00
2023-09-25 20:37:34 -07:00
method put*(self: SQLiteDatastore,
key: Key,
data: seq[byte]): Future[?!void] {.async.} =
2023-09-21 17:52:06 -07:00
self.db.put(KeyId.new key.id(), DataBuffer.new data)
2023-09-20 17:12:19 -07:00
2023-09-25 20:37:34 -07:00
method put*(self: SQLiteDatastore,
batch: seq[BatchEntry]): Future[?!void] {.async.} =
2023-09-25 20:58:26 -07:00
var dbatch: seq[tuple[key: KeyId, data: DataBuffer]]
2023-09-21 17:52:06 -07:00
for entry in batch:
2023-09-25 20:58:26 -07:00
dbatch.add((KeyId.new entry.key.id(), DataBuffer.new entry.data))
2023-09-21 17:52:06 -07:00
self.db.put(dbatch)
2023-09-20 17:12:19 -07:00
2023-09-21 17:52:06 -07:00
method close*(self: SQLiteDatastore): Future[?!void] {.async.} =
self.db.close()
2023-09-20 17:12:19 -07:00
2023-09-25 21:07:42 -07:00
method queryIter*(
2023-09-21 17:52:06 -07:00
self: SQLiteDatastore,
query: Query
2023-09-25 21:05:07 -07:00
): ?!(iterator(): ?!QueryResponse) =
2023-09-20 17:12:19 -07:00
2023-09-25 20:58:26 -07:00
let dbquery = dbQuery(
key= KeyId.new query.key.id(),
value= query.value,
limit= query.limit,
offset= query.offset,
sort= query.sort,
2023-09-21 17:52:06 -07:00
)
2023-09-25 21:05:07 -07:00
var qhandle = ? self.db.query(dbquery)
let iter = iterator(): ?!QueryResponse =
for resp in qhandle.iter():
without qres =? resp, err:
yield QueryResponse.failure err
2023-09-25 21:13:23 -07:00
let k = qres.key.map() do(k: KeyId) -> Key:
Key.init($k).expect("valid key")
2023-09-25 21:12:06 -07:00
let v: seq[byte] = qres.data
yield success (k, v)
2023-09-25 21:05:07 -07:00
success iter
2023-09-20 17:12:19 -07:00
2023-09-21 17:52:06 -07:00
proc new*(
T: type SQLiteDatastore,
path: string,
readOnly = false): ?!T =
2023-09-20 17:12:19 -07:00
2023-09-21 17:52:06 -07:00
let
flags =
if readOnly: SQLITE_OPEN_READONLY
else: SQLITE_OPEN_READWRITE or SQLITE_OPEN_CREATE
2023-09-20 17:12:19 -07:00
2023-09-21 17:52:06 -07:00
success T(
db: ? SQLiteDsDb.open(path, flags),
readOnly: readOnly)
2023-09-20 17:12:19 -07:00
2023-09-21 17:52:06 -07:00
proc new*(
T: type SQLiteDatastore,
db: SQLiteDsDb): ?!T =
2023-09-20 17:12:19 -07:00
2023-09-21 17:52:06 -07:00
success T(
db: db,
readOnly: db.readOnly)