mirror of
https://github.com/logos-storage/nim-datastore.git
synced 2026-01-03 22:23:10 +00:00
check for out-of-memory errors re: sqlite3_column_text/blob/bytes
closes #2
This commit is contained in:
parent
1a1a1ac642
commit
f634c2f5ae
@ -136,9 +136,26 @@ template journalModePragmaStmt*(env: SQLite): RawStmtPtr =
|
||||
s.dispose
|
||||
return failure $sqlite3_errstr(x)
|
||||
|
||||
if (let x = $sqlite3_column_text(s, 0).cstring; x != "memory" and x != "wal"):
|
||||
let
|
||||
x = sqlite3_column_text(s, 0).cstring
|
||||
|
||||
# detect out-of-memory error
|
||||
# see the conversion table and final paragraph of:
|
||||
# https://www.sqlite.org/c3ref/column_blob.html
|
||||
# see also https://www.sqlite.org/rescode.html
|
||||
|
||||
# in order to detect an out-of-memory error check that the result is a null
|
||||
# pointer and that the result code is an error code
|
||||
if x.isNil:
|
||||
let
|
||||
code = sqlite3_errcode(sqlite3_db_handle(s))
|
||||
|
||||
if not (code in [SQLITE_OK, SQLITE_ROW, SQLITE_DONE]):
|
||||
raise (ref Defect)(msg: $sqlite3_errstr(code))
|
||||
|
||||
if not ($x in ["memory", "wal"]):
|
||||
s.dispose
|
||||
return failure "Invalid pragma result: " & $x
|
||||
return failure "Invalid pragma result: \"" & $x & "\""
|
||||
|
||||
s
|
||||
|
||||
|
||||
@ -185,7 +185,22 @@ proc idCol*(
|
||||
s: RawStmtPtr,
|
||||
index = 0): string =
|
||||
|
||||
$sqlite3_column_text(s, index.cint).cstring
|
||||
let
|
||||
text = sqlite3_column_text(s, index.cint).cstring
|
||||
|
||||
# detect out-of-memory error
|
||||
# see the conversion table and final paragraph of:
|
||||
# https://www.sqlite.org/c3ref/column_blob.html
|
||||
|
||||
# the "id" column is NOT NULL PRIMARY KEY so an out-of-memory error can be
|
||||
# inferred from a null pointer result
|
||||
if text.isNil:
|
||||
let
|
||||
code = sqlite3_errcode(sqlite3_db_handle(s))
|
||||
|
||||
raise (ref Defect)(msg: $sqlite3_errstr(code))
|
||||
|
||||
$text
|
||||
|
||||
proc dataCol*(
|
||||
s: RawStmtPtr,
|
||||
@ -193,9 +208,36 @@ proc dataCol*(
|
||||
|
||||
let
|
||||
i = index.cint
|
||||
dataBytes = cast[ptr UncheckedArray[byte]](sqlite3_column_blob(s, i))
|
||||
blob = sqlite3_column_blob(s, i)
|
||||
|
||||
# detect out-of-memory error
|
||||
# see the conversion table and final paragraph of:
|
||||
# https://www.sqlite.org/c3ref/column_blob.html
|
||||
# see also https://www.sqlite.org/rescode.html
|
||||
|
||||
# the "data" column can be NULL so in order to detect an out-of-memory error
|
||||
# it is necessary to check that the result is a null pointer and that the
|
||||
# result code is an error code
|
||||
if blob.isNil:
|
||||
let
|
||||
code = sqlite3_errcode(sqlite3_db_handle(s))
|
||||
|
||||
if not (code in [SQLITE_OK, SQLITE_ROW, SQLITE_DONE]):
|
||||
raise (ref Defect)(msg: $sqlite3_errstr(code))
|
||||
|
||||
let
|
||||
dataLen = sqlite3_column_bytes(s, i)
|
||||
|
||||
# an out-of-memory error can be inferred from a null pointer result
|
||||
if (unsafeAddr dataLen).isNil:
|
||||
let
|
||||
code = sqlite3_errcode(sqlite3_db_handle(s))
|
||||
|
||||
raise (ref Defect)(msg: $sqlite3_errstr(code))
|
||||
|
||||
let
|
||||
dataBytes = cast[ptr UncheckedArray[byte]](blob)
|
||||
|
||||
@(toOpenArray(dataBytes, 0, dataLen - 1))
|
||||
|
||||
proc timestampCol*(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user