Skip to content

Commit b6fe02d

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 b3a6871 commit b6fe02d

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/easy_sqlite3.nim

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
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`, newStatement, rows

src/easy_sqlite3/bindings.nim

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

227-
type SqliteDateType* = enum
227+
type SqliteDataType* = enum
228228
dt_integer = 1,
229229
dt_float = 2,
230230
dt_text = 3,
@@ -385,7 +385,9 @@ proc sqlite3_bind_pointer*(st: ptr RawStatement, idx: int, val: pointer, name: c
385385
proc sqlite3_bind_zeroblob64*(st: ptr RawStatement, idx: int, len: int): ResultCode {.sqlite3linkage.}
386386
proc sqlite3_changes*(st: ptr RawDatabase): int {.sqlite3linkage.}
387387
proc sqlite3_last_insert_rowid*(st: ptr RawDatabase): int {.sqlite3linkage.}
388-
proc sqlite3_column_type*(st: ptr RawStatement, idx: int): SqliteDateType {.sqlite3linkage.}
388+
proc sqlite3_column_count*(st: ptr RawStatement): int {.sqlite3linkage.}
389+
proc sqlite3_column_type*(st: ptr RawStatement, idx: int): SqliteDataType {.sqlite3linkage.}
390+
proc sqlite3_column_name*(st: ptr RawStatement, idx: int): cstring {.sqlite3linkage.}
389391
proc sqlite3_column_blob*(st: ptr RawStatement, idx: int): pointer {.sqlite3linkage.}
390392
proc sqlite3_column_bytes*(st: ptr RawStatement, idx: int): int {.sqlite3linkage.}
391393
proc sqlite3_column_double*(st: ptr RawStatement, idx: int): float64 {.sqlite3linkage.}
@@ -497,6 +499,9 @@ proc `[]=`*[T](st: ref Statement, idx: int, val: Option[T]) =
497499
else:
498500
st[idx] = val.get
499501

502+
proc `[]=`*[T](st: ref Statement, name: string, value: T) =
503+
st[st.getParameterIndex(name)] = value
504+
500505
proc reset*(st: ref Statement) =
501506
st.raw.sqliteCheck sqlite3_reset(st.raw)
502507

@@ -515,7 +520,7 @@ proc withColumnBlob*(st: ref Statement, idx: int, recv: proc(vm: openarray[byte]
515520
let l = sqlite3_column_bytes(st.raw, idx)
516521
recv(cast[ptr UncheckedArray[byte]](p).toOpenArray(0, l))
517522

518-
proc getColumnType*(st: ref Statement, idx: int): SqliteDateType =
523+
proc getColumnType*(st: ref Statement, idx: int): SqliteDataType =
519524
sqlite3_column_type(st.raw, idx)
520525

521526
proc getColumn*(st: ref Statement, idx: int, T: typedesc[seq[byte]]): seq[byte] =
@@ -542,6 +547,31 @@ proc getColumn*[T](st: ref Statement, idx: int, _: typedesc[Option[T]]): Option[
542547
else:
543548
some(st.getColumn(idx, T))
544549

550+
type ColumnDef* = object
551+
st*: ref Statement
552+
idx*: int
553+
data_type*: SqliteDataType
554+
name*: string
555+
556+
proc columns*(st: ref Statement): seq[ref ColumnDef] =
557+
result = @[]
558+
var idx = 0
559+
let count = sqlite3_column_count(st.raw)
560+
while idx < count:
561+
let col = new(ColumnDef)
562+
col.st = st
563+
col.idx = idx
564+
col.data_type = sqlite3_column_type(st.raw, idx)
565+
col.name = $sqlite3_column_name(st.raw, idx)
566+
result.add(col)
567+
idx += 1
568+
569+
proc `[]`*(st: ref Statement, idx: int): ref ColumnDef =
570+
result = st.columns[idx]
571+
572+
proc `[]`*[T](col: ref ColumnDef, t: typedesc[T]): T =
573+
result = col.st.getColumn(col.idx, t)
574+
545575
proc unpack*[T: tuple](st: ref Statement, _: typedesc[T]): T =
546576
var idx = 0
547577
for value in result.fields:
@@ -568,3 +598,10 @@ proc execM*(db: var Database, sqls: varargs[string]) {.discardable.} =
568598
except CatchableError:
569599
discard db.exec "ROLLBACK"
570600
raise getCurrentException()
601+
602+
iterator rows*(st: ref Statement): seq[ref ColumnDef] =
603+
try:
604+
while st.step():
605+
yield st.columns()
606+
finally:
607+
st.reset()

0 commit comments

Comments
 (0)