Skip to content

Commit d47af49

Browse files
committed
Project DECOUPLE updates
1 parent 5cdf8d9 commit d47af49

File tree

7 files changed

+346
-186
lines changed

7 files changed

+346
-186
lines changed

docs/index.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# SQLite.jl Documentation
2+
3+
```@contents
4+
```
5+
6+
## High-level interface
7+
```@docs
8+
SQLite.read
9+
SQLite.write
10+
```
11+
12+
## Lower-level utilities
13+
```@docs
14+
SQLite.Source
15+
SQLite.Sink
16+
SQLite.Options
17+
SQLite.parsefield
18+
SQLite.readline(::SQLite.Source)
19+
SQLite.readsplitline
20+
SQLite.countlines(::SQLite.Source)
21+
```

docs/make.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Documenter, SQLite
2+
3+
makedocs(
4+
modules = [SQLite],
5+
)
6+
7+
deploydocs(
8+
deps = Deps.pip("mkdocs", "python-markdown-math"),
9+
repo = "github.com/JuliaDB/SQLite.jl.git"
10+
)

src/SQLite.jl

Lines changed: 88 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
VERSION >= v"0.4.0-dev+6521" && __precompile__(true)
22
module SQLite
33

4-
using CSV, DataStreams, DataFrames, NullableArrays, WeakRefStrings
4+
using DataStreams, DataFrames, WeakRefStrings
55

6-
export Data
6+
export Data, DataFrame
77

88
if !isdefined(Core, :String)
99
typealias String UTF8String
@@ -23,7 +23,7 @@ include("consts.jl")
2323
include("api.jl")
2424

2525
immutable NullType end
26-
"custom NULL value for interacting with the SQLite database"
26+
# custom NULL value for interacting with the SQLite database
2727
const NULL = NullType()
2828
show(io::IO,::NullType) = print(io,"#NULL")
2929

@@ -34,7 +34,14 @@ sqliteopen(file::UTF16String,handle) = sqlite3_open16(file,handle)
3434
sqliteerror() = throw(SQLiteException(unsafe_string(sqlite3_errmsg())))
3535
sqliteerror(db) = throw(SQLiteException(unsafe_string(sqlite3_errmsg(db.handle))))
3636

37-
"represents an SQLite database, either backed by an on-disk file or in-memory"
37+
"""
38+
represents an SQLite database, either backed by an on-disk file or in-memory
39+
40+
Constructors:
41+
42+
* `SQLite.DB()` => in-memory SQLite database
43+
* `SQLite.DB(file)` => file-based SQLite database
44+
"""
3845
type DB
3946
file::String
4047
handle::Ptr{Void}
@@ -54,7 +61,6 @@ type DB
5461
end
5562
end
5663
end
57-
"`SQLite.DB()` creates an in-memory SQLite database"
5864
DB() = DB(":memory:")
5965

