mirror of https://github.com/status-im/nim-eth.git
sqlite3: support option type
.. and any integer when writing but don't support int32 on reads - internally sqlite will truncate on overflow which isn't nice.
This commit is contained in:
parent
2a292cfb62
commit
68e6aadc29
|
@ -93,10 +93,13 @@ proc bindParam(s: RawStmtPtr, n: int, val: auto): cint =
|
|||
sqlite3_bind_blob(s, n.cint, nil, 0.cint, nil)
|
||||
else:
|
||||
{.fatal: "Please add support for the '" & $typeof(val) & "' type".}
|
||||
elif val is int32:
|
||||
sqlite3_bind_int(s, n.cint, val)
|
||||
elif val is int64:
|
||||
sqlite3_bind_int64(s, n.cint, val)
|
||||
elif val is SomeInteger:
|
||||
sqlite3_bind_int64(s, n.cint, val.clong)
|
||||
elif val is Option:
|
||||
if val.isNone():
|
||||
sqlite3_bind_null(s, n.cint)
|
||||
else:
|
||||
bindParam(s, n, val.get())
|
||||
else:
|
||||
{.fatal: "Please add support for the '" & $typeof(val) & "' type".}
|
||||
|
||||
|
@ -125,13 +128,15 @@ proc exec*[P](s: SqliteStmt[P, void], params: P): KvResult[void] =
|
|||
|
||||
res
|
||||
|
||||
template readResult(s: RawStmtPtr, column: cint, T: type): auto =
|
||||
when T is int32:
|
||||
sqlite3_column_int(s, column)
|
||||
elif T is int64:
|
||||
template readSimpleResult(s: RawStmtPtr, column: cint, T: type): auto =
|
||||
when T is int64:
|
||||
sqlite3_column_int64(s, column)
|
||||
elif T is int:
|
||||
{.fatal: "Please use specify either int32 or int64 precisely".}
|
||||
elif T is SomeInteger:
|
||||
# sqlite integers are "up to" 8 bytes in size, so rather than silently
|
||||
# truncate them, we support only 64-bit integers when reading and let the
|
||||
# calling code deal with it - careful though, anything that is not an
|
||||
# integer (ie TEXT) is returned as 0
|
||||
{.fatal: "Use int64 for reading integers".}
|
||||
elif T is openArray[byte]:
|
||||
let
|
||||
p = cast[ptr UncheckedArray[byte]](sqlite3_column_blob(s, column))
|
||||
|
@ -161,6 +166,15 @@ template readResult(s: RawStmtPtr, column: cint, T: type): auto =
|
|||
else:
|
||||
{.fatal: "Please add support for the '" & $(T) & "' type".}
|
||||
|
||||
template readResult(s: RawStmtPtr, column: cint, T: type): auto =
|
||||
when T is Option:
|
||||
if sqlite3_column_type(s, column) == SQLITE_NULL:
|
||||
none(typeof(default(T).get()))
|
||||
else:
|
||||
some(readSimpleResult(s, column, typeof(default(T).get())))
|
||||
else:
|
||||
readSimpleResult(s, column, T)
|
||||
|
||||
template readResult(s: RawStmtPtr, T: type): auto =
|
||||
when T is tuple:
|
||||
var res: T
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{.used.}
|
||||
|
||||
import
|
||||
std/os,
|
||||
std/[os, options],
|
||||
testutils/unittests,
|
||||
../../eth/db/[kvstore, kvstore_sqlite3],
|
||||
./test_kvstore
|
||||
|
@ -45,7 +45,6 @@ procSuite "SqStoreRef":
|
|||
NoParams, int64).get
|
||||
|
||||
var totalRecords = 0
|
||||
echo "About to call total records"
|
||||
let countRes = countStmt.exec do (res: int64):
|
||||
totalRecords = int res
|
||||
|
||||
|
@ -138,7 +137,6 @@ procSuite "SqStoreRef":
|
|||
NoParams, int64).get
|
||||
|
||||
var totalRecords = 0
|
||||
echo "About to call total attestations"
|
||||
let countRes = countStmt.exec do (res: int64):
|
||||
totalRecords = int res
|
||||
|
||||
|
@ -178,3 +176,43 @@ procSuite "SqStoreRef":
|
|||
source == 2
|
||||
target == 4
|
||||
digest == hash
|
||||
|
||||
test "null values":
|
||||
#
|
||||
let db = SqStoreRef.init("", "test", inMemory = true)[]
|
||||
defer: db.close()
|
||||
|
||||
let createTableRes = db.exec """
|
||||
CREATE TABLE IF NOT EXISTS testnull(
|
||||
a INTEGER PRIMARY KEY,
|
||||
b INTEGER NULL,
|
||||
c INTEGER NULL
|
||||
);
|
||||
"""
|
||||
check createTableRes.isOk
|
||||
|
||||
type
|
||||
ABC = (int64, Option[int64], Option[int64])
|
||||
let insertStmt = db.prepareStmt("""
|
||||
INSERT INTO testnull(a, b, c) VALUES (?,?,?);
|
||||
""", ABC, void).get()
|
||||
|
||||
const val = (42'i64, none(int64), some(44'i64))
|
||||
check:
|
||||
insertStmt.exec(val).isOk()
|
||||
|
||||
let selectStmt = db.prepareStmt("""
|
||||
SELECT a, b, c FROM testnull
|
||||
""", NoParams, ABC).get()
|
||||
|
||||
block:
|
||||
var abc: ABC
|
||||
let selectRes = selectStmt.exec do (res: ABC):
|
||||
abc = res
|
||||
|
||||
if selectRes.isErr:
|
||||
echo selectRes.error
|
||||
|
||||
check:
|
||||
selectRes.isOk and selectRes.get == true
|
||||
abc == val
|
||||
|
|
Loading…
Reference in New Issue