mirror of
https://github.com/logos-storage/nim-datastore.git
synced 2026-01-04 14:43:12 +00:00
openArray
This commit is contained in:
parent
1833155e53
commit
f7a933a60a
10
datastore/backend.nim
Normal file
10
datastore/backend.nim
Normal file
@ -0,0 +1,10 @@
|
||||
import pkg/questionable/results
|
||||
import pkg/upraises
|
||||
|
||||
import ./threads/databuffer
|
||||
import ./threads/threadresult
|
||||
import ./threads/semaphore
|
||||
import ./types
|
||||
|
||||
export databuffer, threadresult, semaphore, types
|
||||
export upraises, results
|
||||
@ -7,10 +7,10 @@ import pkg/sqlite3_abi
|
||||
from pkg/stew/results as stewResults import isErr
|
||||
import pkg/upraises
|
||||
|
||||
import ../datastore
|
||||
import ../backend
|
||||
import ./sqlitedsdb
|
||||
|
||||
export datastore, sqlitedsdb
|
||||
export backend, sqlitedsdb
|
||||
|
||||
push: {.upraises: [].}
|
||||
|
||||
@ -26,7 +26,7 @@ proc readOnly*(self: SQLiteDatastore): bool = self.db.readOnly
|
||||
proc timestamp*(t = epochTime()): int64 =
|
||||
(t * 1_000_000).int64
|
||||
|
||||
proc has*(self: SQLiteDatastore, key: Key): ?!bool =
|
||||
proc has*(self: SQLiteDatastore, key: DbKey): ?!bool =
|
||||
var
|
||||
exists = false
|
||||
|
||||
@ -38,10 +38,10 @@ proc has*(self: SQLiteDatastore, key: Key): ?!bool =
|
||||
|
||||
return success exists
|
||||
|
||||
proc delete*(self: SQLiteDatastore, key: Key): ?!void =
|
||||
return self.db.deleteStmt.exec((key.id))
|
||||
proc delete*(self: SQLiteDatastore, key: DbKey): ?!void =
|
||||
return self.db.deleteStmt.exec((key.data))
|
||||
|
||||
proc delete*(self: SQLiteDatastore, keys: seq[Key]): ?!void =
|
||||
proc delete*(self: SQLiteDatastore, keys: seq[DbKey]): ?!void =
|
||||
if err =? self.db.beginStmt.exec().errorOption:
|
||||
return failure(err)
|
||||
|
||||
@ -57,7 +57,7 @@ proc delete*(self: SQLiteDatastore, keys: seq[Key]): ?!void =
|
||||
|
||||
return success()
|
||||
|
||||
proc get*(self: SQLiteDatastore, key: Key): ?!seq[byte] =
|
||||
proc get*(self: SQLiteDatastore, key: DbKey): ?!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`
|
||||
@ -73,11 +73,11 @@ proc get*(self: SQLiteDatastore, key: Key): ?!seq[byte] =
|
||||
|
||||
if bytes.len <= 0:
|
||||
return failure(
|
||||
newException(DatastoreKeyNotFound, "Key doesn't exist"))
|
||||
newException(DatastoreKeyNotFound, "DbKey doesn't exist"))
|
||||
|
||||
return success bytes
|
||||
|
||||
proc put*(self: SQLiteDatastore, key: Key, data: seq[byte]): ?!void =
|
||||
proc put*(self: SQLiteDatastore, key: DbKey, data: seq[byte]): ?!void =
|
||||
return self.db.putStmt.exec((key.id, data, timestamp()))
|
||||
|
||||
proc put*(self: SQLiteDatastore, batch: seq[BatchEntry]): ?!void =
|
||||
@ -169,7 +169,7 @@ iterator query*(self: SQLiteDatastore,
|
||||
case v
|
||||
of SQLITE_ROW:
|
||||
let
|
||||
key = Key.init(
|
||||
key = DbKey.init(
|
||||
$sqlite3_column_text_not_null(s, QueryStmtIdCol))
|
||||
.expect("should not fail")
|
||||
|
||||
@ -208,7 +208,7 @@ iterator query*(self: SQLiteDatastore,
|
||||
return success (key.some, data)
|
||||
of SQLITE_DONE:
|
||||
iter.finished = true
|
||||
return success (Key.none, EmptyBytes)
|
||||
return success (DbKey.none, EmptyBytes)
|
||||
else:
|
||||
iter.finished = true
|
||||
return failure newException(DatastoreError, $sqlite3_errstr(v))
|
||||
|
||||
@ -61,7 +61,7 @@ proc bindParam(
|
||||
sqlite3_bind_int64(s, n.cint, val.int64)
|
||||
elif val is float32 | float64:
|
||||
sqlite3_bind_double(s, n.cint, val.float64)
|
||||
elif val is string:
|
||||
elif val is string|openArray[char]:
|
||||
# `-1` implies string length is num bytes up to first null-terminator;
|
||||
# `SQLITE_TRANSIENT` "indicate[s] that the object is to be copied prior
|
||||
# to the return from sqlite3_bind_*(). The object and pointer to it must
|
||||
|
||||
@ -90,3 +90,10 @@ converter toBuffer*(err: ref CatchableError): DataBuffer =
|
||||
##
|
||||
|
||||
return DataBuffer.new(err.msg)
|
||||
|
||||
template toOpenArray*[T: byte | char](data: DataBuffer, t: typedesc[T]): openArray[T] =
|
||||
## get openArray from DataBuffer as char
|
||||
##
|
||||
## this is explicit since sqlite treats string differently from openArray[byte]
|
||||
let bf = cast[ptr UncheckedArray[T]](data[].buf)
|
||||
bf.toOpenArray(0, data[].size-1)
|
||||
|
||||
@ -37,6 +37,9 @@ proc toDb*(value: sink seq[byte]): DbValue {.inline, raises: [].} =
|
||||
proc toValue*(value: DbValue): seq[byte] {.inline, raises: [].} =
|
||||
value.data.toSeq()
|
||||
|
||||
template toOpenArray*(x: DbKey): openArray[char] =
|
||||
x.data[].buf.toOpenArray(0, x[].size-1)
|
||||
|
||||
converter toThreadErr*(e: ref CatchableError): ThreadResErr {.inline, raises: [].} =
|
||||
if e of DatastoreKeyNotFound: (ErrorEnum.DatastoreKeyNotFoundErr, DataBuffer.new(e.msg))
|
||||
elif e of QueryEndedError: (ErrorEnum.QueryEndedErr, DataBuffer.new(e.msg))
|
||||
|
||||
@ -103,5 +103,15 @@ suite "Share buffer test":
|
||||
test "seq conversion":
|
||||
check a.toSeq() == "/a/b".toBytes
|
||||
|
||||
test "basic openArray test":
|
||||
proc letters(val: openArray[char]): int =
|
||||
val.len()
|
||||
proc bytes(val: openArray[byte]): int =
|
||||
val.len()
|
||||
|
||||
check a.toOpenArray(char).letters() == a.len()
|
||||
check a.toOpenArray(byte).bytes() == a.len()
|
||||
# check a.toOpenArray(char).bytes() == a.len()
|
||||
|
||||
test "basic thread test":
|
||||
runBasicTest()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user