6066
function _close(db::DB)
@@ -92,15 +98,28 @@ sqliteprepare(db,sql,stmt,null) = @CHECK db sqlite3_prepare_v2(db.handle,sql,stm
9298
include("UDF.jl")
9399
export @sr_str, @register, register
94100

95-
"bind a row (`values`) to nameless parameters by index"
101+
"""
102+
`SQLite.bind!(stmt::SQLite.Stmt, values)`
103+
104+
bind `values` to parameters in a prepared SQL statement. Values can be:
105+
106+
* `Vector`; where each element will be bound to an SQL parameter by index order
107+
* `Dict`; where dict values will be bound to named SQL parameters by the dict key
108+
109+
Additional methods exist for working individual SQL parameters:
110+
111+
* `SQLite.bind!(stmt, name, val)`: bind a single value to a named SQL parameter
112+
* `SQLite.bind!(stmt, index, val)`: bind a single value to a SQL parameter by index number
113+
"""
114+
function bind! end
115+
96116
function bind!(stmt::Stmt, values::Vector)
97117
nparams = sqlite3_bind_parameter_count(stmt.handle)
98118
@assert nparams == length(values) "you must provide values for all placeholders"
99119
for i in 1:nparams
100120
@inbounds bind!(stmt, i, values[i])
101121
end
102122
end
103-
"bind a row (`Dict(:key => value)`) to named parameters"
104123
function bind!{V}(stmt::Stmt, values::Dict{Symbol, V})
105124
nparams = sqlite3_bind_parameter_count(stmt.handle)
106125
@assert nparams == length(values) "you must provide values for all placeholders"
@@ -113,7 +132,6 @@ function bind!{V}(stmt::Stmt, values::Dict{Symbol, V})
113132
end
114133
end
115134
# Binding parameters to SQL statements
116-
"bind `val` to the named parameter `name`"
117135
function bind!(stmt::Stmt,name::AbstractString,val)
118136
i::Int = sqlite3_bind_parameter_index(stmt.handle,name)
119137
if i == 0
@@ -135,10 +153,10 @@ function bind!(stmt::Stmt,i::Int,val::WeakRefString{UInt32})
135153
end
136154
# We may want to track the new ByteVec type proposed at https://github.com/JuliaLang/julia/pull/8964
137155
# as the "official" bytes type instead of Vector{UInt8}
138-
"bind a byte vector as an SQLite BLOB"
139156
bind!(stmt::Stmt,i::Int,val::Vector{UInt8}) = (sqlite3_bind_blob(stmt.handle,i,val); return nothing)
140157
# Fallback is BLOB and defaults to serializing the julia value
141-
"internal wrapper type to, in-effect, mark something which has been serialized"
158+
159+
# internal wrapper type to, in-effect, mark something which has been serialized
142160
immutable Serialization
143161
object
144162
end
@@ -152,7 +170,7 @@ function sqlserialize(x)
152170
serialize(t,s)
153171
return takebuf_array(t)
154172
end
155-
"fallback method to bind arbitrary julia `val` to the parameter at index `i` (object is serialized)"
173+
# fallback method to bind arbitrary julia `val` to the parameter at index `i` (object is serialized)
156174
bind!(stmt::Stmt,i::Int,val) = bind!(stmt,i,sqlserialize(val))
157175

158176
# magic bytes that indicate that a value is in fact a serialized julia value, instead of just a byte vector
@@ -171,7 +189,14 @@ end
171189
#int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
172190
#int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
173191

174-
"Execute a prepared SQLite statement"
192+
"""
193+
`SQLite.execute!(stmt::SQLite.Stmt)` => `Void`
194+
`SQLite.execute!(db::DB, sql::String)` => `Void`
195+
196+
Execute a prepared SQLite statement, not checking for or returning any results.
197+
"""
198+
function execute! end
199+
175200
function execute!(stmt::Stmt)
176201
r = sqlite3_step(stmt.handle)
177202
if r == SQLITE_DONE
@@ -181,27 +206,39 @@ function execute!(stmt::Stmt)
181206
end
182207
return r
183208
end
184-
"Prepare and execute an SQLite statement"
185209
function execute!(db::DB,sql::AbstractString)
186210
stmt = Stmt(db,sql)
187211
return execute!(stmt)
188212
end
189213

190-
"Escape SQLite identifiers (e.g. column, table or index names). Can be either
214+
"""
215+
`SQLite.esc_id(x::Union{String,Vector{String}})`
216+
217+
Escape SQLite identifiers (e.g. column, table or index names). Can be either
191218
a string, or a vector of strings (note does not check for null characters).
192-
A vector of identifiers will be separated by commas."
219+
A vector of identifiers will be separated by commas.
220+
"""
221+
function esc_id end
222+
193223
esc_id(x::AbstractString) = "\""*replace(x,"\"","\"\"")*"\""
194224
esc_id{S<:AbstractString}(X::AbstractVector{S}) = join(map(esc_id,X),',')
195225

196226

197227
# Transaction-based commands
198228
"""
199-
Begin a transaction in the spedified `mode`, default = "DEFERRED".
229+
`SQLite.transaction(db, mode="DEFERRED")`
230+
`SQLite.transaction(func, db)`
231+
232+
Begin a transaction in the specified `mode`, default = "DEFERRED".
200233
201234
If `mode` is one of "", "DEFERRED", "IMMEDIATE" or "EXCLUSIVE" then a
202235
transaction of that (or the default) type is started. Otherwise a savepoint
203236
is created whose name is `mode` converted to AbstractString.
237+
238+
In the second method, `func` is executed within a transaction (the transaction being committed upon successful execution)
204239
"""
240+
function transaction end
241+
205242
function transaction(db, mode="DEFERRED")
206243
execute!(db,"PRAGMA temp_store=MEMORY;")
207244
if uppercase(mode) in ["", "DEFERRED", "IMMEDIATE", "EXCLUSIVE"]
@@ -210,7 +247,6 @@ function transaction(db, mode="DEFERRED")
210247
execute!(db, "SAVEPOINT $(mode);")
211248
end
212249
end
213-
"Execute the function `f` within a transaction."
214250
function transaction(f::Function, db)
215251
# generate a random name for the savepoint
216252
name = string("SQLITE",randstring(10))
@@ -228,17 +264,33 @@ function transaction(f::Function, db)
228264
end
229265
end
230266

231-
"commit a transaction or named savepoint"
267+
"""
268+
`SQLite.commit(db)`
269+
`SQLite.commit(db, name)`
270+
271+
commit a transaction or named savepoint
272+
"""
273+
function commit end
274+
232275
commit(db) = execute!(db, "COMMIT TRANSACTION;")
233-
"commit a transaction or named savepoint"
234276
commit(db, name) = execute!(db, "RELEASE SAVEPOINT $(name);")
235277

236-
"rollback transaction or named savepoint"
278+
"""
279+
`SQLite.rollback(db)`
280+
`SQLite.rollback(db, name)`
281+
282+
rollback transaction or named savepoint
283+
"""
284+
function rollback end
285+
237286
rollback(db) = execute!(db, "ROLLBACK TRANSACTION;")
238-
"rollback transaction or named savepoint"
239287
rollback(db, name) = execute!(db, "ROLLBACK TRANSACTION TO SAVEPOINT $(name);")
240288

241-
"drop the SQLite table `table` from the database `db`; `ifexists=true` will prevent an error being thrown if `table` doesn't exist"
289+
"""
290+
`SQLite.drop!(db, table; ifexists::Bool=true)`
291+
292+
drop the SQLite table `table` from the database `db`; `ifexists=true` will prevent an error being thrown if `table` doesn't exist
293+
"""
242294
function drop!(db::DB, table::AbstractString; ifexists::Bool=false)
243295
exists = ifexists ? "IF EXISTS" : ""
244296
transaction(db) do
@@ -248,7 +300,11 @@ function drop!(db::DB, table::AbstractString; ifexists::Bool=false)
248300
return
249301
end
250302

251-
"drop the SQLite index `index` from the database `db`; `ifexists=true` will not return an error if `index` doesn't exist"
303+
"""
304+
`SQLite.dropindex!(db, index; ifexists::Bool=true)`
305+
306+
drop the SQLite index `index` from the database `db`; `ifexists=true` will not return an error if `index` doesn't exist
307+
"""
252308
function dropindex!(db::DB,index::AbstractString;ifexists::Bool=false)
253309
exists = ifexists ? "IF EXISTS" : ""
254310
transaction(db) do
@@ -258,6 +314,8 @@ function dropindex!(db::DB,index::AbstractString;ifexists::Bool=false)
258314
end
259315

260316
"""
317+
`SQLite.createindex!(db, table, index, cols; unique::Bool=true, ifnotexists::Bool=false)`
318+
261319
create the SQLite index `index` on the table `table` using `cols`, which may be a single column or vector of columns.
262320
`unique` specifies whether the index will be unique or not.
263321
`ifnotexists=true` will not throw an error if the index already exists
@@ -273,11 +331,15 @@ function createindex!{S<:AbstractString}(db::DB,table::AbstractString,index::Abs
273331
return
274332
end
275333

276-
"removes duplicate rows from `table` based on the values in `cols` which is an array of column names"
334+
"""
335+
`SQLite.removeduplicates!(db, table, cols::Vector)`
336+
337+
removes duplicate rows from `table` based on the values in `cols` which is an array of column names
338+
"""
277339
function removeduplicates!{T <: AbstractString}(db,table::AbstractString,cols::AbstractArray{T})
278340
colsstr = ""
279341
for c in cols
280-
colsstr = colsstr*esc_id(c)*","
342+
colsstr = colsstr * esc_id(c) * ","
281343
end
282344
colsstr = chop(colsstr)
283345
transaction(db) do
@@ -287,19 +349,7 @@ function removeduplicates!{T <: AbstractString}(db,table::AbstractString,cols::A
287349
return
288350
end
289351

290-
function removeduplicates!(db,table::AbstractString,cols::AbstractString)
291-
warn("This method is deprecated, please provide the column names as an array of column names rather than a single string.")
292-
transaction(db) do
293-
execute!(db,"DELETE FROM $(esc_id(table)) WHERE _ROWID_ NOT IN (SELECT max(_ROWID_) from $(esc_id(table)) GROUP BY $(esc_id(cols)));")
294-
end
295-
execute!(db,"ANALYZE $table")
296-
return
297-
end
298-
299-
300-
"""
301-
`SQLite.Source` implementes the `DataStreams` framework for interacting with SQLite databases
302-
"""
352+
"`SQLite.Source` implements the `Source` interface in the `DataStreams` framework"
303353
type Source <: Data.Source
304354
schema::Data.Schema
305355
stmt::Stmt

0 commit comments

Comments
 (0)