1
+ using DataStreams
1
2
module SQLite
2
3
3
4
using Compat, NullableArrays, CSV, Libz, DataStreams
4
- import CSV. PointerString
5
-
6
- # Deprecated exports
7
- export NULL, SQLiteDB, SQLiteStmt, ResultSet,
8
- execute, query, tables, indices, columns, droptable, dropindex,
9
- create, createindex, append, deleteduplicates
10
-
11
- import Base: == , show, convert, bind, close
5
+ const PointerString = Data. PointerString
6
+ const NULLSTRING = Data. NULLSTRING
12
7
13
8
type SQLiteException <: Exception
14
9
msg:: AbstractString
17
12
include (" consts.jl" )
18
13
include (" api.jl" )
19
14
20
- # Custom NULL type
21
15
immutable NullType end
16
+ " custom NULL value for interacting with the SQLite database"
22
17
const NULL = NullType ()
23
18
show (io:: IO ,:: NullType ) = print (io," #NULL" )
24
19
25
- " internal wrapper type to, in-effect, mark something which has been serialized"
26
- immutable Serialization
27
- object
28
- end
29
-
30
20
# TODO : Support sqlite3_open_v2
31
21
# Normal constructor from filename
32
22
sqliteopen (file,handle) = sqlite3_open (file,handle)
33
23
sqliteopen (file:: UTF16String ,handle) = sqlite3_open16 (file,handle)
34
24
sqliteerror () = throw (SQLiteException (bytestring (sqlite3_errmsg ())))
35
25
sqliteerror (db) = throw (SQLiteException (bytestring (sqlite3_errmsg (db. handle))))
36
26
27
+ " represents an SQLite database, either backed by an on-disk file or in-memory"
37
28
type DB
38
29
file:: UTF8String
39
30
handle:: Ptr{Void}
40
31
changes:: Int
41
32
42
33
function DB (f:: UTF8String )
43
- handle = [ C_NULL ]
34
+ handle = Ref {Ptr{Void}} ()
44
35
f = isempty (f) ? f : expanduser (f)
45
36
if @OK sqliteopen (f,handle)
46
- db = new (f,handle[1 ],0 )
37
+ db = new (f,handle[],0 )
47
38
register (db, regexp, nargs= 2 , name= " regexp" )
48
39
finalizer (db, _close)
49
40
return db
50
41
else # error
51
- sqlite3_close (handle[1 ])
42
+ sqlite3_close (handle[])
52
43
sqliteerror ()
53
44
end
54
45
end
@@ -74,9 +65,9 @@ type Stmt
74
65
handle:: Ptr{Void}
75
66
76
67
function Stmt (db:: DB ,sql:: AbstractString )
77
- handle = [ C_NULL ]
78
- sqliteprepare (db,sql,handle,[ C_NULL ] )
79
- stmt = new (db,handle[1 ])
68
+ handle = Ref {Ptr{Void}} ()
69
+ sqliteprepare (db,sql,handle,Ref {Ptr{Void}} () )
70
+ stmt = new (db,handle[])
80
71
finalizer (stmt, _close)
81
72
return stmt
82
73
end
@@ -88,8 +79,7 @@ function _close(stmt::Stmt)
88
79
return
89
80
end
90
81
91
- sqliteprepare (db,sql,stmt,null) =
92
- @CHECK db sqlite3_prepare_v2 (db. handle,utf8 (sql),stmt,null)
82
+ sqliteprepare (db,sql,stmt,null) = @CHECK db sqlite3_prepare_v2 (db. handle,utf8 (sql),stmt,null)
93
83
94
84
# TO DEPRECATE
95
85
type SQLiteDB{T<: AbstractString }
@@ -140,8 +130,14 @@ bind!(stmt::Stmt,i::Int,val::PointerString) = (sqlite3_bind_text(stmt.handle,i,
140
130
bind! (stmt:: Stmt ,i:: Int ,val:: UTF16String ) = (sqlite3_bind_text16 (stmt. handle,i,val); return nothing )
141
131
# We may want to track the new ByteVec type proposed at https://github.com/JuliaLang/julia/pull/8964
142
132
# as the "official" bytes type instead of Vector{UInt8}
133
+ " bind a byte vector as an SQLite BLOB"
143
134
bind! (stmt:: Stmt ,i:: Int ,val:: Vector{UInt8} ) = (sqlite3_bind_blob (stmt. handle,i,val); return nothing )
144
135
# Fallback is BLOB and defaults to serializing the julia value
136
+ " internal wrapper type to, in-effect, mark something which has been serialized"
137
+ immutable Serialization
138
+ object
139
+ end
140
+
145
141
function sqlserialize (x)
146
142
t = IOBuffer ()
147
143
# deserialize will sometimes return a random object when called on an array
@@ -151,8 +147,21 @@ function sqlserialize(x)
151
147
serialize (t,s)
152
148
return takebuf_array (t)
153
149
end
154
- " bind `val` to the parameter at index `i`"
150
+ " fallback method to bind arbitrary julia `val` to the parameter at index `i` (object is serialized) "
155
151
bind! (stmt:: Stmt ,i:: Int ,val) = bind! (stmt,i,sqlserialize (val))
152
+
153
+ # magic bytes that indicate that a value is in fact a serialized julia value, instead of just a byte vector
154
+ const SERIALIZATION = UInt8[0x11 ,0x01 ,0x02 ,0x0d ,0x53 ,0x65 ,0x72 ,0x69 ,0x61 ,0x6c ,0x69 ,0x7a ,0x61 ,0x74 ,0x69 ,0x6f ,0x6e ,0x23 ]
155
+ function sqldeserialize (r)
156
+ ret = ccall (:memcmp , Int32, (Ptr{UInt8},Ptr{UInt8}, UInt),
157
+ SERIALIZATION, r, min (18 ,length (r)))
158
+ if ret == 0
159
+ v = deserialize (IOBuffer (r))
160
+ return v. object
161
+ else
162
+ return r
163
+ end
164
+ end
156
165
# TODO :
157
166
# int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
158
167
# int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
@@ -173,19 +182,6 @@ function execute!(db::DB,sql::AbstractString)
173
182
return execute! (stmt)
174
183
end
175
184
176
- const SERIALIZATION = UInt8[0x11 ,0x01 ,0x02 ,0x0d ,0x53 ,0x65 ,0x72 ,0x69 ,0x61 ,0x6c ,0x69 ,0x7a ,0x61 ,0x74 ,0x69 ,0x6f ,0x6e ,0x23 ]
177
- function sqldeserialize (r)
178
- ret = ccall (:memcmp , Int32, (Ptr{UInt8},Ptr{UInt8}, UInt),
179
- SERIALIZATION, r, min (18 ,length (r)))
180
-
181
- if ret == 0
182
- v = deserialize (IOBuffer (r))
183
- return v. object
184
- else
185
- return r
186
- end
187
- end
188
-
189
185
# Transaction-based commands
190
186
"""
191
187
Begin a transaction in the spedified `mode`, default = "DEFERRED".
@@ -271,6 +267,23 @@ function removeduplicates!(db,table::AbstractString,cols::AbstractString)
271
267
return
272
268
end
273
269
270
+ """
271
+ `SQLite.Source` implementes the `DataStreams` framework for interacting with SQLite databases
272
+ """
273
+ type Source <: Data.Source
274
+ schema:: Data.Schema
275
+ stmt:: Stmt
276
+ status:: Cint
277
+ end
278
+
279
+ " SQLite.Sink implements the `Sink` interface in the `DataStreams` framework"
280
+ type Sink <: Data.Sink # <: IO
281
+ schema:: Data.Schema
282
+ db:: DB
283
+ tablename:: UTF8String
284
+ stmt:: Stmt
285
+ end
286
+
274
287
include (" Source.jl" )
275
288
include (" Sink.jl" )
276
289
0 commit comments