openArray

This commit is contained in:
Jaremy Creechley 2023-09-20 18:08:27 -07:00
parent f7a933a60a
commit 77efc50469
No known key found for this signature in database
GPG Key ID: 4E66FB67B21D3300
3 changed files with 31 additions and 10 deletions

View File

@ -3,6 +3,8 @@ import pkg/questionable/results
import pkg/sqlite3_abi
import pkg/upraises
import ../backend
export sqlite3_abi
# Adapted from:
@ -61,7 +63,14 @@ 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|openArray[char]:
elif val is string:
# `-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
# remain valid until then. SQLite will then manage the lifetime of its
# private copy."
sqlite3_bind_text(s, n.cint, val.cstring, -1.cint, SQLITE_TRANSIENT)
elif val is DbKey:
# `-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

View File

@ -51,10 +51,15 @@ proc new*[T: byte | char](tp: type DataBuffer, data: openArray[T]): DataBuffer =
##
result = DataBuffer.new(data.len)
if data.len() > 0:
# TODO: we might want to copy data, otherwise the GC might
# release it on stack-unwind
copyMem(result[].buf, baseAddr data, data.len)
proc setData*[T: byte | char](db: DataBuffer, data: openArray[T]) =
## allocate new buffer and copies indata from openArray
##
if data.len() > db.len():
raise newException(IndexDefect, "data too large for buffer")
copyMem(db[].buf, baseAddr data, data.len)
converter toSeq*(self: DataBuffer): seq[byte] =
## convert buffer to a seq type using copy and either a byte or char
##

View File

@ -22,23 +22,30 @@ type
ThreadQueryRes* = (DataBuffer, DataBuffer)
ThreadResult*[T: ThreadTypes] = Result[T, ThreadResErr]
DbKey* = tuple[data: DataBuffer]
DbValue* = tuple[data: DataBuffer]
DbKey* = object
data: DataBuffer
DbVal* = object
data: DataBuffer
proc toDb*(key: Key): DbKey {.inline, raises: [].} =
(data: DataBuffer.new(key.id()))
let id: string = key.id()
let db = DataBuffer.new(id.len()+1) # include room for null for cstring compat
db.setData(id)
DbKey(data: db)
proc toKey*(key: DbKey): Key {.inline, raises: [].} =
Key.init(key.data).expect("expected valid key here for but got `" & $key.data & "`")
proc toDb*(value: sink seq[byte]): DbValue {.inline, raises: [].} =
(data: DataBuffer.new(value))
proc toDb*(value: sink seq[byte]): DbVal {.inline, raises: [].} =
DbVal(data: DataBuffer.new(value))
proc toValue*(value: DbValue): seq[byte] {.inline, raises: [].} =
proc toValue*(value: DbVal): seq[byte] {.inline, raises: [].} =
value.data.toSeq()
template toOpenArray*(x: DbKey): openArray[char] =
x.data[].buf.toOpenArray(0, x[].size-1)
x.data.toOpenArray(char)
template toOpenArray*(x: DbVal): openArray[byte] =
x.data.toOpenArray(byte)
converter toThreadErr*(e: ref CatchableError): ThreadResErr {.inline, raises: [].} =
if e of DatastoreKeyNotFound: (ErrorEnum.DatastoreKeyNotFoundErr, DataBuffer.new(e.msg))