Skip to content

Commit e5b2869

Browse files
committed
Allow bytearrays to be stored as BLOBs.
Any object that is serialized is now put in a Serialization type then serialized. When sqldeserialize is called on a bytearray, it checks whether the deserialized array is a Serialization and if so returns the object it holds, otherwise returning the array.
1 parent 5ee41db commit e5b2869

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

src/SQLite.jl

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ immutable NullType end
1616
const NULL = NullType()
1717
Base.show(io::IO,::NullType) = print(io,"NULL")
1818

19+
# internal wrapper type to, in-effect, mark something which has been serialized
20+
type Serialization
21+
object
22+
end
23+
1924
type ResultSet
2025
colnames
2126
values::Vector{Any}
@@ -132,13 +137,18 @@ Base.bind(stmt::SQLiteStmt,i::Int,val::Int64) = @CHECK stmt.db sqlite3_
132137
Base.bind(stmt::SQLiteStmt,i::Int,val::NullType) = @CHECK stmt.db sqlite3_bind_null(stmt.handle,i)
133138
Base.bind(stmt::SQLiteStmt,i::Int,val::AbstractString) = @CHECK stmt.db sqlite3_bind_text(stmt.handle,i,val)
134139
Base.bind(stmt::SQLiteStmt,i::Int,val::UTF16String) = @CHECK stmt.db sqlite3_bind_text16(stmt.handle,i,val)
140+
Base.bind(stmt::SQLiteStmt,i::Int,val::Vector{UInt8}) = @CHECK stmt.db sqlite3_bind_blob(stmt.handle,i,val)
135141
# Fallback is BLOB and defaults to serializing the julia value
136142
function sqlserialize(x)
137143
t = IOBuffer()
138-
serialize(t,x)
144+
# deserialize will sometimes return a random object when called on an array
145+
# which has not been previously serialized, we can use this type to check
146+
# that the array has been serialized
147+
s = Serialization(x)
148+
serialize(t,s)
139149
return takebuf_array(t)
140150
end
141-
Base.bind(stmt::SQLiteStmt,i::Int,val) = @CHECK stmt.db sqlite3_bind_blob(stmt.handle,i,sqlserialize(val))
151+
Base.bind(stmt::SQLiteStmt,i::Int,val) = bind(stmt,i,sqlserialize(val))
142152
#TODO:
143153
#int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
144154
#int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
@@ -159,7 +169,23 @@ function execute(db::SQLiteDB,sql::AbstractString)
159169
return changes(db)
160170
end
161171

162-
sqldeserialize(r) = deserialize(IOBuffer(r))
172+
function sqldeserialize(r)
173+
# try blocks introduce new scope
174+
local v
175+
# deserialize will sometimes, but not consistently (see comment in
176+
# sqlserialize), throw an error when called on an object which hasn't been
177+
# previously serialized
178+
try
179+
v = deserialize(IOBuffer(r))
180+
catch
181+
return r
182+
end
183+
if isa(v, Serialization)
184+
return v.object
185+
else
186+
return r
187+
end
188+
end
163189

164190
function query(db::SQLiteDB,sql::AbstractString, values=[])
165191
stmt = SQLiteStmt(db,sql)

src/UDF.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ sqlreturn(context, val::Int64) = sqlite3_result_int64(context, val)
3030
sqlreturn(context, val::Float64) = sqlite3_result_double(context, val)
3131
sqlreturn(context, val::UTF16String) = sqlite3_result_text16(context, val)
3232
sqlreturn(context, val::AbstractString) = sqlite3_result_text(context, val)
33-
sqlreturn(context, val) = sqlite3_result_blob(context, sqlserialize(val))
33+
sqlreturn(context, val::Vector{UInt8}) = sqlite3_result_blob(context, sqlserialize(val))
3434

3535
sqlreturn(context, val::Bool) = sqlreturn(context, int(val))
36+
sqlreturn(context, val) = sqlreturn(context, sqlserialize(val))
3637

3738
# Internal method for generating an SQLite scalar function from
3839
# a Julia function name

0 commit comments

Comments
 (0)