1111 DbConn * = PSqlite3 # # encapsulates a database connection
1212
1313 varcharType* = string
14+ blobType* = seq [byte ]
1415 intType* = int
1516 floatType* = float
1617 boolType* = bool
@@ -36,7 +37,15 @@ template startBindings*(s: PStmt; n: int) =
3637template bindParam * (db: DbConn ; s: PStmt ; idx: int ; x, t: untyped ) =
3738 # when not (x is t):
3839 # {.error: "type mismatch for query argument at position " & $idx.}
39- when t is int or t is int64 or t is bool :
40+ when t is blobType:
41+ let xs = x
42+ let blobPtr = if xs.len == 0 :
43+ cast [pointer ](nil )
44+ else :
45+ cast [pointer ](unsafeAddr (xs[0 ]))
46+ if bind_blob (s, idx.cint , blobPtr, xs.len.cint , SQLITE_STATIC ) != SQLITE_OK :
47+ dbError (db)
48+ elif t is int or t is int64 or t is bool :
4049 if bind_int64 (s, idx.cint , x.int64 ) != SQLITE_OK : dbError (db)
4150 elif t is string :
4251 if bind_text (s, idx.cint , cstring (x), x.len.cint , SQLITE_STATIC ) != SQLITE_OK :
@@ -75,7 +84,7 @@ template bindFromJson*(db: DbConn; s: PStmt; idx: int; x: JsonNode;
7584 t: typedesc [string ]) =
7685 doAssert x.kind == JString
7786 let xs = x.str
78- if bind_blob (s, idx.cint , cstring (xs), xs.len.cint , SQLITE_STATIC ) != SQLITE_OK :
87+ if bind_text (s, idx.cint , cstring (xs), xs.len.cint , SQLITE_STATIC ) != SQLITE_OK :
7988 dbError (db)
8089
8190template bindFromJson * (db: DbConn ; s: PStmt ; idx: int ; x: JsonNode ;
@@ -127,12 +136,27 @@ proc fillString(dest: var string; src: cstring; srcLen: int) =
127136 else : setLen (dest, srcLen)
128137 copyMem (unsafeAddr (dest[0 ]), src, srcLen)
129138
139+ proc fillBytes (dest: var seq [byte ]; src: pointer ; srcLen: int ) =
140+ if srcLen == 0 : return
141+ when defined (nimNoNilSeqs):
142+ setLen (dest, srcLen)
143+ else :
144+ if dest.isNil: dest = newSeq [byte ](srcLen)
145+ else : setLen (dest, srcLen)
146+ copyMem (unsafeAddr (dest[0 ]), src, srcLen)
147+
130148template bindResult * (db: DbConn ; s: PStmt ; idx: int ; dest: var string ;
131149 t: typedesc ; name: string ) =
132150 let srcLen = column_bytes (s, idx.cint )
133151 let src = column_text (s, idx.cint )
134152 fillString (dest, src, srcLen)
135153
154+ template bindResult * (db: DbConn ; s: PStmt ; idx: int ; dest: var blobType;
155+ t: typedesc ; name: string ) =
156+ let srcLen = column_bytes (s, idx.cint )
157+ let src = column_blob (s, idx.cint )
158+ fillBytes (dest, src, srcLen)
159+
136160template bindResult * (db: DbConn ; s: PStmt ; idx: int ; dest: float64 ;
137161 t: typedesc ; name: string ) =
138162 dest = column_double (s, idx.cint )
@@ -184,6 +208,17 @@ template bindToJson*(db: DbConn; s: PStmt; idx: int; obj: JsonNode;
184208 t: typedesc [int | int64 ]; name: string ) =
185209 obj[name] = newJInt (column_int64 (s, idx.cint ))
186210
211+ template bindToJson * (db: DbConn ; s: PStmt ; idx: int ; obj: JsonNode ;
212+ t: typedesc [blobType]; name: string ) =
213+ let srcLen = column_bytes (s, idx.cint )
214+ let src = column_blob (s, idx.cint )
215+ var data: blobType
216+ fillBytes (data, src, srcLen)
217+ let arr = newJArray ()
218+ for b in data:
219+ arr.add newJInt (int (b))
220+ obj[name] = arr
221+
187222template bindToJson * (db: DbConn ; s: PStmt ; idx: int ; obj: JsonNode ;
188223 t: typedesc [float64 ]; name: string ) =
189224 obj[name] = newJFloat (column_double (s, idx.cint ))
0 commit comments