Skip to content

Commit ae9cde8

Browse files
committed
Add ability to run statements without the macro
This is required to run highly dynamic SQL statements where the number of parameters and the structure of results is only known dynamically. Also fix typo s/SqliteDateType/SqliteDataType/
1 parent a339d89 commit ae9cde8

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

src/easy_sqlite3.nim

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import easy_sqlite3/[bindings,macros]
22
export macros
33

4-
export raw, len, toOpenArray, SQLiteError, SQLiteBlob, Statement, Database, OpenFlag, enableSharedCache, initDatabase, exec, execM, changes, lastInsertRowid, `[]=`, reset, step, withColumnBlob, getParameterIndex, getColumnType, getColumn, unpack, `=destroy`
4+
export raw, len, toOpenArray, SQLiteError, SQLiteBlob, Statement, Database,
5+
SqliteDataType, OpenFlag, enableSharedCache, initDatabase, exec, execM,
6+
changes, lastInsertRowid, `[]=`, reset, step, withColumnBlob,
7+
getParameterIndex, getColumnType, getColumn, ColumnDef, columns, `[]`,
8+
unpack, `=destroy`, setAuthorizer, AuthorizerActionCode,
9+
AuthorizerResult, Authorizer, newStatement, lines

src/easy_sqlite3/bindings.nim

+40-3
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ type SqliteDestroctor* = proc (p: pointer) {.cdecl.}
276276
const StaticDestructor* = cast[SqliteDestroctor](0)
277277
const TransientDestructor* = cast[SqliteDestroctor](-1)
278278

279-
type SqliteDateType* = enum
279+
type SqliteDataType* = enum
280280
dt_integer = 1,
281281
dt_float = 2,
282282
dt_text = 3,
@@ -438,7 +438,9 @@ proc sqlite3_bind_pointer*(st: ptr RawStatement, idx: int, val: pointer, name: c
438438
proc sqlite3_bind_zeroblob64*(st: ptr RawStatement, idx: int, len: int): ResultCode {.sqlite3linkage.}
439439
proc sqlite3_changes*(st: ptr RawDatabase): int {.sqlite3linkage.}
440440
proc sqlite3_last_insert_rowid*(st: ptr RawDatabase): int {.sqlite3linkage.}
441-
proc sqlite3_column_type*(st: ptr RawStatement, idx: int): SqliteDateType {.sqlite3linkage.}
441+
proc sqlite3_column_count*(st: ptr RawStatement): int {.sqlite3linkage.}
442+
proc sqlite3_column_type*(st: ptr RawStatement, idx: int): SqliteDataType {.sqlite3linkage.}
443+
proc sqlite3_column_name*(st: ptr RawStatement, idx: int): cstring {.sqlite3linkage.}
442444
proc sqlite3_column_blob*(st: ptr RawStatement, idx: int): pointer {.sqlite3linkage.}
443445
proc sqlite3_column_bytes*(st: ptr RawStatement, idx: int): int {.sqlite3linkage.}
444446
proc sqlite3_column_double*(st: ptr RawStatement, idx: int): float64 {.sqlite3linkage.}
@@ -576,6 +578,9 @@ proc `[]=`*[T](st: ref Statement, idx: int, val: Option[T]) =
576578
else:
577579
st[idx] = val.get
578580

581+
proc `[]=`*[T](st: ref Statement, name: string, value: T) =
582+
st[st.getParameterIndex(name)] = value
583+
579584
proc reset*(st: ref Statement) =
580585
st.raw.sqliteCheck sqlite3_reset(st.raw)
581586

@@ -594,7 +599,7 @@ proc withColumnBlob*(st: ref Statement, idx: int, recv: proc(vm: openarray[byte]
594599
let l = sqlite3_column_bytes(st.raw, idx)
595600
recv(cast[ptr UncheckedArray[byte]](p).toOpenArray(0, l))
596601

597-
proc getColumnType*(st: ref Statement, idx: int): SqliteDateType =
602+
proc getColumnType*(st: ref Statement, idx: int): SqliteDataType =
598603
sqlite3_column_type(st.raw, idx)
599604

600605
proc getColumn*(st: ref Statement, idx: int, T: typedesc[seq[byte]]): seq[byte] =
@@ -621,6 +626,31 @@ proc getColumn*[T](st: ref Statement, idx: int, _: typedesc[Option[T]]): Option[
621626
else:
622627
some(st.getColumn(idx, T))
623628

629+
type ColumnDef* = object
630+
st*: ref Statement
631+
idx*: int
632+
data_type*: SqliteDataType
633+
name*: string
634+
635+
proc columns*(st: ref Statement): seq[ref ColumnDef] =
636+
result = @[]
637+
var idx = 0
638+
let count = sqlite3_column_count(st.raw)
639+
while idx < count:
640+
let col = new(ColumnDef)
641+
col.st = st
642+
col.idx = idx
643+
col.data_type = sqlite3_column_type(st.raw, idx)
644+
col.name = $sqlite3_column_name(st.raw, idx)
645+
result.add(col)
646+
idx += 1
647+
648+
proc `[]`*(st: ref Statement, idx: int): ref ColumnDef =
649+
result = st.columns[idx]
650+
651+
proc `[]`*[T](col: ref ColumnDef, t: typedesc[T]): T =
652+
result = col.st.getColumn(col.idx, t)
653+
624654
proc unpack*[T: tuple](st: ref Statement, _: typedesc[T]): T =
625655
var idx = 0
626656
for value in result.fields:
@@ -647,3 +677,10 @@ proc execM*(db: var Database, sqls: varargs[string]) {.discardable.} =
647677
except CatchableError:
648678
discard db.exec "ROLLBACK"
649679
raise getCurrentException()
680+
681+
iterator lines*(st: ref Statement): seq[ref ColumnDef] =
682+
try:
683+
while st.step():
684+
yield st.columns()
685+
finally:
686+
st.reset()

0 commit comments

Comments
 (0)