@@ -4,7 +4,7 @@ export NULL, SQLiteDB, SQLiteStmt, ResultSet,
4
4
execute, query, tables, drop, create, append
5
5
6
6
type SQLiteException <: Exception
7
- msg:: String
7
+ msg:: AbstractString
8
8
end
9
9
10
10
include (" consts.jl" )
23
23
== (a:: ResultSet ,b:: ResultSet ) = a. colnames == b. colnames && a. values == b. values
24
24
include (" show.jl" )
25
25
26
- type SQLiteDB{T<: String }
26
+ type SQLiteDB{T<: AbstractString }
27
27
file:: T
28
28
handle:: Ptr{Void}
29
29
changes:: Int
@@ -48,7 +48,7 @@ sqliteopen(file::UTF16String,handle) = sqlite3_open16(file,handle)
48
48
sqliteerror () = throw (SQLiteException (bytestring (sqlite3_errmsg ())))
49
49
sqliteerror (db) = throw (SQLiteException (bytestring (sqlite3_errmsg (db. handle))))
50
50
51
- function SQLiteDB (file:: String = " " ;UTF16:: Bool = false )
51
+ function SQLiteDB (file:: AbstractString = " " ;UTF16:: Bool = false )
52
52
handle = [C_NULL ]
53
53
utf = UTF16 ? utf16 : utf8
54
54
file = isempty (file) ? file : expanduser (file)
@@ -83,7 +83,7 @@ sqliteprepare(db,sql,stmt,null) =
83
83
sqliteprepare (db:: SQLiteDB{UTF16String} ,sql,stmt,null) =
84
84
@CHECK db sqlite3_prepare16_v2 (db. handle,utf16 (sql),stmt,null)
85
85
86
- function SQLiteStmt {T} (db:: SQLiteDB{T} ,sql:: String )
86
+ function SQLiteStmt {T} (db:: SQLiteDB{T} ,sql:: AbstractString )
87
87
handle = [C_NULL ]
88
88
sqliteprepare (db,sql,handle,[C_NULL ])
89
89
stmt = SQLiteStmt (db,handle[1 ],convert (T,sql))
@@ -98,20 +98,40 @@ function Base.close(stmt::SQLiteStmt)
98
98
return
99
99
end
100
100
101
+ # bind a row to nameless parameters
102
+ function Base. bind (stmt:: SQLiteStmt , values:: Vector )
103
+ nparams = sqlite3_bind_parameter_count (stmt. handle)
104
+ @assert nparams == length (values) " you must provide values for all placeholders"
105
+ for i in 1 : nparams
106
+ @inbounds bind (stmt, i, values[i])
107
+ end
108
+ end
109
+ # bind a row to named parameters
110
+ function Base. bind {V} (stmt:: SQLiteStmt , values:: Dict{Symbol, V} )
111
+ nparams = sqlite3_bind_parameter_count (stmt. handle)
112
+ @assert nparams == length (values) " you must provide values for all placeholders"
113
+ for i in 1 : nparams
114
+ name = bytestring (sqlite3_bind_parameter_name (stmt. handle, i))
115
+ @assert ! isempty (name) " nameless parameters should be passed as a Vector"
116
+ # name is returned with the ':', '@' or '$' at the start
117
+ name = name[2 : end ]
118
+ bind (stmt, i, values[symbol (name)])
119
+ end
120
+ end
101
121
# Binding parameters to SQL statements
102
- function Base. bind (stmt:: SQLiteStmt ,name:: String ,val)
122
+ function Base. bind (stmt:: SQLiteStmt ,name:: AbstractString ,val)
103
123
i = sqlite3_bind_parameter_index (stmt. handle,name)
104
124
if i == 0
105
125
throw (SQLiteException (" SQL parameter $name not found in $stmt " ))
106
126
end
107
127
return bind (stmt,i,val)
108
128
end
109
- Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: FloatingPoint ) = @CHECK stmt. db sqlite3_bind_double (stmt. handle,i,float64 (val))
110
- Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: Int32 ) = @CHECK stmt. db sqlite3_bind_int (stmt. handle,i,val)
111
- Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: Int64 ) = @CHECK stmt. db sqlite3_bind_int64 (stmt. handle,i,val)
112
- Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: NullType ) = @CHECK stmt. db sqlite3_bind_null (stmt. handle,i)
113
- Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: String ) = @CHECK stmt. db sqlite3_bind_text (stmt. handle,i,val)
114
- Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: UTF16String ) = @CHECK stmt. db sqlite3_bind_text16 (stmt. handle,i,val)
129
+ Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: FloatingPoint ) = @CHECK stmt. db sqlite3_bind_double (stmt. handle,i,float64 (val))
130
+ Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: Int32 ) = @CHECK stmt. db sqlite3_bind_int (stmt. handle,i,val)
131
+ Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: Int64 ) = @CHECK stmt. db sqlite3_bind_int64 (stmt. handle,i,val)
132
+ Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: NullType ) = @CHECK stmt. db sqlite3_bind_null (stmt. handle,i)
133
+ Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: AbstractString ) = @CHECK stmt. db sqlite3_bind_text (stmt. handle,i,val)
134
+ Base. bind (stmt:: SQLiteStmt ,i:: Int ,val:: UTF16String ) = @CHECK stmt. db sqlite3_bind_text16 (stmt. handle,i,val)
115
135
# Fallback is BLOB and defaults to serializing the julia value
116
136
function sqlserialize (x)
117
137
t = IOBuffer ()
@@ -133,22 +153,23 @@ function execute(stmt::SQLiteStmt)
133
153
end
134
154
return r
135
155
end
136
- function execute (db:: SQLiteDB ,sql:: String )
156
+ function execute (db:: SQLiteDB ,sql:: AbstractString )
137
157
stmt = SQLiteStmt (db,sql)
138
158
execute (stmt)
139
159
return changes (db)
140
160
end
141
161
142
162
sqldeserialize (r) = deserialize (IOBuffer (r))
143
163
144
- function query (db:: SQLiteDB ,sql:: String )
164
+ function query (db:: SQLiteDB ,sql:: AbstractString , values = [] )
145
165
stmt = SQLiteStmt (db,sql)
166
+ bind (stmt, values)
146
167
status = execute (stmt)
147
168
ncols = sqlite3_column_count (stmt. handle)
148
169
if status == SQLITE_DONE || ncols == 0
149
170
return changes (db)
150
171
end
151
- colnames = Array (String ,ncols)
172
+ colnames = Array (AbstractString ,ncols)
152
173
results = Array (Any,ncols)
153
174
for i = 1 : ncols
154
175
colnames[i] = bytestring (sqlite3_column_name (stmt. handle,i- 1 ))
@@ -199,7 +220,7 @@ function transaction(db, mode="DEFERRED")
199
220
200
221
If mode is one of "", "DEFERRED", "IMMEDIATE" or "EXCLUSIVE" then a
201
222
transaction of that (or the default) type is started. Otherwise a savepoint
202
- is created whose name is mode converted to String .
223
+ is created whose name is mode converted to AbstractString .
203
224
=#
204
225
if uppercase (mode) in [" " , " DEFERRED" , " IMMEDIATE" , " EXCLUSIVE" ]
205
226
execute (db, " BEGIN $(mode) TRANSACTION;" )
@@ -236,15 +257,15 @@ commit(db, name) = execute(db, "RELEASE SAVEPOINT $(name);")
236
257
rollback (db) = execute (db, " ROLLBACK TRANSACTION;" )
237
258
rollback (db, name) = execute (db, " ROLLBACK TRANSACTION TO SAVEPOINT $(name) ;" )
238
259
239
- function drop (db:: SQLiteDB ,table:: String )
260
+ function drop (db:: SQLiteDB ,table:: AbstractString )
240
261
transaction (db) do
241
262
execute (db," drop table $table " )
242
263
end
243
264
execute (db," vacuum" )
244
265
return changes (db)
245
266
end
246
267
247
- function dropindex (db:: SQLiteDB ,index:: String )
268
+ function dropindex (db:: SQLiteDB ,index:: AbstractString )
248
269
transaction (db) do
249
270
execute (db," drop index $index " )
250
271
end
@@ -253,12 +274,12 @@ end
253
274
254
275
gettype {T<:Integer} (:: Type{T} ) = " INT"
255
276
gettype {T<:Real} (:: Type{T} ) = " REAL"
256
- gettype {T<:String } (:: Type{T} ) = " TEXT"
277
+ gettype {T<:AbstractString } (:: Type{T} ) = " TEXT"
257
278
gettype (:: Type ) = " BLOB"
258
279
gettype (:: Type{NullType} ) = " NULL"
259
280
260
- function create (db:: SQLiteDB ,name:: String ,table,
261
- colnames= String [],coltypes= DataType[];temp:: Bool = false )
281
+ function create (db:: SQLiteDB ,name:: AbstractString ,table,
282
+ colnames= AbstractString [],coltypes= DataType[];temp:: Bool = false )
262
283
N, M = size (table)
263
284
colnames = isempty (colnames) ? [" x$i " for i= 1 : M] : colnames
264
285
coltypes = isempty (coltypes) ? [typeof (table[1 ,i]) for i= 1 : M] : coltypes
@@ -284,7 +305,7 @@ function create(db::SQLiteDB,name::String,table,
284
305
return changes (db)
285
306
end
286
307
287
- function createindex (db:: SQLiteDB ,table:: String ,index:: String ,cols;unique:: Bool = true )
308
+ function createindex (db:: SQLiteDB ,table:: AbstractString ,index:: AbstractString ,cols;unique:: Bool = true )
288
309
u = unique ? " unique" : " "
289
310
transaction (db) do
290
311
execute (db," create $u index $index on $table ($cols )" )
@@ -293,7 +314,7 @@ function createindex(db::SQLiteDB,table::String,index::String,cols;unique::Bool=
293
314
return changes (db)
294
315
end
295
316
296
- function append (db:: SQLiteDB ,name:: String ,table)
317
+ function append (db:: SQLiteDB ,name:: AbstractString ,table)
297
318
N, M = size (table)
298
319
transaction (db) do
299
320
# insert statements
@@ -312,7 +333,7 @@ function append(db::SQLiteDB,name::String,table)
312
333
return return changes (db)
313
334
end
314
335
315
- function deleteduplicates (db,table:: String ,cols:: String )
336
+ function deleteduplicates (db,table:: AbstractString ,cols:: AbstractString )
316
337
transaction (db) do
317
338
execute (db," delete from $table where rowid not in (select max(rowid) from $table group by $cols );" )
318
339
end
0 commit comments