diff --git a/.JuliaFormatter.toml b/.JuliaFormatter.toml new file mode 100644 index 0000000..2d202e5 --- /dev/null +++ b/.JuliaFormatter.toml @@ -0,0 +1,8 @@ +# Configuration file for JuliaFormatter.jl +# For more information, see: https://domluna.github.io/JuliaFormatter.jl/stable/config/ + +always_for_in = true +margin = 80 +remove_extra_newlines = true +separate_kwargs_with_semicolon = true +short_to_long_function_def = true diff --git a/docs/make.jl b/docs/make.jl index 2d3bbb7..a992771 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,17 +1,13 @@ using Documenter, SQLite makedocs(; - modules=[SQLite], - format=Documenter.HTML(), - pages=[ - "Home" => "index.md", - ], - repo="https://github.com/JuliaDatabases/SQLite.jl/blob/{commit}{path}#L{line}", - sitename="SQLite.jl", - authors="Jacob Quinn", - assets=String[], + modules = [SQLite], + format = Documenter.HTML(), + pages = ["Home" => "index.md"], + repo = "https://github.com/JuliaDatabases/SQLite.jl/blob/{commit}{path}#L{line}", + sitename = "SQLite.jl", + authors = "Jacob Quinn", + assets = String[], ) -deploydocs(; - repo="github.com/JuliaDatabases/SQLite.jl", -) +deploydocs(; repo = "github.com/JuliaDatabases/SQLite.jl") diff --git a/src/SQLite.jl b/src/SQLite.jl index 508fcbf..fadc25f 100644 --- a/src/SQLite.jl +++ b/src/SQLite.jl @@ -16,7 +16,9 @@ const DBHandle = Ptr{Cvoid} # SQLite3 DB connection handle const StmtHandle = Ptr{Cvoid} # SQLite3 prepared statement handle # Normal constructor from filename -sqliteexception(handle::DBHandle) = SQLiteException(unsafe_string(sqlite3_errmsg(handle))) +function sqliteexception(handle::DBHandle) + SQLiteException(unsafe_string(sqlite3_errmsg(handle))) +end function sqliteexception(handle::DBHandle, stmt::StmtHandle) errstr = unsafe_string(sqlite3_errmsg(handle)) stmt_text_handle = sqlite3_expanded_sql(stmt) @@ -27,7 +29,9 @@ function sqliteexception(handle::DBHandle, stmt::StmtHandle) end sqliteerror(handle::DBHandle) = throw(sqliteexception(handle)) -sqliteerror(handle::DBHandle, stmt::StmtHandle) = throw(sqliteexception(handle, stmt)) +function sqliteerror(handle::DBHandle, stmt::StmtHandle) + throw(sqliteexception(handle, stmt)) +end """ Internal wrapper that holds the handle to SQLite3 prepared statement. @@ -41,10 +45,10 @@ all its `SQLite._Stmt` objects are closed. """ mutable struct _Stmt handle::StmtHandle - params::Dict{Int, Any} + params::Dict{Int,Any} function _Stmt(handle::StmtHandle) - stmt = new(handle, Dict{Int, Any}()) + stmt = new(handle, Dict{Int,Any}()) finalizer(_close!, stmt) return stmt end @@ -82,7 +86,7 @@ The `SQLite.DB` will be automatically closed/shutdown when it goes out of scope mutable struct DB <: DBInterface.Connection file::String handle::DBHandle - stmts::Dict{_StmtId, _Stmt} # opened prepared statements + stmts::Dict{_StmtId,_Stmt} # opened prepared statements lastStmtId::_StmtId @@ -90,7 +94,7 @@ mutable struct DB <: DBInterface.Connection handle = Ref{DBHandle}() f = String(isempty(f) ? f : expanduser(f)) if @OK sqlite3_open(f, handle) - db = new(f, handle[], Dict{StmtHandle, _Stmt}(), 0) + db = new(f, handle[], Dict{StmtHandle,_Stmt}(), 0) finalizer(_close, db) return db else # error @@ -124,7 +128,9 @@ end sqliteerror(db::DB) = sqliteerror(db.handle) sqliteexception(db::DB) = sqliteexception(db.handle) -Base.show(io::IO, db::SQLite.DB) = print(io, string("SQLite.DB(", "\"$(db.file)\"", ")")) +function Base.show(io::IO, db::SQLite.DB) + print(io, string("SQLite.DB(", "\"$(db.file)\"", ")")) +end # prepare given sql statement function _Stmt(db::DB, sql::AbstractString) @@ -180,7 +186,8 @@ _stmt_safe(stmt::Stmt) = get(stmt.db.stmts, stmt.id, nothing) # get underlying _Stmt or throw if not found @inline function _stmt(stmt::Stmt) _st = _stmt_safe(stmt) - (_st === nothing) && throw(SQLiteException("Statement $(stmt.id) not found")) + (_st === nothing) && + throw(SQLiteException("Statement $(stmt.id) not found")) return _st end @@ -201,8 +208,14 @@ function DBInterface.close!(stmt::Stmt) return stmt end -sqliteprepare(db::DB, sql::AbstractString, stmt::Ref{StmtHandle}, null::Ref{StmtHandle}) = +function sqliteprepare( + db::DB, + sql::AbstractString, + stmt::Ref{StmtHandle}, + null::Ref{StmtHandle}, +) @CHECK db sqlite3_prepare_v2(db.handle, sql, stmt, null) +end include("UDF.jl") export @sr_str @@ -269,28 +282,40 @@ function bind! end function bind!(stmt::_Stmt, params::DBInterface.NamedStatementParams) nparams = sqlite3_bind_parameter_count(stmt.handle) - (nparams <= length(params)) || throw(SQLiteException("values should be provided for all query placeholders")) + (nparams <= length(params)) || throw( + SQLiteException("values should be provided for all query placeholders"), + ) for i in 1:nparams name = unsafe_string(sqlite3_bind_parameter_name(stmt.handle, i)) - isempty(name) && throw(SQLiteException("nameless parameters should be passed as a Vector")) + isempty(name) && throw( + SQLiteException("nameless parameters should be passed as a Vector"), + ) # name is returned with the ':', '@' or '$' at the start sym = Symbol(name[2:end]) - haskey(params, sym) || throw(SQLiteException("`$name` not found in values keyword arguments to bind to sql statement")) + haskey(params, sym) || throw( + SQLiteException( + "`$name` not found in values keyword arguments to bind to sql statement", + ), + ) bind!(stmt, i, params[sym]) end end function bind!(stmt::_Stmt, values::DBInterface.PositionalStatementParams) nparams = sqlite3_bind_parameter_count(stmt.handle) - (nparams == length(values)) || throw(SQLiteException("values should be provided for all query placeholders")) + (nparams == length(values)) || throw( + SQLiteException("values should be provided for all query placeholders"), + ) for i in 1:nparams @inbounds bind!(stmt, i, values[i]) end end -bind!(stmt::Stmt, values::DBInterface.StatementParams) = bind!(_stmt(stmt), values) +function bind!(stmt::Stmt, values::DBInterface.StatementParams) + bind!(_stmt(stmt), values) +end -bind!(stmt::Union{_Stmt, Stmt}; kwargs...) = bind!(stmt, kwargs.data) +bind!(stmt::Union{_Stmt,Stmt}; kwargs...) = bind!(stmt, kwargs.data) # Binding parameters to SQL statements function bind!(stmt::_Stmt, name::AbstractString, val::Any) @@ -302,23 +327,99 @@ function bind!(stmt::_Stmt, name::AbstractString, val::Any) end # binding method for internal _Stmt class -bind!(stmt::_Stmt, i::Integer, val::AbstractFloat) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_double(stmt.handle, i, Float64(val)); return nothing) -bind!(stmt::_Stmt, i::Integer, val::Int32) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_int(stmt.handle, i, val); return nothing) -bind!(stmt::_Stmt, i::Integer, val::Int64) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_int64(stmt.handle, i, val); return nothing) -bind!(stmt::_Stmt, i::Integer, val::Missing) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_null(stmt.handle, i); return nothing) -bind!(stmt::_Stmt, i::Integer, val::Nothing) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_null(stmt.handle, i); return nothing) -bind!(stmt::_Stmt, i::Integer, val::AbstractString) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_text(stmt.handle, i, val); return nothing) -bind!(stmt::_Stmt, i::Integer, val::WeakRefString{UInt8}) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_text(stmt.handle, i, val.ptr, val.len); return nothing) -bind!(stmt::_Stmt, i::Integer, val::WeakRefString{UInt16}) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_text16(stmt.handle, i, val.ptr, val.len*2); return nothing) -bind!(stmt::_Stmt, i::Integer, val::Bool) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_int(stmt.handle, i, Int32(val)); return nothing) -bind!(stmt::_Stmt, i::Integer, val::Vector{UInt8}) = (stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_blob(stmt.handle, i, val); return nothing) +function bind!(stmt::_Stmt, i::Integer, val::AbstractFloat) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_double( + stmt.handle, + i, + Float64(val), + ); return nothing + ) +end +function bind!(stmt::_Stmt, i::Integer, val::Int32) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_int( + stmt.handle, + i, + val, + ); return nothing + ) +end +function bind!(stmt::_Stmt, i::Integer, val::Int64) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_int64( + stmt.handle, + i, + val, + ); return nothing + ) +end +function bind!(stmt::_Stmt, i::Integer, val::Missing) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_null(stmt.handle, i); return nothing + ) +end +function bind!(stmt::_Stmt, i::Integer, val::Nothing) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_null(stmt.handle, i); return nothing + ) +end +function bind!(stmt::_Stmt, i::Integer, val::AbstractString) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_text( + stmt.handle, + i, + val, + ); return nothing + ) +end +function bind!(stmt::_Stmt, i::Integer, val::WeakRefString{UInt8}) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_text( + stmt.handle, + i, + val.ptr, + val.len, + ); return nothing + ) +end +function bind!(stmt::_Stmt, i::Integer, val::WeakRefString{UInt16}) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_text16( + stmt.handle, + i, + val.ptr, + val.len * 2, + ); return nothing + ) +end +function bind!(stmt::_Stmt, i::Integer, val::Bool) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_int( + stmt.handle, + i, + Int32(val), + ); return nothing + ) +end +function bind!(stmt::_Stmt, i::Integer, val::Vector{UInt8}) + ( + stmt.params[i] = val; @CHECK stmt.db sqlite3_bind_blob( + stmt.handle, + i, + val, + ); return nothing + ) +end # Fallback is BLOB and defaults to serializing the julia value -bind!(stmt::Stmt, param::Union{Integer, AbstractString}, val::Any) = bind!(_stmt(stmt), param, val) +function bind!(stmt::Stmt, param::Union{Integer,AbstractString}, val::Any) + bind!(_stmt(stmt), param, val) +end # internal wrapper mutable struct to, in-effect, mark something which has been serialized struct Serialized - object + object::Any end function sqlserialize(x) @@ -345,22 +446,32 @@ function sqldeserialize(r) if sizeof(r) < sizeof(SERIALIZATION) return r end - ret = ccall(:memcmp, Int32, (Ptr{UInt8}, Ptr{UInt8}, UInt), - SERIALIZATION, r, min(sizeof(SERIALIZATION), sizeof(r))) + ret = ccall( + :memcmp, + Int32, + (Ptr{UInt8}, Ptr{UInt8}, UInt), + SERIALIZATION, + r, + min(sizeof(SERIALIZATION), sizeof(r)), + ) if ret == 0 try v = Serialization.deserialize(IOBuffer(r)) return v.object catch e - throw(SerializeError("Error deserializing non-primitive value out of database; this is probably due to using SQLite.jl with a different Julia version than was used to originally serialize the database values. The same Julia version that was used to serialize should be used to extract the database values into a different format (csv file, feather file, etc.) and then loaded back into the sqlite database with the current Julia version.")) + throw( + SerializeError( + "Error deserializing non-primitive value out of database; this is probably due to using SQLite.jl with a different Julia version than was used to originally serialize the database values. The same Julia version that was used to serialize should be used to extract the database values into a different format (csv file, feather file, etc.) and then loaded back into the sqlite database with the current Julia version.", + ), + ) end else return r end end #TODO: - #int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); - #int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +#int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); +#int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); # get julia type for given column of the given statement function juliatype(handle, col) @@ -382,21 +493,29 @@ function juliatype(handle, col) end # convert SQLite stored type into Julia equivalent -juliatype(x::Integer) = +function juliatype(x::Integer) x == SQLITE_INTEGER ? Int64 : x == SQLITE_FLOAT ? Float64 : - x == SQLITE_TEXT ? String : - x == SQLITE_NULL ? Missing : - Any + x == SQLITE_TEXT ? String : x == SQLITE_NULL ? Missing : Any +end # convert SQLite declared type into Julia equivalent, # fall back to default (stored type), if no good match -function juliatype(decl_typestr::AbstractString, - default::Type = Any) +function juliatype(decl_typestr::AbstractString, default::Type = Any) typeuc = uppercase(decl_typestr) # try to match the type affinities described in the "Affinity Name Examples" section # of https://www.sqlite.org/datatype3.html - if typeuc in ("INTEGER", "INT", "TINYINT", "SMALLINT", "MEDIUMINT", "BIGINT", "UNSIGNED BIG INT", "INT2", "INT8") + if typeuc in ( + "INTEGER", + "INT", + "TINYINT", + "SMALLINT", + "MEDIUMINT", + "BIGINT", + "UNSIGNED BIG INT", + "INT2", + "INT8", + ) return Int64 elseif typeuc in ("NUMERIC", "REAL", "FLOAT", "DOUBLE", "DOUBLE PRECISION") return Float64 @@ -408,7 +527,10 @@ function juliatype(decl_typestr::AbstractString, return default # FIXME elseif typeuc == "TIMESTAMP" return default # FIXME - elseif occursin(r"^N?V?A?R?Y?I?N?G?\s*CHARA?C?T?E?R?T?E?X?T?\s*\(?\d*\)?$"i, typeuc) + elseif occursin( + r"^N?V?A?R?Y?I?N?G?\s*CHARA?C?T?E?R?T?E?X?T?\s*\(?\d*\)?$"i, + typeuc, + ) return String elseif occursin(r"^NUMERIC\(\d+,\d+\)$", typeuc) return Float64 @@ -417,11 +539,21 @@ function juliatype(decl_typestr::AbstractString, end end -sqlitevalue(::Type{T}, handle, col) where {T <: Union{Base.BitSigned, Base.BitUnsigned}} = convert(T, sqlite3_column_int64(handle, col)) -const FLOAT_TYPES = Union{Float16, Float32, Float64} # exclude BigFloat -sqlitevalue(::Type{T}, handle, col) where {T <: FLOAT_TYPES} = convert(T, sqlite3_column_double(handle, col)) +function sqlitevalue( + ::Type{T}, + handle, + col, +) where {T<:Union{Base.BitSigned,Base.BitUnsigned}} + convert(T, sqlite3_column_int64(handle, col)) +end +const FLOAT_TYPES = Union{Float16,Float32,Float64} # exclude BigFloat +function sqlitevalue(::Type{T}, handle, col) where {T<:FLOAT_TYPES} + convert(T, sqlite3_column_double(handle, col)) +end #TODO: test returning a WeakRefString instead of calling `unsafe_string` -sqlitevalue(::Type{T}, handle, col) where {T <: AbstractString} = convert(T, unsafe_string(sqlite3_column_text(handle, col))) +function sqlitevalue(::Type{T}, handle, col) where {T<:AbstractString} + convert(T, unsafe_string(sqlite3_column_text(handle, col))) +end function sqlitevalue(::Type{T}, handle, col) where {T} blob = convert(Ptr{UInt8}, sqlite3_column_blob(handle, col)) b = sqlite3_column_bytes(handle, col) @@ -440,8 +572,8 @@ sqlitetype_(::Type) = "BLOB" # fallback sqlitetype(::Type{Missing}) = "NULL" sqlitetype(::Type{Nothing}) = "NULL" -sqlitetype(::Type{Union{T, Missing}}) where T = sqlitetype_(T) -sqlitetype(::Type{T}) where T = string(sqlitetype_(T), " NOT NULL") +sqlitetype(::Type{Union{T,Missing}}) where {T} = sqlitetype_(T) +sqlitetype(::Type{T}) where {T} = string(sqlitetype_(T), " NOT NULL") """ SQLite.execute(db::SQLite.DB, sql::AbstractString, [params]) -> Int @@ -459,7 +591,7 @@ To get the results of a SQL query, it is recommended to use [`DBInterface.execut """ function execute end -function execute(db::DB, stmt::_Stmt, params::DBInterface.StatementParams=()) +function execute(db::DB, stmt::_Stmt, params::DBInterface.StatementParams = ()) sqlite3_reset(stmt.handle) bind!(stmt, params) r = sqlite3_step(stmt.handle) @@ -473,13 +605,18 @@ function execute(db::DB, stmt::_Stmt, params::DBInterface.StatementParams=()) return r end -execute(stmt::Stmt, params::DBInterface.StatementParams) = +function execute(stmt::Stmt, params::DBInterface.StatementParams) execute(stmt.db, _stmt(stmt), params) +end execute(stmt::Stmt; kwargs...) = execute(stmt, values(kwargs)) -function execute(db::DB, sql::AbstractString, params::DBInterface.StatementParams) - # prepare without registering _Stmt in DB +function execute( + db::DB, + sql::AbstractString, + params::DBInterface.StatementParams, +) + # prepare without registering _Stmt in DB _stmt = _Stmt(db, sql) try return execute(db, _stmt, params) @@ -488,7 +625,9 @@ function execute(db::DB, sql::AbstractString, params::DBInterface.StatementParam end end -execute(db::DB, sql::AbstractString; kwargs...) = execute(db, sql, values(kwargs)) +function execute(db::DB, sql::AbstractString; kwargs...) + execute(db, sql, values(kwargs)) +end """ SQLite.esc_id(x::Union{AbstractString,Vector{AbstractString}}) @@ -535,8 +674,10 @@ julia> DBInterface.execute(db,"SELECT * FROM temp WHERE label IN (\$(SQLite.esc_ """ function esc_id end -esc_id(x::AbstractString) = "\"" * replace(x, "\""=>"\"\"") * "\"" -esc_id(X::AbstractVector{S}) where {S <: AbstractString} = join(map(esc_id, X), ',') +esc_id(x::AbstractString) = "\"" * replace(x, "\"" => "\"\"") * "\"" +function esc_id(X::AbstractVector{S}) where {S<:AbstractString} + join(map(esc_id, X), ',') +end # Transaction-based commands """ @@ -553,7 +694,7 @@ In the second method, `func` is executed within a transaction (the transaction b """ function transaction end -function transaction(db::DB, mode="DEFERRED") +function transaction(db::DB, mode = "DEFERRED") execute(db, "PRAGMA temp_store=MEMORY;") if uppercase(mode) in ["", "DEFERRED", "IMMEDIATE", "EXCLUSIVE"] execute(db, "BEGIN $(mode) TRANSACTION;") @@ -601,14 +742,16 @@ rollback transaction or named savepoint function rollback end rollback(db::DB) = execute(db, "ROLLBACK TRANSACTION;") -rollback(db::DB, name::AbstractString) = execute(db, "ROLLBACK TRANSACTION TO SAVEPOINT $(name);") +function rollback(db::DB, name::AbstractString) + execute(db, "ROLLBACK TRANSACTION TO SAVEPOINT $(name);") +end """ SQLite.drop!(db, table; ifexists::Bool=true) drop the SQLite table `table` from the database `db`; `ifexists=true` will prevent an error being thrown if `table` doesn't exist """ -function drop!(db::DB, table::AbstractString; ifexists::Bool=false) +function drop!(db::DB, table::AbstractString; ifexists::Bool = false) exists = ifexists ? "IF EXISTS" : "" transaction(db) do execute(db, "DROP TABLE $exists $(esc_id(table))") @@ -622,7 +765,7 @@ end drop the SQLite index `index` from the database `db`; `ifexists=true` will not return an error if `index` doesn't exist """ -function dropindex!(db::DB, index::AbstractString; ifexists::Bool=false) +function dropindex!(db::DB, index::AbstractString; ifexists::Bool = false) exists = ifexists ? "IF EXISTS" : "" transaction(db) do execute(db, "DROP INDEX $exists $(esc_id(index))") @@ -638,12 +781,21 @@ which may be a single column or vector of columns. `unique` specifies whether the index will be unique or not. `ifnotexists=true` will not throw an error if the index already exists """ -function createindex!(db::DB, table::AbstractString, index::AbstractString, cols::Union{S, AbstractVector{S}}; - unique::Bool=true, ifnotexists::Bool=false) where {S <: AbstractString} +function createindex!( + db::DB, + table::AbstractString, + index::AbstractString, + cols::Union{S,AbstractVector{S}}; + unique::Bool = true, + ifnotexists::Bool = false, +) where {S<:AbstractString} u = unique ? "UNIQUE" : "" exists = ifnotexists ? "IF NOT EXISTS" : "" transaction(db) do - execute(db, "CREATE $u INDEX $exists $(esc_id(index)) ON $(esc_id(table)) ($(esc_id(cols)))") + execute( + db, + "CREATE $u INDEX $exists $(esc_id(index)) ON $(esc_id(table)) ($(esc_id(cols)))", + ) end execute(db, "ANALYZE $index") return @@ -657,18 +809,25 @@ Removes duplicate rows from `table` based on the values in `cols`, which is an a A convenience method for the common task of removing duplicate rows in a dataset according to some subset of columns that make up a "primary key". """ -function removeduplicates!(db::DB, table::AbstractString, cols::AbstractArray{T}) where {T <: AbstractString} +function removeduplicates!( + db::DB, + table::AbstractString, + cols::AbstractArray{T}, +) where {T<:AbstractString} colsstr = "" for c in cols - colsstr = colsstr * esc_id(c) * "," + colsstr = colsstr * esc_id(c) * "," end colsstr = chop(colsstr) transaction(db) do - execute(db, "DELETE FROM $(esc_id(table)) WHERE _ROWID_ NOT IN (SELECT max(_ROWID_) from $(esc_id(table)) GROUP BY $(colsstr));") + execute( + db, + "DELETE FROM $(esc_id(table)) WHERE _ROWID_ NOT IN (SELECT max(_ROWID_) from $(esc_id(table)) GROUP BY $(colsstr));", + ) end execute(db, "ANALYZE $table") return - end +end include("tables.jl") @@ -677,9 +836,20 @@ include("tables.jl") returns a list of tables in `db` """ -function tables(db::DB, sink=columntable) - tblnames = DBInterface.execute(sink, db, "SELECT name FROM sqlite_master WHERE type='table';") - return [DBTable(tbl, Tables.schema(DBInterface.execute(db,"SELECT * FROM $(tbl) LIMIT 0"))) for tbl in tblnames.name] +function tables(db::DB, sink = columntable) + tblnames = DBInterface.execute( + sink, + db, + "SELECT name FROM sqlite_master WHERE type='table';", + ) + return [ + DBTable( + tbl, + Tables.schema( + DBInterface.execute(db, "SELECT * FROM $(tbl) LIMIT 0"), + ), + ) for tbl in tblnames.name + ] end """ @@ -687,14 +857,22 @@ end returns a list of indices in `db` """ -indices(db::DB, sink=columntable) = DBInterface.execute(sink, db, "SELECT name FROM sqlite_master WHERE type='index';") +function indices(db::DB, sink = columntable) + DBInterface.execute( + sink, + db, + "SELECT name FROM sqlite_master WHERE type='index';", + ) +end """ SQLite.columns(db, table, sink=columntable) returns a list of columns in `table` """ -columns(db::DB, table::AbstractString, sink=columntable) = DBInterface.execute(sink, db, "PRAGMA table_info($(esc_id(table)))") +function columns(db::DB, table::AbstractString, sink = columntable) + DBInterface.execute(sink, db, "PRAGMA table_info($(esc_id(table)))") +end """ SQLite.last_insert_rowid(db) @@ -708,8 +886,14 @@ last_insert_rowid(db::DB) = sqlite3_last_insert_rowid(db.handle) Enables extension loading (off by default) on the sqlite database `db`. Pass `false` as the second argument to disable. """ -function enable_load_extension(db::DB, enable::Bool=true) - ccall((:sqlite3_enable_load_extension, SQLite.libsqlite), Cint, (Ptr{Cvoid}, Cint), db.handle, enable) +function enable_load_extension(db::DB, enable::Bool = true) + ccall( + (:sqlite3_enable_load_extension, SQLite.libsqlite), + Cint, + (Ptr{Cvoid}, Cint), + db.handle, + enable, + ) end """ @@ -717,10 +901,8 @@ end Set a busy handler that sleeps for a specified amount of milliseconds when a table is locked. After at least ms milliseconds of sleeping, the handler will return 0, causing sqlite to return SQLITE_BUSY. """ -function busy_timeout(db::DB, ms::Integer=0) +function busy_timeout(db::DB, ms::Integer = 0) sqlite3_busy_timeout(db.handle, ms) end - - end # module diff --git a/src/UDF.jl b/src/UDF.jl index 30e1a96..fc126bd 100644 --- a/src/UDF.jl +++ b/src/UDF.jl @@ -30,24 +30,28 @@ see [below](@ref regex). """ function sqlreturn end -sqlreturn(context, ::Missing) = sqlite3_result_null(context) -sqlreturn(context, val::Int32) = sqlite3_result_int(context, val) -sqlreturn(context, val::Int64) = sqlite3_result_int64(context, val) -sqlreturn(context, val::Float64) = sqlite3_result_double(context, val) +sqlreturn(context, ::Missing) = sqlite3_result_null(context) +sqlreturn(context, val::Int32) = sqlite3_result_int(context, val) +sqlreturn(context, val::Int64) = sqlite3_result_int64(context, val) +sqlreturn(context, val::Float64) = sqlite3_result_double(context, val) sqlreturn(context, val::AbstractString) = sqlite3_result_text(context, val) -sqlreturn(context, val::Vector{UInt8}) = sqlite3_result_blob(context, val) +sqlreturn(context, val::Vector{UInt8}) = sqlite3_result_blob(context, val) sqlreturn(context, val::Bool) = sqlreturn(context, Int(val)) sqlreturn(context, val) = sqlreturn(context, sqlserialize(val)) # Internal method for generating an SQLite scalar function from # a Julia function name -function scalarfunc(func,fsym=Symbol(string(func))) +function scalarfunc(func, fsym = Symbol(string(func))) # check if name defined in Base so we don't clobber Base methods - nm = isdefined(Base,fsym) ? :(Base.$fsym) : fsym + nm = isdefined(Base, fsym) ? :(Base.$fsym) : fsym return quote #nm needs to be a symbol or expr, i.e. :sin or :(Base.sin) - function $(nm)(context::Ptr{Cvoid}, nargs::Cint, values::Ptr{Ptr{Cvoid}}) + function $(nm)( + context::Ptr{Cvoid}, + nargs::Cint, + values::Ptr{Ptr{Cvoid}}, + ) args = [SQLite.sqlvalue(values, i) for i in 1:nargs] ret = $(func)(args...) SQLite.sqlreturn(context, ret) @@ -74,21 +78,30 @@ function bytestoint(ptr::Ptr{UInt8}, start::Int, len::Int) return htol(s) end -function stepfunc(init, func, fsym=Symbol(string(func)*"_step")) - nm = isdefined(Base,fsym) ? :(Base.$fsym) : fsym +function stepfunc(init, func, fsym = Symbol(string(func) * "_step")) + nm = isdefined(Base, fsym) ? :(Base.$fsym) : fsym return quote - function $(nm)(context::Ptr{Cvoid}, nargs::Cint, values::Ptr{Ptr{Cvoid}}) + function $(nm)( + context::Ptr{Cvoid}, + nargs::Cint, + values::Ptr{Ptr{Cvoid}}, + ) args = [sqlvalue(values, i) for i in 1:nargs] intsize = sizeof(Int) ptrsize = sizeof(Ptr) acsize = intsize + ptrsize - acptr = convert(Ptr{UInt8}, sqlite3_aggregate_context(context, acsize)) + acptr = + convert(Ptr{UInt8}, sqlite3_aggregate_context(context, acsize)) # acptr will be zeroed-out if this is the first iteration ret = ccall( - :memcmp, Cint, (Ptr{UInt8}, Ptr{UInt8}, Cuint), - zeros(UInt8, acsize), acptr, acsize, + :memcmp, + Cint, + (Ptr{UInt8}, Ptr{UInt8}, Cuint), + zeros(UInt8, acsize), + acptr, + acsize, ) if ret == 0 acval = $(init) @@ -101,7 +114,8 @@ function stepfunc(init, func, fsym=Symbol(string(func)*"_step")) valsize = bytestoint(acptr, 1, intsize) # ptr to serialized value is last sizeof(Ptr) bytes valptr = reinterpret( - Ptr{UInt8}, bytestoint(acptr, intsize+1, ptrsize) + Ptr{UInt8}, + bytestoint(acptr, intsize + 1, ptrsize), ) # deserialize the value pointed to by valptr acvalbuf = zeros(UInt8, valsize) @@ -135,12 +149,12 @@ function stepfunc(init, func, fsym=Symbol(string(func)*"_step")) unsafe_copyto!( acptr, pointer(reinterpret(UInt8, [newsize])), - intsize + intsize, ) # copy the address of the pointer to the serialized value valarr = reinterpret(UInt8, [valptr]) for i in 1:length(valarr) - unsafe_store!(acptr, valarr[i], intsize+i) + unsafe_store!(acptr, valarr[i], intsize + i) end nothing end @@ -148,10 +162,14 @@ function stepfunc(init, func, fsym=Symbol(string(func)*"_step")) end end -function finalfunc(init, func, fsym=Symbol(string(func)*"_final")) - nm = isdefined(Base,fsym) ? :(Base.$fsym) : fsym +function finalfunc(init, func, fsym = Symbol(string(func) * "_final")) + nm = isdefined(Base, fsym) ? :(Base.$fsym) : fsym return quote - function $(nm)(context::Ptr{Cvoid}, nargs::Cint, values::Ptr{Ptr{Cvoid}}) + function $(nm)( + context::Ptr{Cvoid}, + nargs::Cint, + values::Ptr{Ptr{Cvoid}}, + ) acptr = convert(Ptr{UInt8}, sqlite3_aggregate_context(context, 0)) # step function wasn't run @@ -166,7 +184,8 @@ function finalfunc(init, func, fsym=Symbol(string(func)*"_final")) valsize = bytestoint(acptr, 1, intsize) # load ptr valptr = reinterpret( - Ptr{UInt8}, bytestoint(acptr, intsize+1, ptrsize) + Ptr{UInt8}, + bytestoint(acptr, intsize + 1, ptrsize), ) # load value @@ -205,13 +224,19 @@ end Register a scalar (first method) or aggregate (second method) function with a [`SQLite.DB`](@ref). """ -function register(db, func::Function; nargs::Int=-1, name::AbstractString=string(func), isdeterm::Bool=true) +function register( + db, + func::Function; + nargs::Int = -1, + name::AbstractString = string(func), + isdeterm::Bool = true, +) @assert nargs <= 127 "use -1 if > 127 arguments are needed" # assume any negative number means a varargs function nargs < -1 && (nargs = -1) @assert sizeof(name) <= 255 "size of function name must be <= 255" - f = eval(scalarfunc(func,Symbol(name))) + f = eval(scalarfunc(func, Symbol(name))) cfunc = @cfunction($f, Cvoid, (Ptr{Cvoid}, Cint, Ptr{Ptr{Cvoid}})) # TODO: allow the other encodings @@ -219,15 +244,28 @@ function register(db, func::Function; nargs::Int=-1, name::AbstractString=string enc = isdeterm ? enc | SQLITE_DETERMINISTIC : enc @CHECK db sqlite3_create_function_v2( - db.handle, name, nargs, enc, C_NULL, cfunc, C_NULL, C_NULL, C_NULL + db.handle, + name, + nargs, + enc, + C_NULL, + cfunc, + C_NULL, + C_NULL, + C_NULL, ) end # as above but for aggregate functions -newidentity() = @eval x->x +newidentity() = @eval x -> x function register( - db, init, step::Function, final::Function= newidentity(); - nargs::Int=-1, name::AbstractString=string(step), isdeterm::Bool=true + db, + init, + step::Function, + final::Function = newidentity(); + nargs::Int = -1, + name::AbstractString = string(step), + isdeterm::Bool = true, ) @assert nargs <= 127 "use -1 if > 127 arguments are needed" nargs < -1 && (nargs = -1) @@ -242,7 +280,15 @@ function register( enc = isdeterm ? enc | SQLITE_DETERMINISTIC : enc @CHECK db sqlite3_create_function_v2( - db.handle, name, nargs, enc, C_NULL, C_NULL, cs, cf, C_NULL + db.handle, + name, + nargs, + enc, + C_NULL, + C_NULL, + cs, + cf, + C_NULL, ) end @@ -255,4 +301,6 @@ regexp(r::AbstractString, s::AbstractString) = occursin(Regex(r), s) This string literal is used to escape all special characters in the string, useful for using regex in a query. """ -macro sr_str(s) s end +macro sr_str(s) + s +end diff --git a/src/api.jl b/src/api.jl index 61187a4..9bddf3d 100644 --- a/src/api.jl +++ b/src/api.jl @@ -1,194 +1,330 @@ function sqlite3_errmsg() - return ccall( (:sqlite3_errmsg, libsqlite), - Ptr{UInt8}, () - ) + return ccall((:sqlite3_errmsg, libsqlite), Ptr{UInt8}, ()) end function sqlite3_errmsg(db::Ptr{Cvoid}) @NULLCHECK db - return ccall( (:sqlite3_errmsg, libsqlite), - Ptr{UInt8}, (Ptr{Cvoid},), - db) + return ccall((:sqlite3_errmsg, libsqlite), Ptr{UInt8}, (Ptr{Cvoid},), db) end function sqlite3_open(file::AbstractString, handle) - return ccall( (:sqlite3_open, libsqlite), - Cint, (Ptr{UInt8}, Ptr{Cvoid}), - file, handle) + return ccall( + (:sqlite3_open, libsqlite), + Cint, + (Ptr{UInt8}, Ptr{Cvoid}), + file, + handle, + ) end function sqlite3_close(handle::Ptr{Cvoid}) @NULLCHECK handle - return ccall( (:sqlite3_close, libsqlite), - Cint, (Ptr{Cvoid},), - handle) + return ccall((:sqlite3_close, libsqlite), Cint, (Ptr{Cvoid},), handle) end function sqlite3_next_stmt(db::Ptr{Cvoid}, stmt::Ptr{Cvoid}) @NULLCHECK db - return ccall( (:sqlite3_next_stmt, libsqlite), - Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}), - db, stmt) -end -function sqlite3_prepare_v2(handle::Ptr{Cvoid}, query::AbstractString, stmt, unused) + return ccall( + (:sqlite3_next_stmt, libsqlite), + Ptr{Cvoid}, + (Ptr{Cvoid}, Ptr{Cvoid}), + db, + stmt, + ) +end +function sqlite3_prepare_v2( + handle::Ptr{Cvoid}, + query::AbstractString, + stmt, + unused, +) @NULLCHECK handle - return ccall( (:sqlite3_prepare_v2, libsqlite), - Cint, (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}, Ptr{Cvoid}), - handle, query, sizeof(query), stmt, unused) -end -function sqlite3_prepare16_v2(handle::Ptr{Cvoid}, query::AbstractString, stmt, unused) + return ccall( + (:sqlite3_prepare_v2, libsqlite), + Cint, + (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}, Ptr{Cvoid}), + handle, + query, + sizeof(query), + stmt, + unused, + ) +end +function sqlite3_prepare16_v2( + handle::Ptr{Cvoid}, + query::AbstractString, + stmt, + unused, +) @NULLCHECK handle - return ccall( (:sqlite3_prepare16_v2, libsqlite), - Cint, (Ptr{Cvoid}, Ptr{UInt16}, Cint, Ptr{Cvoid}, Ptr{Cvoid}), - handle, query, sizeof(query), stmt, unused) + return ccall( + (:sqlite3_prepare16_v2, libsqlite), + Cint, + (Ptr{Cvoid}, Ptr{UInt16}, Cint, Ptr{Cvoid}, Ptr{Cvoid}), + handle, + query, + sizeof(query), + stmt, + unused, + ) end function sqlite3_expanded_sql(stmt::Ptr{Cvoid}) @NULLCHECK stmt - return ccall( (:sqlite3_expanded_sql, libsqlite), - Ptr{UInt8}, (Ptr{Cvoid},), stmt) + return ccall( + (:sqlite3_expanded_sql, libsqlite), + Ptr{UInt8}, + (Ptr{Cvoid},), + stmt, + ) +end +function sqlite3_free(ptr::Ptr{Cvoid}) + ccall((:sqlite3_free, libsqlite), Cvoid, (Ptr{Cvoid},), ptr) end -sqlite3_free(ptr::Ptr{Cvoid}) = ccall( (:sqlite3_free, libsqlite), Cvoid, (Ptr{Cvoid},), ptr) function sqlite3_finalize(stmt::Ptr{Cvoid}) @NULLCHECK stmt - return ccall( (:sqlite3_finalize, libsqlite), - Cint, (Ptr{Cvoid},), - stmt) + return ccall((:sqlite3_finalize, libsqlite), Cint, (Ptr{Cvoid},), stmt) end # SQLITE_API int sqlite3_bind_paramter_count(sqlite3_stmt*) function sqlite3_bind_parameter_count(stmt::Ptr{Cvoid}) - return ccall( (:sqlite3_bind_parameter_count, libsqlite), - Cint, (Ptr{Cvoid},), - stmt) + return ccall( + (:sqlite3_bind_parameter_count, libsqlite), + Cint, + (Ptr{Cvoid},), + stmt, + ) end #SQLITE_API const char* sqlite3_bind_parameter_name(sqlite3_stmt*, int) function sqlite3_bind_parameter_name(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_bind_parameter_name, libsqlite), - Ptr{UInt8}, (Ptr{Cvoid}, Cint), - stmt, col) + return ccall( + (:sqlite3_bind_parameter_name, libsqlite), + Ptr{UInt8}, + (Ptr{Cvoid}, Cint), + stmt, + col, + ) end # SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); function sqlite3_bind_parameter_index(stmt::Ptr{Cvoid}, value::AbstractString) - return ccall( (:sqlite3_bind_parameter_index, libsqlite), - Cint, (Ptr{Cvoid}, Ptr{UInt8}), - stmt, value) + return ccall( + (:sqlite3_bind_parameter_index, libsqlite), + Cint, + (Ptr{Cvoid}, Ptr{UInt8}), + stmt, + value, + ) end # SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); function sqlite3_bind_double(stmt::Ptr{Cvoid}, col::Int, value::Float64) - return ccall( (:sqlite3_bind_double, libsqlite), - Cint, (Ptr{Cvoid}, Cint, Float64), - stmt, col, value) + return ccall( + (:sqlite3_bind_double, libsqlite), + Cint, + (Ptr{Cvoid}, Cint, Float64), + stmt, + col, + value, + ) end # SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); function sqlite3_bind_int(stmt::Ptr{Cvoid}, col::Int, value::Int32) - return ccall( (:sqlite3_bind_int, libsqlite), - Cint, (Ptr{Cvoid}, Cint, Int32), - stmt, col, value) + return ccall( + (:sqlite3_bind_int, libsqlite), + Cint, + (Ptr{Cvoid}, Cint, Int32), + stmt, + col, + value, + ) end # SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); function sqlite3_bind_int64(stmt::Ptr{Cvoid}, col::Int, value::Int64) - return ccall( (:sqlite3_bind_int64, libsqlite), - Cint, (Ptr{Cvoid}, Cint, Int64), - stmt, col, value) + return ccall( + (:sqlite3_bind_int64, libsqlite), + Cint, + (Ptr{Cvoid}, Cint, Int64), + stmt, + col, + value, + ) end # SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); function sqlite3_bind_null(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_bind_null, libsqlite), - Cint, (Ptr{Cvoid}, Cint), - stmt, col) + return ccall( + (:sqlite3_bind_null, libsqlite), + Cint, + (Ptr{Cvoid}, Cint), + stmt, + col, + ) end # SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); function sqlite3_bind_text(stmt::Ptr{Cvoid}, col::Int, value::AbstractString) - return ccall( (:sqlite3_bind_text, libsqlite), - Cint, (Ptr{Cvoid}, Cint, Ptr{UInt8}, Cint, Ptr{Cvoid}), - stmt, col, value, sizeof(value), C_NULL) -end -function sqlite3_bind_text(stmt::Ptr{Cvoid}, col::Int, ptr::Ptr{UInt8}, len::Int) - return ccall( (:sqlite3_bind_text, libsqlite), - Cint, (Ptr{Cvoid}, Cint, Ptr{UInt8}, Cint, Ptr{Cvoid}), - stmt, col, ptr, len, C_NULL) + return ccall( + (:sqlite3_bind_text, libsqlite), + Cint, + (Ptr{Cvoid}, Cint, Ptr{UInt8}, Cint, Ptr{Cvoid}), + stmt, + col, + value, + sizeof(value), + C_NULL, + ) +end +function sqlite3_bind_text( + stmt::Ptr{Cvoid}, + col::Int, + ptr::Ptr{UInt8}, + len::Int, +) + return ccall( + (:sqlite3_bind_text, libsqlite), + Cint, + (Ptr{Cvoid}, Cint, Ptr{UInt8}, Cint, Ptr{Cvoid}), + stmt, + col, + ptr, + len, + C_NULL, + ) end # SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); -function sqlite3_bind_text16(stmt::Ptr{Cvoid}, col::Int, ptr::Ptr{UInt16}, len::Int) - return ccall( (:sqlite3_bind_text16, libsqlite), - Cint, (Ptr{Cvoid}, Cint, Ptr{UInt16}, Cint, Ptr{Cvoid}), - stmt, col, ptr, len, C_NULL) +function sqlite3_bind_text16( + stmt::Ptr{Cvoid}, + col::Int, + ptr::Ptr{UInt16}, + len::Int, +) + return ccall( + (:sqlite3_bind_text16, libsqlite), + Cint, + (Ptr{Cvoid}, Cint, Ptr{UInt16}, Cint, Ptr{Cvoid}), + stmt, + col, + ptr, + len, + C_NULL, + ) end # SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); function sqlite3_bind_blob(stmt::Ptr{Cvoid}, col::Int, value) - return ccall( (:sqlite3_bind_blob, libsqlite), - Cint, (Ptr{Cvoid}, Cint, Ptr{UInt8}, Cint, Ptr{Cvoid}), - stmt, col, value, sizeof(value), SQLITE_STATIC) + return ccall( + (:sqlite3_bind_blob, libsqlite), + Cint, + (Ptr{Cvoid}, Cint, Ptr{UInt8}, Cint, Ptr{Cvoid}), + stmt, + col, + value, + sizeof(value), + SQLITE_STATIC, + ) end # SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); # SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); - # SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); function sqlite3_busy_timeout(db::Ptr{Cvoid}, ms) @NULLCHECK db - return ccall( (:sqlite3_busy_timeout, libsqlite), - Cint, (Ptr{Cvoid}, Cint), - db, ms) + return ccall( + (:sqlite3_busy_timeout, libsqlite), + Cint, + (Ptr{Cvoid}, Cint), + db, + ms, + ) end function sqlite3_clear_bindings(stmt::Ptr{Cvoid}) - return ccall( (:sqlite3_clear_bindings, libsqlite), - Cint, (Ptr{Cvoid},), - stmt) + return ccall( + (:sqlite3_clear_bindings, libsqlite), + Cint, + (Ptr{Cvoid},), + stmt, + ) end function sqlite3_step(stmt::Ptr{Cvoid}) - return ccall( (:sqlite3_step, libsqlite), - Cint, (Ptr{Cvoid},), - stmt) + return ccall((:sqlite3_step, libsqlite), Cint, (Ptr{Cvoid},), stmt) end function sqlite3_column_count(stmt::Ptr{Cvoid}) - return ccall( (:sqlite3_column_count, libsqlite), - Cint, (Ptr{Cvoid},), - stmt) + return ccall((:sqlite3_column_count, libsqlite), Cint, (Ptr{Cvoid},), stmt) end function sqlite3_column_type(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_type, libsqlite), - Cint, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_type, libsqlite), + Cint, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_column_blob(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_blob, libsqlite), - Ptr{Cvoid}, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_blob, libsqlite), + Ptr{Cvoid}, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_column_bytes(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_bytes, libsqlite), - Cint, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_bytes, libsqlite), + Cint, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_column_bytes16(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_bytes16, libsqlite), - Cint, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_bytes16, libsqlite), + Cint, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_column_double(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_double, libsqlite), - Cdouble, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_double, libsqlite), + Cdouble, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_column_int(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_int, libsqlite), - Cint, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_int, libsqlite), + Cint, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_column_int64(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_int64, libsqlite), - Clonglong, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_int64, libsqlite), + Clonglong, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_column_text(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_text, libsqlite), - Ptr{UInt8}, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_text, libsqlite), + Ptr{UInt8}, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_column_text16(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_text16, libsqlite), - Ptr{Cvoid}, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_text16, libsqlite), + Ptr{Cvoid}, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end # function sqlite3_column_value(stmt::Ptr{Cvoid}, col::Cint) # return ccall( (:sqlite3_column_value, libsqlite), @@ -197,34 +333,36 @@ end # end # SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); function sqlite3_reset(stmt::Ptr{Cvoid}) - return ccall( (:sqlite3_reset, libsqlite), - Cint, (Ptr{Cvoid},), - stmt) + return ccall((:sqlite3_reset, libsqlite), Cint, (Ptr{Cvoid},), stmt) end # SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); function sqlite3_column_name(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_name, libsqlite), - Ptr{UInt8}, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_name, libsqlite), + Ptr{UInt8}, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_column_name16(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_name16, libsqlite), - Ptr{UInt8}, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_name16, libsqlite), + Ptr{UInt8}, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end function sqlite3_changes(db::Ptr{Cvoid}) @NULLCHECK db - return ccall( (:sqlite3_changes, libsqlite), - Cint, (Ptr{Cvoid},), - db) + return ccall((:sqlite3_changes, libsqlite), Cint, (Ptr{Cvoid},), db) end function sqlite3_total_changes(db::Ptr{Cvoid}) @NULLCHECK db - return ccall( (:sqlite3_changes, libsqlite), - Cint, (Ptr{Cvoid},), - db) + return ccall((:sqlite3_changes, libsqlite), Cint, (Ptr{Cvoid},), db) end # SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); @@ -236,9 +374,13 @@ end # SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*, int); function sqlite3_column_decltype(stmt::Ptr{Cvoid}, col::Int) - return ccall( (:sqlite3_column_decltype, libsqlite), - Ptr{UInt8}, (Ptr{Cvoid}, Cint), - stmt, col-1) + return ccall( + (:sqlite3_column_decltype, libsqlite), + Ptr{UInt8}, + (Ptr{Cvoid}, Cint), + stmt, + col - 1, + ) end # SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*, int); # SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*, int); @@ -247,47 +389,79 @@ end # SQLITE_API void sqlite3_result_double(sqlite3_context*, double); function sqlite3_result_double(context::Ptr{Cvoid}, value::Float64) - return ccall( (:sqlite3_result_double, libsqlite), - Cvoid, (Ptr{Cvoid}, Float64), - context, value) + return ccall( + (:sqlite3_result_double, libsqlite), + Cvoid, + (Ptr{Cvoid}, Float64), + context, + value, + ) end # SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int) function sqlite3_result_error(context::Ptr{Cvoid}, msg::AbstractString) - return ccall( (:sqlite3_result_error, libsqlite), - Cvoid, (Ptr{Cvoid}, Ptr{UInt8}, Cint), - context, value, sizeof(msg)+1) + return ccall( + (:sqlite3_result_error, libsqlite), + Cvoid, + (Ptr{Cvoid}, Ptr{UInt8}, Cint), + context, + value, + sizeof(msg) + 1, + ) end # SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int) # SQLITE_API void sqlite3_result_int(sqlite3_context*, int); function sqlite3_result_int(context::Ptr{Cvoid}, value::Int32) - return ccall( (:sqlite3_result_int, libsqlite), - Cvoid, (Ptr{Cvoid}, Int32), - context, value) + return ccall( + (:sqlite3_result_int, libsqlite), + Cvoid, + (Ptr{Cvoid}, Int32), + context, + value, + ) end # SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); function sqlite3_result_int64(context::Ptr{Cvoid}, value::Int64) - return ccall( (:sqlite3_result_int64, libsqlite), - Cvoid, (Ptr{Cvoid}, Int64), - context, value) + return ccall( + (:sqlite3_result_int64, libsqlite), + Cvoid, + (Ptr{Cvoid}, Int64), + context, + value, + ) end # SQLITE_API void sqlite3_result_null(sqlite3_context*); function sqlite3_result_null(context::Ptr{Cvoid}) - return ccall( (:sqlite3_result_null, libsqlite), - Cvoid, (Ptr{Cvoid},), - context) + return ccall( + (:sqlite3_result_null, libsqlite), + Cvoid, + (Ptr{Cvoid},), + context, + ) end # SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int n, void(*)(void*)); function sqlite3_result_text(context::Ptr{Cvoid}, value::AbstractString) - return ccall( (:sqlite3_result_text, libsqlite), - Cvoid, (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}), - context, value, sizeof(value), SQLITE_TRANSIENT) + return ccall( + (:sqlite3_result_text, libsqlite), + Cvoid, + (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}), + context, + value, + sizeof(value), + SQLITE_TRANSIENT, + ) end # SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); # SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int n, void(*)(void*)); function sqlite3_result_blob(context::Ptr{Cvoid}, value) - return ccall( (:sqlite3_result_blob, libsqlite), - Cvoid, (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}), - context, value, sizeof(value), SQLITE_TRANSIENT) + return ccall( + (:sqlite3_result_blob, libsqlite), + Cvoid, + (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}), + context, + value, + sizeof(value), + SQLITE_TRANSIENT, + ) end # SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); # SQLITE_API void sqlite3_result_value(sqlite3_context*, const sqlite3_value*); @@ -295,109 +469,143 @@ end # SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*) # SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int) - -function sqlite3_create_function_v2(db::Ptr{Cvoid}, name::AbstractString, nargs::Integer, - enc::Integer, data::Ptr{Cvoid}, func, - step, final, - destructor::Ptr{Cvoid}) +function sqlite3_create_function_v2( + db::Ptr{Cvoid}, + name::AbstractString, + nargs::Integer, + enc::Integer, + data::Ptr{Cvoid}, + func, + step, + final, + destructor::Ptr{Cvoid}, +) @NULLCHECK db return ccall( (:sqlite3_create_function_v2, libsqlite), Cint, - (Ptr{Cvoid}, Ptr{UInt8}, Cint, Cint, Ptr{Cvoid}, - Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), - db, name, nargs, enc, data, func, step, final, destructor) + ( + Ptr{Cvoid}, + Ptr{UInt8}, + Cint, + Cint, + Ptr{Cvoid}, + Ptr{Cvoid}, + Ptr{Cvoid}, + Ptr{Cvoid}, + Ptr{Cvoid}, + ), + db, + name, + nargs, + enc, + data, + func, + step, + final, + destructor, + ) end # SQLITE_API void* sqlite3_aggregate_context(sqlite3_context*, int nBytes) function sqlite3_aggregate_context(context::Ptr{Cvoid}, nbytes::Integer) - return ccall( (:sqlite3_aggregate_context, libsqlite), - Ptr{Cvoid}, (Ptr{Cvoid}, Cint), - context, nbytes) + return ccall( + (:sqlite3_aggregate_context, libsqlite), + Ptr{Cvoid}, + (Ptr{Cvoid}, Cint), + context, + nbytes, + ) end # SQLITE_API int sqlite3_value_type(sqlite3_value*) function sqlite3_value_type(value::Ptr{Cvoid}) - return ccall( (:sqlite3_value_type, libsqlite), - Cint, (Ptr{Cvoid},), - value) + return ccall((:sqlite3_value_type, libsqlite), Cint, (Ptr{Cvoid},), value) end # SQLITE_API const void* sqlite3_value_blob(sqlite3_value*) function sqlite3_value_blob(value::Ptr{Cvoid}) - return ccall( (:sqlite3_value_blob, libsqlite), - Ptr{Cvoid}, (Ptr{Cvoid},), - value) + return ccall( + (:sqlite3_value_blob, libsqlite), + Ptr{Cvoid}, + (Ptr{Cvoid},), + value, + ) end # SQLITE_API int sqlite3_value_bytes(sqlite3_value*) function sqlite3_value_bytes(value::Ptr{Cvoid}) - return ccall( (:sqlite3_value_bytes, libsqlite), - Cint, (Ptr{Cvoid},), - value) + return ccall((:sqlite3_value_bytes, libsqlite), Cint, (Ptr{Cvoid},), value) end # SQLITE_API int sqlite3_value_bytes16(sqlite3_value*) function sqlite3_value_bytes16(value::Ptr{Cvoid}) - return ccall( (:sqlite3_value_bytes16, libsqlite), - Cint, (Ptr{Cvoid},), - value) + return ccall( + (:sqlite3_value_bytes16, libsqlite), + Cint, + (Ptr{Cvoid},), + value, + ) end # SQLITE_API double sqlite3_value_double(sqlite3_value*) function sqlite3_value_double(value::Ptr{Cvoid}) - return ccall( (:sqlite3_value_double, libsqlite), - Cdouble, (Ptr{Cvoid},), - value) + return ccall( + (:sqlite3_value_double, libsqlite), + Cdouble, + (Ptr{Cvoid},), + value, + ) end # SQLITE_API int sqlite3_value_int(sqlite3_value*) function sqlite3_value_int(value::Ptr{Cvoid}) - return ccall( (:sqlite3_value_int, libsqlite), - Cint, (Ptr{Cvoid},), - value) + return ccall((:sqlite3_value_int, libsqlite), Cint, (Ptr{Cvoid},), value) end # SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value*) function sqlite3_value_int64(value::Ptr{Cvoid}) - return ccall( (:sqlite3_value_int64, libsqlite), - Clonglong, (Ptr{Cvoid},), - value) + return ccall( + (:sqlite3_value_int64, libsqlite), + Clonglong, + (Ptr{Cvoid},), + value, + ) end # SQLITE_API const unsigned char* sqlite3_value_text(sqlite3_value*) function sqlite3_value_text(value::Ptr{Cvoid}) - return ccall( (:sqlite3_value_text, libsqlite), - Ptr{UInt8}, (Ptr{Cvoid},), - value) + return ccall( + (:sqlite3_value_text, libsqlite), + Ptr{UInt8}, + (Ptr{Cvoid},), + value, + ) end # SQLITE_API const void* sqlite3_value_text16(sqlite3_value*) function sqlite3_value_text16(value::Ptr{Cvoid}) - return ccall( (:sqlite3_value_text16, libsqlite), - Ptr{Cvoid}, (Ptr{Cvoid},), - value) + return ccall( + (:sqlite3_value_text16, libsqlite), + Ptr{Cvoid}, + (Ptr{Cvoid},), + value, + ) end # SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*) - function sqlite3_initialize() - return ccall( (:sqlite3_initialize, libsqlite), - Cint, (), - ) + return ccall((:sqlite3_initialize, libsqlite), Cint, ()) end function sqlite3_shutdown() - return ccall( (:sqlite3_shutdown, libsqlite), - Cint, (), - ) + return ccall((:sqlite3_shutdown, libsqlite), Cint, ()) end function sqlite3_os_init() - return ccall( (:sqlite3_os_init, libsqlite), - Cint, (), - ) + return ccall((:sqlite3_os_init, libsqlite), Cint, ()) end function sqlite3_os_end() - return ccall( (:sqlite3_os_end, libsqlite), - Cint, (), - ) + return ccall((:sqlite3_os_end, libsqlite), Cint, ()) end -function sqlite3_free_table(result::Array{AbstractString, 1}) - return ccall( (:sqlite3_free_table, libsqlite), - Cvoid, (Ptr{Ptr{Cvoid}},), - result) +function sqlite3_free_table(result::Array{AbstractString,1}) + return ccall( + (:sqlite3_free_table, libsqlite), + Cvoid, + (Ptr{Ptr{Cvoid}},), + result, + ) end # SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); @@ -405,22 +613,21 @@ end # SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); function sqlite3_errcode(db::Ptr{Cvoid}) @NULLCHECK db - return ccall( (:sqlite3_errcode, libsqlite), - Cint, (Ptr{Cvoid},), - db) + return ccall((:sqlite3_errcode, libsqlite), Cint, (Ptr{Cvoid},), db) end function sqlite3_extended_errcode(db::Ptr{Cvoid}) @NULLCHECK db - return ccall( (:sqlite3_extended_errcode, libsqlite), - Cint, (Ptr{Cvoid},), - db) + return ccall( + (:sqlite3_extended_errcode, libsqlite), + Cint, + (Ptr{Cvoid},), + db, + ) end # SQLITE_API int sqlite3_errcode(sqlite3 *db); # SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); function sqlite3_errstr(ret::Cint) - return ccall( (:sqlite3_errstr, libsqlite), - Ptr{UInt8}, (Cint,), - ret) + return ccall((:sqlite3_errstr, libsqlite), Ptr{UInt8}, (Cint,), ret) end # SQLITE_API const char *sqlite3_errstr(int); @@ -445,29 +652,67 @@ end # SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); # Not directly used -function sqlite3_open_v2(file::AbstractString, handle, flags::Cint, vfs::AbstractString) - return ccall( (:sqlite3_open_v2, libsqlite), - Cint, (Ptr{UInt8}, Ptr{Cvoid}, Cint, Ptr{UInt8}), - file, handle, flags, vfs) -end -function sqlite3_prepare(handle::Ptr{Cvoid}, query::AbstractString, stmt, unused) +function sqlite3_open_v2( + file::AbstractString, + handle, + flags::Cint, + vfs::AbstractString, +) + return ccall( + (:sqlite3_open_v2, libsqlite), + Cint, + (Ptr{UInt8}, Ptr{Cvoid}, Cint, Ptr{UInt8}), + file, + handle, + flags, + vfs, + ) +end +function sqlite3_prepare( + handle::Ptr{Cvoid}, + query::AbstractString, + stmt, + unused, +) @NULLCHECK handle - return ccall( (:sqlite3_prepare, libsqlite), - Cint, (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}, Ptr{Cvoid}), - handle, query, sizeof(query), stmt, unused) -end -function sqlite3_prepare16(handle::Ptr{Cvoid}, query::AbstractString, stmt, unused) + return ccall( + (:sqlite3_prepare, libsqlite), + Cint, + (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}, Ptr{Cvoid}), + handle, + query, + sizeof(query), + stmt, + unused, + ) +end +function sqlite3_prepare16( + handle::Ptr{Cvoid}, + query::AbstractString, + stmt, + unused, +) @NULLCHECK handle - return ccall( (:sqlite3_prepare16, libsqlite), - Cint, (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}, Ptr{Cvoid}), - handle, query, sizeof(query), stmt, unused) + return ccall( + (:sqlite3_prepare16, libsqlite), + Cint, + (Ptr{Cvoid}, Ptr{UInt8}, Cint, Ptr{Cvoid}, Ptr{Cvoid}), + handle, + query, + sizeof(query), + stmt, + unused, + ) end function sqlite3_close_v2(handle::Ptr{Cvoid}) @NULLCHECK handle try - return ccall( (:sqlite3_close_v2, libsqlite), - Cint, (Ptr{Cvoid},), - handle) + return ccall( + (:sqlite3_close_v2, libsqlite), + Cint, + (Ptr{Cvoid},), + handle, + ) catch # Older versions of the library don't have this, abort to other close warn("sqlite3_close_v2 not available.") @@ -476,7 +721,10 @@ function sqlite3_close_v2(handle::Ptr{Cvoid}) end function sqlite3_last_insert_rowid(handle::Ptr{Cvoid}) @NULLCHECK handle - return ccall( (:sqlite3_last_insert_rowid, libsqlite), - Clong, (Ptr{Cvoid},), - handle) + return ccall( + (:sqlite3_last_insert_rowid, libsqlite), + Clong, + (Ptr{Cvoid},), + handle, + ) end diff --git a/src/consts.jl b/src/consts.jl index 2780a36..4622bad 100644 --- a/src/consts.jl +++ b/src/consts.jl @@ -5,7 +5,7 @@ macro OK(func) :($(esc(func)) == SQLITE_OK) end -macro CHECK(db,ex) +macro CHECK(db, ex) esc(quote if !(@OK $ex) sqliteerror($db) @@ -24,229 +24,229 @@ macro NULLCHECK(ptr) end #Return codes -const SQLITE_OK = 0 # /* Successful result */ -const SQLITE_ERROR = 1 # /* SQL error or missing database */ -const SQLITE_INTERNAL = 2 # /* Internal logic error in SQLite */ -const SQLITE_PERM = 3 # /* Access permission denied */ -const SQLITE_ABORT = 4 # /* Callback routine requested an abort */ -const SQLITE_BUSY = 5 # /* The database file is locked */ -const SQLITE_LOCKED = 6 # /* A table in the database is locked */ -const SQLITE_NOMEM = 7 # /* A malloc() failed */ -const SQLITE_READONLY = 8 # /* Attempt to write a readonly database */ -const SQLITE_INTERRUPT = 9 # /* Operation terminated by sqlite3_interrupt()*/ -const SQLITE_IOERR = 10 # /* Some kind of disk I/O error occurred */ -const SQLITE_CORRUPT = 11 # /* The database disk image is malformed */ -const SQLITE_NOTFOUND = 12 # /* Unknown opcode in sqlite3_file_control() */ -const SQLITE_FULL = 13 # /* Insertion failed because database is full */ -const SQLITE_CANTOPEN = 14 # /* Unable to open the database file */ -const SQLITE_PROTOCOL = 15 # /* Database lock protocol error */ -const SQLITE_EMPTY = 16 # /* Database is empty */ -const SQLITE_SCHEMA = 17 # /* The database schema changed */ -const SQLITE_TOOBIG = 18 # /* String or BLOB exceeds size limit */ -const SQLITE_CONSTRAINT = 19 # /* Abort due to constraint violation */ -const SQLITE_MISMATCH = 20 # /* Data type mismatch */ -const SQLITE_MISUSE = 21 # /* Library used incorrectly */ -const SQLITE_NOLFS = 22 # /* Uses OS features not supported on host */ -const SQLITE_AUTH = 23 # /* Authorization denied */ -const SQLITE_FORMAT = 24 # /* Auxiliary database format error */ -const SQLITE_RANGE = 25 # /* 2nd parameter to sqlite3_bind out of range */ -const SQLITE_NOTADB = 26 # /* File opened that is not a database file */ -const SQLITE_NOTICE = 27 # /* Notifications from sqlite3_log() */ -const SQLITE_WARNING = 28 # /* Warnings from sqlite3_log() */ -const SQLITE_ROW = 100 # /* sqlite3_step() has another row ready */ -const SQLITE_DONE = 101 # /* sqlite3_step() has finished executing */ +const SQLITE_OK = 0 # /* Successful result */ +const SQLITE_ERROR = 1 # /* SQL error or missing database */ +const SQLITE_INTERNAL = 2 # /* Internal logic error in SQLite */ +const SQLITE_PERM = 3 # /* Access permission denied */ +const SQLITE_ABORT = 4 # /* Callback routine requested an abort */ +const SQLITE_BUSY = 5 # /* The database file is locked */ +const SQLITE_LOCKED = 6 # /* A table in the database is locked */ +const SQLITE_NOMEM = 7 # /* A malloc() failed */ +const SQLITE_READONLY = 8 # /* Attempt to write a readonly database */ +const SQLITE_INTERRUPT = 9 # /* Operation terminated by sqlite3_interrupt()*/ +const SQLITE_IOERR = 10 # /* Some kind of disk I/O error occurred */ +const SQLITE_CORRUPT = 11 # /* The database disk image is malformed */ +const SQLITE_NOTFOUND = 12 # /* Unknown opcode in sqlite3_file_control() */ +const SQLITE_FULL = 13 # /* Insertion failed because database is full */ +const SQLITE_CANTOPEN = 14 # /* Unable to open the database file */ +const SQLITE_PROTOCOL = 15 # /* Database lock protocol error */ +const SQLITE_EMPTY = 16 # /* Database is empty */ +const SQLITE_SCHEMA = 17 # /* The database schema changed */ +const SQLITE_TOOBIG = 18 # /* String or BLOB exceeds size limit */ +const SQLITE_CONSTRAINT = 19 # /* Abort due to constraint violation */ +const SQLITE_MISMATCH = 20 # /* Data type mismatch */ +const SQLITE_MISUSE = 21 # /* Library used incorrectly */ +const SQLITE_NOLFS = 22 # /* Uses OS features not supported on host */ +const SQLITE_AUTH = 23 # /* Authorization denied */ +const SQLITE_FORMAT = 24 # /* Auxiliary database format error */ +const SQLITE_RANGE = 25 # /* 2nd parameter to sqlite3_bind out of range */ +const SQLITE_NOTADB = 26 # /* File opened that is not a database file */ +const SQLITE_NOTICE = 27 # /* Notifications from sqlite3_log() */ +const SQLITE_WARNING = 28 # /* Warnings from sqlite3_log() */ +const SQLITE_ROW = 100 # /* sqlite3_step() has another row ready */ +const SQLITE_DONE = 101 # /* sqlite3_step() has finished executing */ #Extended Return codes -const SQLITE_IOERR_READ = (SQLITE_IOERR | (1<<8)) -const SQLITE_IOERR_SHORT_READ = (SQLITE_IOERR | (2<<8)) -const SQLITE_IOERR_WRITE = (SQLITE_IOERR | (3<<8)) -const SQLITE_IOERR_FSYNC = (SQLITE_IOERR | (4<<8)) -const SQLITE_IOERR_DIR_FSYNC = (SQLITE_IOERR | (5<<8)) -const SQLITE_IOERR_TRUNCATE = (SQLITE_IOERR | (6<<8)) -const SQLITE_IOERR_FSTAT = (SQLITE_IOERR | (7<<8)) -const SQLITE_IOERR_UNLOCK = (SQLITE_IOERR | (8<<8)) -const SQLITE_IOERR_RDLOCK = (SQLITE_IOERR | (9<<8)) -const SQLITE_IOERR_DELETE = (SQLITE_IOERR | (10<<8)) -const SQLITE_IOERR_BLOCKED = (SQLITE_IOERR | (11<<8)) -const SQLITE_IOERR_NOMEM = (SQLITE_IOERR | (12<<8)) -const SQLITE_IOERR_ACCESS = (SQLITE_IOERR | (13<<8)) -const SQLITE_IOERR_CHECKRESERVEDLOCK = (SQLITE_IOERR | (14<<8)) -const SQLITE_IOERR_LOCK = (SQLITE_IOERR | (15<<8)) -const SQLITE_IOERR_CLOSE = (SQLITE_IOERR | (16<<8)) -const SQLITE_IOERR_DIR_CLOSE = (SQLITE_IOERR | (17<<8)) -const SQLITE_IOERR_SHMOPEN = (SQLITE_IOERR | (18<<8)) -const SQLITE_IOERR_SHMSIZE = (SQLITE_IOERR | (19<<8)) -const SQLITE_IOERR_SHMLOCK = (SQLITE_IOERR | (20<<8)) -const SQLITE_IOERR_SHMMAP = (SQLITE_IOERR | (21<<8)) -const SQLITE_IOERR_SEEK = (SQLITE_IOERR | (22<<8)) -const SQLITE_IOERR_DELETE_NOENT = (SQLITE_IOERR | (23<<8)) -const SQLITE_IOERR_MMAP = (SQLITE_IOERR | (24<<8)) -const SQLITE_LOCKED_SHAREDCACHE = (SQLITE_LOCKED | (1<<8)) -const SQLITE_BUSY_RECOVERY = (SQLITE_BUSY | (1<<8)) -const SQLITE_CANTOPEN_NOTEMPDIR = (SQLITE_CANTOPEN | (1<<8)) -const SQLITE_CANTOPEN_ISDIR = (SQLITE_CANTOPEN | (2<<8)) -const SQLITE_CANTOPEN_FULLPATH = (SQLITE_CANTOPEN | (3<<8)) -const SQLITE_CORRUPT_VTAB = (SQLITE_CORRUPT | (1<<8)) -const SQLITE_READONLY_RECOVERY = (SQLITE_READONLY | (1<<8)) -const SQLITE_READONLY_CANTLOCK = (SQLITE_READONLY | (2<<8)) -const SQLITE_READONLY_ROLLBACK = (SQLITE_READONLY | (3<<8)) -const SQLITE_ABORT_ROLLBACK = (SQLITE_ABORT | (2<<8)) -const SQLITE_CONSTRAINT_CHECK = (SQLITE_CONSTRAINT | (1<<8)) -const SQLITE_CONSTRAINT_COMMITHOOK = (SQLITE_CONSTRAINT | (2<<8)) -const SQLITE_CONSTRAINT_FOREIGNKEY = (SQLITE_CONSTRAINT | (3<<8)) -const SQLITE_CONSTRAINT_FUNCTION = (SQLITE_CONSTRAINT | (4<<8)) -const SQLITE_CONSTRAINT_NOTNULL = (SQLITE_CONSTRAINT | (5<<8)) -const SQLITE_CONSTRAINT_PRIMARYKEY = (SQLITE_CONSTRAINT | (6<<8)) -const SQLITE_CONSTRAINT_TRIGGER = (SQLITE_CONSTRAINT | (7<<8)) -const SQLITE_CONSTRAINT_UNIQUE = (SQLITE_CONSTRAINT | (8<<8)) -const SQLITE_CONSTRAINT_VTAB = (SQLITE_CONSTRAINT | (9<<8)) -const SQLITE_NOTICE_RECOVER_WAL = (SQLITE_NOTICE | (1<<8)) -const SQLITE_NOTICE_RECOVER_ROLLBACK = (SQLITE_NOTICE | (2<<8)) +const SQLITE_IOERR_READ = (SQLITE_IOERR | (1 << 8)) +const SQLITE_IOERR_SHORT_READ = (SQLITE_IOERR | (2 << 8)) +const SQLITE_IOERR_WRITE = (SQLITE_IOERR | (3 << 8)) +const SQLITE_IOERR_FSYNC = (SQLITE_IOERR | (4 << 8)) +const SQLITE_IOERR_DIR_FSYNC = (SQLITE_IOERR | (5 << 8)) +const SQLITE_IOERR_TRUNCATE = (SQLITE_IOERR | (6 << 8)) +const SQLITE_IOERR_FSTAT = (SQLITE_IOERR | (7 << 8)) +const SQLITE_IOERR_UNLOCK = (SQLITE_IOERR | (8 << 8)) +const SQLITE_IOERR_RDLOCK = (SQLITE_IOERR | (9 << 8)) +const SQLITE_IOERR_DELETE = (SQLITE_IOERR | (10 << 8)) +const SQLITE_IOERR_BLOCKED = (SQLITE_IOERR | (11 << 8)) +const SQLITE_IOERR_NOMEM = (SQLITE_IOERR | (12 << 8)) +const SQLITE_IOERR_ACCESS = (SQLITE_IOERR | (13 << 8)) +const SQLITE_IOERR_CHECKRESERVEDLOCK = (SQLITE_IOERR | (14 << 8)) +const SQLITE_IOERR_LOCK = (SQLITE_IOERR | (15 << 8)) +const SQLITE_IOERR_CLOSE = (SQLITE_IOERR | (16 << 8)) +const SQLITE_IOERR_DIR_CLOSE = (SQLITE_IOERR | (17 << 8)) +const SQLITE_IOERR_SHMOPEN = (SQLITE_IOERR | (18 << 8)) +const SQLITE_IOERR_SHMSIZE = (SQLITE_IOERR | (19 << 8)) +const SQLITE_IOERR_SHMLOCK = (SQLITE_IOERR | (20 << 8)) +const SQLITE_IOERR_SHMMAP = (SQLITE_IOERR | (21 << 8)) +const SQLITE_IOERR_SEEK = (SQLITE_IOERR | (22 << 8)) +const SQLITE_IOERR_DELETE_NOENT = (SQLITE_IOERR | (23 << 8)) +const SQLITE_IOERR_MMAP = (SQLITE_IOERR | (24 << 8)) +const SQLITE_LOCKED_SHAREDCACHE = (SQLITE_LOCKED | (1 << 8)) +const SQLITE_BUSY_RECOVERY = (SQLITE_BUSY | (1 << 8)) +const SQLITE_CANTOPEN_NOTEMPDIR = (SQLITE_CANTOPEN | (1 << 8)) +const SQLITE_CANTOPEN_ISDIR = (SQLITE_CANTOPEN | (2 << 8)) +const SQLITE_CANTOPEN_FULLPATH = (SQLITE_CANTOPEN | (3 << 8)) +const SQLITE_CORRUPT_VTAB = (SQLITE_CORRUPT | (1 << 8)) +const SQLITE_READONLY_RECOVERY = (SQLITE_READONLY | (1 << 8)) +const SQLITE_READONLY_CANTLOCK = (SQLITE_READONLY | (2 << 8)) +const SQLITE_READONLY_ROLLBACK = (SQLITE_READONLY | (3 << 8)) +const SQLITE_ABORT_ROLLBACK = (SQLITE_ABORT | (2 << 8)) +const SQLITE_CONSTRAINT_CHECK = (SQLITE_CONSTRAINT | (1 << 8)) +const SQLITE_CONSTRAINT_COMMITHOOK = (SQLITE_CONSTRAINT | (2 << 8)) +const SQLITE_CONSTRAINT_FOREIGNKEY = (SQLITE_CONSTRAINT | (3 << 8)) +const SQLITE_CONSTRAINT_FUNCTION = (SQLITE_CONSTRAINT | (4 << 8)) +const SQLITE_CONSTRAINT_NOTNULL = (SQLITE_CONSTRAINT | (5 << 8)) +const SQLITE_CONSTRAINT_PRIMARYKEY = (SQLITE_CONSTRAINT | (6 << 8)) +const SQLITE_CONSTRAINT_TRIGGER = (SQLITE_CONSTRAINT | (7 << 8)) +const SQLITE_CONSTRAINT_UNIQUE = (SQLITE_CONSTRAINT | (8 << 8)) +const SQLITE_CONSTRAINT_VTAB = (SQLITE_CONSTRAINT | (9 << 8)) +const SQLITE_NOTICE_RECOVER_WAL = (SQLITE_NOTICE | (1 << 8)) +const SQLITE_NOTICE_RECOVER_ROLLBACK = (SQLITE_NOTICE | (2 << 8)) #Text Encodings -const SQLITE_UTF8 = 1 # -const SQLITE_UTF16LE = 2 # -const SQLITE_UTF16BE = 3 # -const SQLITE_UTF16 = 4 # /* Use native byte order */ -const SQLITE_ANY = 5 # /* DEPRECATED */ -const SQLITE_UTF16_ALIGNED = 8 # /* sqlite3_create_collation only */ +const SQLITE_UTF8 = 1 # +const SQLITE_UTF16LE = 2 # +const SQLITE_UTF16BE = 3 # +const SQLITE_UTF16 = 4 # /* Use native byte order */ +const SQLITE_ANY = 5 # /* DEPRECATED */ +const SQLITE_UTF16_ALIGNED = 8 # /* sqlite3_create_collation only */ #Fundamental Data Types const SQLITE_INTEGER = 1 -const SQLITE_FLOAT = 2 -const SQLITE_TEXT = 3 -const SQLITE_BLOB = 4 -const SQLITE_NULL = 5 +const SQLITE_FLOAT = 2 +const SQLITE_TEXT = 3 +const SQLITE_BLOB = 4 +const SQLITE_NULL = 5 -const SQLITE3_TEXT = 3 +const SQLITE3_TEXT = 3 #Checkpoint operation parameters -const SQLITE_CHECKPOINT_PASSIVE = 0 # -const SQLITE_CHECKPOINT_FULL = 1 # -const SQLITE_CHECKPOINT_RESTART = 2 # +const SQLITE_CHECKPOINT_PASSIVE = 0 # +const SQLITE_CHECKPOINT_FULL = 1 # +const SQLITE_CHECKPOINT_RESTART = 2 # #Configuration Options -const SQLITE_CONFIG_SINGLETHREAD = 1 # /* nil */ -const SQLITE_CONFIG_MULTITHREAD = 2 # /* nil */ -const SQLITE_CONFIG_SERIALIZED = 3 # /* nil */ -const SQLITE_CONFIG_MALLOC = 4 # /* sqlite3_mem_methods* */ -const SQLITE_CONFIG_GETMALLOC = 5 # /* sqlite3_mem_methods* */ -const SQLITE_CONFIG_SCRATCH = 6 # /* void*, int sz, int N */ -const SQLITE_CONFIG_PAGECACHE = 7 # /* void*, int sz, int N */ -const SQLITE_CONFIG_HEAP = 8 # /* void*, int nByte, int min */ -const SQLITE_CONFIG_MEMSTATUS = 9 # /* boolean */ -const SQLITE_CONFIG_MUTEX = 10 # /* sqlite3_mutex_methods* */ -const SQLITE_CONFIG_GETMUTEX = 11 # /* sqlite3_mutex_methods* */ +const SQLITE_CONFIG_SINGLETHREAD = 1 # /* nil */ +const SQLITE_CONFIG_MULTITHREAD = 2 # /* nil */ +const SQLITE_CONFIG_SERIALIZED = 3 # /* nil */ +const SQLITE_CONFIG_MALLOC = 4 # /* sqlite3_mem_methods* */ +const SQLITE_CONFIG_GETMALLOC = 5 # /* sqlite3_mem_methods* */ +const SQLITE_CONFIG_SCRATCH = 6 # /* void*, int sz, int N */ +const SQLITE_CONFIG_PAGECACHE = 7 # /* void*, int sz, int N */ +const SQLITE_CONFIG_HEAP = 8 # /* void*, int nByte, int min */ +const SQLITE_CONFIG_MEMSTATUS = 9 # /* boolean */ +const SQLITE_CONFIG_MUTEX = 10 # /* sqlite3_mutex_methods* */ +const SQLITE_CONFIG_GETMUTEX = 11 # /* sqlite3_mutex_methods* */ #/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ -const SQLITE_CONFIG_LOOKASIDE = 13 # /* int int */ -const SQLITE_CONFIG_PCACHE = 14 # /* no-op */ -const SQLITE_CONFIG_GETPCACHE = 15 # /* no-op */ -const SQLITE_CONFIG_LOG = 16 # /* xFunc, void* */ -const SQLITE_CONFIG_URI = 17 # /* int */ -const SQLITE_CONFIG_PCACHE2 = 18 # /* sqlite3_pcache_methods2* */ -const SQLITE_CONFIG_GETPCACHE2 = 19 # /* sqlite3_pcache_methods2* */ -const SQLITE_CONFIG_COVERING_INDEX_SCAN = 20 # /* int */ -const SQLITE_CONFIG_SQLLOG = 21 # /* xSqllog, void* */ -const SQLITE_CONFIG_MMAP_SIZE = 22 # /* sqlite3_int64, sqlite3_int64 */ +const SQLITE_CONFIG_LOOKASIDE = 13 # /* int int */ +const SQLITE_CONFIG_PCACHE = 14 # /* no-op */ +const SQLITE_CONFIG_GETPCACHE = 15 # /* no-op */ +const SQLITE_CONFIG_LOG = 16 # /* xFunc, void* */ +const SQLITE_CONFIG_URI = 17 # /* int */ +const SQLITE_CONFIG_PCACHE2 = 18 # /* sqlite3_pcache_methods2* */ +const SQLITE_CONFIG_GETPCACHE2 = 19 # /* sqlite3_pcache_methods2* */ +const SQLITE_CONFIG_COVERING_INDEX_SCAN = 20 # /* int */ +const SQLITE_CONFIG_SQLLOG = 21 # /* xSqllog, void* */ +const SQLITE_CONFIG_MMAP_SIZE = 22 # /* sqlite3_int64, sqlite3_int64 */ #Database Connection Configuration Options -const SQLITE_DBCONFIG_LOOKASIDE = 1001 # /* void* int int */ -const SQLITE_DBCONFIG_ENABLE_FKEY = 1002 # /* int int* */ -const SQLITE_DBCONFIG_ENABLE_TRIGGER = 1003 # /* int int* */ +const SQLITE_DBCONFIG_LOOKASIDE = 1001 # /* void* int int */ +const SQLITE_DBCONFIG_ENABLE_FKEY = 1002 # /* int int* */ +const SQLITE_DBCONFIG_ENABLE_TRIGGER = 1003 # /* int int* */ #Status Parameters for database connections -const SQLITE_DBSTATUS_LOOKASIDE_USED = 0 # -const SQLITE_DBSTATUS_CACHE_USED = 1 # -const SQLITE_DBSTATUS_SCHEMA_USED = 2 # -const SQLITE_DBSTATUS_STMT_USED = 3 # -const SQLITE_DBSTATUS_LOOKASIDE_HIT = 4 # -const SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE = 5 # -const SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL = 6 # -const SQLITE_DBSTATUS_CACHE_HIT = 7 # -const SQLITE_DBSTATUS_CACHE_MISS = 8 # -const SQLITE_DBSTATUS_CACHE_WRITE = 9 # -const SQLITE_DBSTATUS_MAX = 9 # /* Largest defined DBSTATUS */ +const SQLITE_DBSTATUS_LOOKASIDE_USED = 0 # +const SQLITE_DBSTATUS_CACHE_USED = 1 # +const SQLITE_DBSTATUS_SCHEMA_USED = 2 # +const SQLITE_DBSTATUS_STMT_USED = 3 # +const SQLITE_DBSTATUS_LOOKASIDE_HIT = 4 # +const SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE = 5 # +const SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL = 6 # +const SQLITE_DBSTATUS_CACHE_HIT = 7 # +const SQLITE_DBSTATUS_CACHE_MISS = 8 # +const SQLITE_DBSTATUS_CACHE_WRITE = 9 # +const SQLITE_DBSTATUS_MAX = 9 # /* Largest defined DBSTATUS */ #Authorizer Return Codes -const SQLITE_DENY = 1 # /* Abort the SQL statement with an error */ -const SQLITE_IGNORE = 2 # /* Don't allow access, but don't generate an error */ +const SQLITE_DENY = 1 # /* Abort the SQL statement with an error */ +const SQLITE_IGNORE = 2 # /* Don't allow access, but don't generate an error */ #Conflict resolution modes -const SQLITE_ROLLBACK = 1 # +const SQLITE_ROLLBACK = 1 # #/* const SQLITE_IGNORE = 2 # // Also used by sqlite3_authorizer() callback */ -const SQLITE_FAIL = 3 # +const SQLITE_FAIL = 3 # #/* const SQLITE_ABORT = 4 # // Also an error code */ -const SQLITE_REPLACE = 5 # +const SQLITE_REPLACE = 5 # #Standard File Control Opcodes -const SQLITE_FCNTL_LOCKSTATE = 1 # -const SQLITE_GET_LOCKPROXYFILE = 2 # -const SQLITE_SET_LOCKPROXYFILE = 3 # -const SQLITE_LAST_ERRNO = 4 # -const SQLITE_FCNTL_SIZE_HINT = 5 # -const SQLITE_FCNTL_CHUNK_SIZE = 6 # -const SQLITE_FCNTL_FILE_POINTER = 7 # -const SQLITE_FCNTL_SYNC_OMITTED = 8 # -const SQLITE_FCNTL_WIN32_AV_RETRY = 9 # -const SQLITE_FCNTL_PERSIST_WAL = 10 # -const SQLITE_FCNTL_OVERWRITE = 11 # -const SQLITE_FCNTL_VFSNAME = 12 # -const SQLITE_FCNTL_POWERSAFE_OVERWRITE = 13 # -const SQLITE_FCNTL_PRAGMA = 14 # -const SQLITE_FCNTL_BUSYHANDLER = 15 # -const SQLITE_FCNTL_TEMPFILENAME = 16 # -const SQLITE_FCNTL_MMAP_SIZE = 18 # +const SQLITE_FCNTL_LOCKSTATE = 1 # +const SQLITE_GET_LOCKPROXYFILE = 2 # +const SQLITE_SET_LOCKPROXYFILE = 3 # +const SQLITE_LAST_ERRNO = 4 # +const SQLITE_FCNTL_SIZE_HINT = 5 # +const SQLITE_FCNTL_CHUNK_SIZE = 6 # +const SQLITE_FCNTL_FILE_POINTER = 7 # +const SQLITE_FCNTL_SYNC_OMITTED = 8 # +const SQLITE_FCNTL_WIN32_AV_RETRY = 9 # +const SQLITE_FCNTL_PERSIST_WAL = 10 # +const SQLITE_FCNTL_OVERWRITE = 11 # +const SQLITE_FCNTL_VFSNAME = 12 # +const SQLITE_FCNTL_POWERSAFE_OVERWRITE = 13 # +const SQLITE_FCNTL_PRAGMA = 14 # +const SQLITE_FCNTL_BUSYHANDLER = 15 # +const SQLITE_FCNTL_TEMPFILENAME = 16 # +const SQLITE_FCNTL_MMAP_SIZE = 18 # #Device Characteristics -const SQLITE_IOCAP_ATOMIC = 0x00000001 # -const SQLITE_IOCAP_ATOMIC512 = 0x00000002 # -const SQLITE_IOCAP_ATOMIC1K = 0x00000004 # -const SQLITE_IOCAP_ATOMIC2K = 0x00000008 # -const SQLITE_IOCAP_ATOMIC4K = 0x00000010 # -const SQLITE_IOCAP_ATOMIC8K = 0x00000020 # -const SQLITE_IOCAP_ATOMIC16K = 0x00000040 # -const SQLITE_IOCAP_ATOMIC32K = 0x00000080 # -const SQLITE_IOCAP_ATOMIC64K = 0x00000100 # -const SQLITE_IOCAP_SAFE_APPEND = 0x00000200 # -const SQLITE_IOCAP_SEQUENTIAL = 0x00000400 # -const SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN = 0x00000800 # -const SQLITE_IOCAP_POWERSAFE_OVERWRITE = 0x00001000 # +const SQLITE_IOCAP_ATOMIC = 0x00000001 # +const SQLITE_IOCAP_ATOMIC512 = 0x00000002 # +const SQLITE_IOCAP_ATOMIC1K = 0x00000004 # +const SQLITE_IOCAP_ATOMIC2K = 0x00000008 # +const SQLITE_IOCAP_ATOMIC4K = 0x00000010 # +const SQLITE_IOCAP_ATOMIC8K = 0x00000020 # +const SQLITE_IOCAP_ATOMIC16K = 0x00000040 # +const SQLITE_IOCAP_ATOMIC32K = 0x00000080 # +const SQLITE_IOCAP_ATOMIC64K = 0x00000100 # +const SQLITE_IOCAP_SAFE_APPEND = 0x00000200 # +const SQLITE_IOCAP_SEQUENTIAL = 0x00000400 # +const SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN = 0x00000800 # +const SQLITE_IOCAP_POWERSAFE_OVERWRITE = 0x00001000 # #Run-Time Limit Categories -const SQLITE_LIMIT_LENGTH = 0 # -const SQLITE_LIMIT_SQL_LENGTH = 1 # -const SQLITE_LIMIT_COLUMN = 2 # -const SQLITE_LIMIT_EXPR_DEPTH = 3 # -const SQLITE_LIMIT_COMPOUND_SELECT = 4 # -const SQLITE_LIMIT_VDBE_OP = 5 # -const SQLITE_LIMIT_FUNCTION_ARG = 6 # -const SQLITE_LIMIT_ATTACHED = 7 # -const SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8 # -const SQLITE_LIMIT_VARIABLE_NUMBER = 9 # -const SQLITE_LIMIT_TRIGGER_DEPTH = 10 # +const SQLITE_LIMIT_LENGTH = 0 # +const SQLITE_LIMIT_SQL_LENGTH = 1 # +const SQLITE_LIMIT_COLUMN = 2 # +const SQLITE_LIMIT_EXPR_DEPTH = 3 # +const SQLITE_LIMIT_COMPOUND_SELECT = 4 # +const SQLITE_LIMIT_VDBE_OP = 5 # +const SQLITE_LIMIT_FUNCTION_ARG = 6 # +const SQLITE_LIMIT_ATTACHED = 7 # +const SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8 # +const SQLITE_LIMIT_VARIABLE_NUMBER = 9 # +const SQLITE_LIMIT_TRIGGER_DEPTH = 10 # #File Locking Levels -const SQLITE_LOCK_NONE = 0 # -const SQLITE_LOCK_SHARED = 1 # -const SQLITE_LOCK_RESERVED = 2 # -const SQLITE_LOCK_PENDING = 3 # -const SQLITE_LOCK_EXCLUSIVE = 4 # +const SQLITE_LOCK_NONE = 0 # +const SQLITE_LOCK_SHARED = 1 # +const SQLITE_LOCK_RESERVED = 2 # +const SQLITE_LOCK_PENDING = 3 # +const SQLITE_LOCK_EXCLUSIVE = 4 # #Mutex Types -const SQLITE_MUTEX_FAST = 0 # -const SQLITE_MUTEX_RECURSIVE = 1 # -const SQLITE_MUTEX_STATIC_MASTER = 2 # -const SQLITE_MUTEX_STATIC_MEM = 3 # /* sqlite3_malloc() */ -const SQLITE_MUTEX_STATIC_MEM2 = 4 # /* NOT USED */ -const SQLITE_MUTEX_STATIC_OPEN = 4 # /* sqlite3BtreeOpen() */ -const SQLITE_MUTEX_STATIC_PRNG = 5 # /* sqlite3_random() */ -const SQLITE_MUTEX_STATIC_LRU = 6 # /* lru page list */ -const SQLITE_MUTEX_STATIC_LRU2 = 7 # /* NOT USED */ -const SQLITE_MUTEX_STATIC_PMEM = 7 # /* sqlite3PageMalloc() */ +const SQLITE_MUTEX_FAST = 0 # +const SQLITE_MUTEX_RECURSIVE = 1 # +const SQLITE_MUTEX_STATIC_MASTER = 2 # +const SQLITE_MUTEX_STATIC_MEM = 3 # /* sqlite3_malloc() */ +const SQLITE_MUTEX_STATIC_MEM2 = 4 # /* NOT USED */ +const SQLITE_MUTEX_STATIC_OPEN = 4 # /* sqlite3BtreeOpen() */ +const SQLITE_MUTEX_STATIC_PRNG = 5 # /* sqlite3_random() */ +const SQLITE_MUTEX_STATIC_LRU = 6 # /* lru page list */ +const SQLITE_MUTEX_STATIC_LRU2 = 7 # /* NOT USED */ +const SQLITE_MUTEX_STATIC_PMEM = 7 # /* sqlite3PageMalloc() */ #Flags for the xShmLock VFS method -const SQLITE_SHM_UNLOCK = 1 # -const SQLITE_SHM_LOCK = 2 # -const SQLITE_SHM_SHARED = 4 # -const SQLITE_SHM_EXCLUSIVE = 8 # +const SQLITE_SHM_UNLOCK = 1 # +const SQLITE_SHM_LOCK = 2 # +const SQLITE_SHM_SHARED = 4 # +const SQLITE_SHM_EXCLUSIVE = 8 # #Constants Defining Special Destructor Behavior # typedef void (*sqlite3_destructor_type)(void*); @@ -257,48 +257,48 @@ const SQLITE_TRANSIENT = Ptr{Cvoid}(-1) const SQLITE_DETERMINISTIC = 0x800 #Maximum xShmLock index -const SQLITE_SHM_NLOCK = 8 # +const SQLITE_SHM_NLOCK = 8 # #Status Parameters -const SQLITE_STATUS_MEMORY_USED = 0 # -const SQLITE_STATUS_PAGECACHE_USED = 1 # -const SQLITE_STATUS_PAGECACHE_OVERFLOW = 2 # -const SQLITE_STATUS_SCRATCH_USED = 3 # -const SQLITE_STATUS_SCRATCH_OVERFLOW = 4 # -const SQLITE_STATUS_MALLOC_SIZE = 5 # -const SQLITE_STATUS_PARSER_STACK = 6 # -const SQLITE_STATUS_PAGECACHE_SIZE = 7 # -const SQLITE_STATUS_SCRATCH_SIZE = 8 # -const SQLITE_STATUS_MALLOC_COUNT = 9 # +const SQLITE_STATUS_MEMORY_USED = 0 # +const SQLITE_STATUS_PAGECACHE_USED = 1 # +const SQLITE_STATUS_PAGECACHE_OVERFLOW = 2 # +const SQLITE_STATUS_SCRATCH_USED = 3 # +const SQLITE_STATUS_SCRATCH_OVERFLOW = 4 # +const SQLITE_STATUS_MALLOC_SIZE = 5 # +const SQLITE_STATUS_PARSER_STACK = 6 # +const SQLITE_STATUS_PAGECACHE_SIZE = 7 # +const SQLITE_STATUS_SCRATCH_SIZE = 8 # +const SQLITE_STATUS_MALLOC_COUNT = 9 # #Status Parameters for prepared statements -const SQLITE_STMTSTATUS_FULLSCAN_STEP = 1 # -const SQLITE_STMTSTATUS_SORT = 2 # -const SQLITE_STMTSTATUS_AUTOINDEX = 3 # +const SQLITE_STMTSTATUS_FULLSCAN_STEP = 1 # +const SQLITE_STMTSTATUS_SORT = 2 # +const SQLITE_STMTSTATUS_AUTOINDEX = 3 # #Synchronization Type Flags -const SQLITE_SYNC_NORMAL = 0x00002 # -const SQLITE_SYNC_FULL = 0x00003 # -const SQLITE_SYNC_DATAONLY = 0x00010 # +const SQLITE_SYNC_NORMAL = 0x00002 # +const SQLITE_SYNC_FULL = 0x00003 # +const SQLITE_SYNC_DATAONLY = 0x00010 # #Testing Interface Operation Codes -const SQLITE_TESTCTRL_FIRST = 5 # -const SQLITE_TESTCTRL_PRNG_SAVE = 5 # -const SQLITE_TESTCTRL_PRNG_RESTORE = 6 # -const SQLITE_TESTCTRL_PRNG_RESET = 7 # -const SQLITE_TESTCTRL_BITVEC_TEST = 8 # -const SQLITE_TESTCTRL_FAULT_INSTALL = 9 # -const SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS = 10 # -const SQLITE_TESTCTRL_PENDING_BYTE = 11 # -const SQLITE_TESTCTRL_ASSERT = 12 # -const SQLITE_TESTCTRL_ALWAYS = 13 # -const SQLITE_TESTCTRL_RESERVE = 14 # -const SQLITE_TESTCTRL_OPTIMIZATIONS = 15 # -const SQLITE_TESTCTRL_ISKEYWORD = 16 # -const SQLITE_TESTCTRL_SCRATCHMALLOC = 17 # -const SQLITE_TESTCTRL_LOCALTIME_FAULT = 18 # -const SQLITE_TESTCTRL_EXPLAIN_STMT = 19 # -const SQLITE_TESTCTRL_LAST = 19 # +const SQLITE_TESTCTRL_FIRST = 5 # +const SQLITE_TESTCTRL_PRNG_SAVE = 5 # +const SQLITE_TESTCTRL_PRNG_RESTORE = 6 # +const SQLITE_TESTCTRL_PRNG_RESET = 7 # +const SQLITE_TESTCTRL_BITVEC_TEST = 8 # +const SQLITE_TESTCTRL_FAULT_INSTALL = 9 # +const SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS = 10 # +const SQLITE_TESTCTRL_PENDING_BYTE = 11 # +const SQLITE_TESTCTRL_ASSERT = 12 # +const SQLITE_TESTCTRL_ALWAYS = 13 # +const SQLITE_TESTCTRL_RESERVE = 14 # +const SQLITE_TESTCTRL_OPTIMIZATIONS = 15 # +const SQLITE_TESTCTRL_ISKEYWORD = 16 # +const SQLITE_TESTCTRL_SCRATCHMALLOC = 17 # +const SQLITE_TESTCTRL_LOCALTIME_FAULT = 18 # +const SQLITE_TESTCTRL_EXPLAIN_STMT = 19 # +const SQLITE_TESTCTRL_LAST = 19 # #Virtual Table Configuration Options -const SQLITE_VTAB_CONSTRAINT_SUPPORT = 1 # +const SQLITE_VTAB_CONSTRAINT_SUPPORT = 1 # diff --git a/src/tables.jl b/src/tables.jl index 95ff746..e5153d8 100644 --- a/src/tables.jl +++ b/src/tables.jl @@ -7,7 +7,7 @@ struct Query status::Base.RefValue{Cint} names::Vector{Symbol} types::Vector{Type} - lookup::Dict{Symbol, Int} + lookup::Dict{Symbol,Int} current_rownumber::Base.RefValue{Int} end @@ -26,7 +26,7 @@ Tables.columnnames(q::Query) = q.names struct DBTable name::String - schema::Union{Tables.Schema, Nothing} + schema::Union{Tables.Schema,Nothing} end DBTable(name::String) = DBTable(name, nothing) @@ -71,7 +71,13 @@ function done(q::Query) return false end -@noinline wrongrow(i) = throw(ArgumentError("row $i is no longer valid; sqlite query results are forward-only iterators where each row is only valid when iterated; re-execute the query, convert rows to NamedTuples, or stream the results to a sink to save results")) +@noinline function wrongrow(i) + throw( + ArgumentError( + "row $i is no longer valid; sqlite query results are forward-only iterators where each row is only valid when iterated; re-execute the query, convert rows to NamedTuples, or stream the results to a sink to save results", + ), + ) +end function getvalue(q::Query, col::Int, rownumber::Int, ::Type{T}) where {T} rownumber == q.current_rownumber[] || wrongrow(rownumber) @@ -81,14 +87,24 @@ function getvalue(q::Query, col::Int, rownumber::Int, ::Type{T}) where {T} return missing else TT = juliatype(t) # native SQLite Int, Float, and Text types - return sqlitevalue(ifelse(TT === Any && !isbitstype(T), T, TT), handle, col) + return sqlitevalue( + ifelse(TT === Any && !isbitstype(T), T, TT), + handle, + col, + ) end end -Tables.getcolumn(r::Row, ::Type{T}, i::Int, nm::Symbol) where {T} = getvalue(getquery(r), i, getfield(r, :rownumber), T) +function Tables.getcolumn(r::Row, ::Type{T}, i::Int, nm::Symbol) where {T} + getvalue(getquery(r), i, getfield(r, :rownumber), T) +end -Tables.getcolumn(r::Row, i::Int) = Tables.getcolumn(r, getquery(r).types[i], i, getquery(r).names[i]) -Tables.getcolumn(r::Row, nm::Symbol) = Tables.getcolumn(r, getquery(r).lookup[nm]) +function Tables.getcolumn(r::Row, i::Int) + Tables.getcolumn(r, getquery(r).types[i], i, getquery(r).names[i]) +end +function Tables.getcolumn(r::Row, nm::Symbol) + Tables.getcolumn(r, getquery(r).lookup[nm]) +end Tables.columnnames(r::Row) = Tables.columnnames(getquery(r)) function Base.iterate(q::Query) @@ -129,27 +145,38 @@ Calling `SQLite.reset!(result)` will re-execute the query and reset the iterator The resultset iterator supports the [Tables.jl](https://github.com/JuliaData/Tables.jl) interface, so results can be collected in any Tables.jl-compatible sink, like `DataFrame(results)`, `CSV.write("results.csv", results)`, etc. """ -function DBInterface.execute(stmt::Stmt, params::DBInterface.StatementParams; allowduplicates::Bool=false) +function DBInterface.execute( + stmt::Stmt, + params::DBInterface.StatementParams; + allowduplicates::Bool = false, +) status = execute(stmt, params) _st = _stmt(stmt) cols = sqlite3_column_count(_st.handle) header = Vector{Symbol}(undef, cols) types = Vector{Type}(undef, cols) - for i = 1:cols + for i in 1:cols nm = sym(sqlite3_column_name(_st.handle, i)) - if !allowduplicates && nm in view(header, 1:(i - 1)) + if !allowduplicates && nm in view(header, 1:(i-1)) j = 1 newnm = Symbol(nm, :_, j) - while newnm in view(header, 1:(i - 1)) + while newnm in view(header, 1:(i-1)) j += 1 newnm = Symbol(nm, :_, j) end nm = newnm end header[i] = nm - types[i] = Union{juliatype(_st.handle, i), Missing} + types[i] = Union{juliatype(_st.handle, i),Missing} end - return Query(stmt, Ref(status), header, types, Dict(x=>i for (i, x) in enumerate(header)), Ref(0)) + return Query( + stmt, + Ref(status), + header, + types, + Dict(x => i for (i, x) in enumerate(header)), + Ref(0), + ) end """ @@ -161,13 +188,22 @@ where `names` can be a vector or tuple of String/Symbol column names, and `types If `temp=true`, the table will be created temporarily, which means it will be deleted when the `db` is closed. If `ifnotexists=true`, no error will be thrown if the table already exists. """ -function createtable!(db::DB, name::AbstractString, ::Tables.Schema{names, types}; - temp::Bool=false, ifnotexists::Bool=true) where {names, types} +function createtable!( + db::DB, + name::AbstractString, + ::Tables.Schema{names,types}; + temp::Bool = false, + ifnotexists::Bool = true, +) where {names,types} temp = temp ? "TEMP" : "" ifnotexists = ifnotexists ? "IF NOT EXISTS" : "" - columns = [string(esc_id(String(names[i])), ' ', - sqlitetype(types !== nothing ? fieldtype(types, i) : Any)) - for i in eachindex(names)] + columns = [ + string( + esc_id(String(names[i])), + ' ', + sqlitetype(types !== nothing ? fieldtype(types, i) : Any), + ) for i in eachindex(names) + ] sql = "CREATE $temp TABLE $ifnotexists $(esc_id(string(name))) ($(join(columns, ',')))" return execute(db, sql) end @@ -175,7 +211,7 @@ end # table info for load!(): # returns NamedTuple with columns information, # or nothing if table does not exist -tableinfo(db::DB, name::AbstractString) = +function tableinfo(db::DB, name::AbstractString) DBInterface.execute(db, "pragma table_info($(esc_id(name)))") do qry st = qry.status[] if st == SQLITE_ROW @@ -186,6 +222,7 @@ tableinfo(db::DB, name::AbstractString) = sqliteerror(q.stmt.db) end end +end """ source |> SQLite.load!(db::SQLite.DB, tablename::String; temp::Bool=false, ifnotexists::Bool=false, replace::Bool=false, analyze::Bool=false) @@ -200,10 +237,20 @@ Load a Tables.jl input `source` into an SQLite table that will be named `tablena """ function load! end -load!(db::DB, name::AbstractString="sqlitejl_"*Random.randstring(5); kwargs...) = +function load!( + db::DB, + name::AbstractString = "sqlitejl_" * Random.randstring(5); + kwargs..., +) x -> load!(x, db, name; kwargs...) +end -function load!(itr, db::DB, name::AbstractString="sqlitejl_"*Random.randstring(5); kwargs...) +function load!( + itr, + db::DB, + name::AbstractString = "sqlitejl_" * Random.randstring(5); + kwargs..., +) # check if table exists db_tableinfo = tableinfo(db, name) rows = Tables.rows(itr) @@ -212,12 +259,16 @@ function load!(itr, db::DB, name::AbstractString="sqlitejl_"*Random.randstring(5 end # case-insensitive check for duplicate column names -function checkdupnames(names::Union{AbstractVector, Tuple}) +function checkdupnames(names::Union{AbstractVector,Tuple}) checkednames = Set{String}() for name in names lcname = lowercase(string(name)) if lcname in checkednames - throw(SQLiteException("Duplicate case-insensitive column name $lcname detected. SQLite doesn't allow duplicate column names and treats them case insensitive")) + throw( + SQLiteException( + "Duplicate case-insensitive column name $lcname detected. SQLite doesn't allow duplicate column names and treats them case insensitive", + ), + ) end push!(checkednames, lcname) end @@ -225,31 +276,52 @@ function checkdupnames(names::Union{AbstractVector, Tuple}) end # check if schema names match column names in DB -function checknames(::Tables.Schema{names}, db_names::AbstractVector{String}) where {names} +function checknames( + ::Tables.Schema{names}, + db_names::AbstractVector{String}, +) where {names} table_names = Set(string.(names)) db_names = Set(db_names) if table_names != db_names - throw(SQLiteException("Error loading, column names from table $(collect(table_names)) do not match database names $(collect(db_names))")) + throw( + SQLiteException( + "Error loading, column names from table $(collect(table_names)) do not match database names $(collect(db_names))", + ), + ) end return true end -function load!(sch::Tables.Schema, rows, db::DB, name::AbstractString, db_tableinfo::Union{NamedTuple, Nothing}, row=nothing, st=nothing; - temp::Bool=false, ifnotexists::Bool=false, replace::Bool=false, analyze::Bool=false) +function load!( + sch::Tables.Schema, + rows, + db::DB, + name::AbstractString, + db_tableinfo::Union{NamedTuple,Nothing}, + row = nothing, + st = nothing; + temp::Bool = false, + ifnotexists::Bool = false, + replace::Bool = false, + analyze::Bool = false, +) # check for case-insensitive duplicate column names (sqlite doesn't allow) checkdupnames(sch.names) # check if `rows` column names match the existing table, or create the new one if db_tableinfo !== nothing checknames(sch, db_tableinfo.name) else - createtable!(db, name, sch; temp=temp, ifnotexists=ifnotexists) + createtable!(db, name, sch; temp = temp, ifnotexists = ifnotexists) end # build insert statement columns = join(esc_id.(string.(sch.names)), ",") params = chop(repeat("?,", length(sch.names))) kind = replace ? "REPLACE" : "INSERT" - stmt = _Stmt(db, "$kind INTO $(esc_id(string(name))) ($columns) VALUES ($params)") + stmt = _Stmt( + db, + "$kind INTO $(esc_id(string(name))) ($columns) VALUES ($params)", + ) # start a transaction for inserting rows DBInterface.transaction(db) do if row === nothing @@ -280,8 +352,14 @@ function load!(sch::Tables.Schema, rows, db::DB, name::AbstractString, db_tablei end # unknown schema case -function load!(::Nothing, rows, db::DB, name::AbstractString, - db_tableinfo::Union{NamedTuple, Nothing}; kwargs...) +function load!( + ::Nothing, + rows, + db::DB, + name::AbstractString, + db_tableinfo::Union{NamedTuple,Nothing}; + kwargs..., +) state = iterate(rows) state === nothing && return name row, st = state diff --git a/test/runtests.jl b/test/runtests.jl index 091f8f4..5b6289c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -45,7 +45,7 @@ function setup_clean_test_db(f::Function, args...) dbfile = joinpath(dirname(pathof(SQLite)), "../test/Chinook_Sqlite.sqlite") tmp_dir = mktempdir() test_dbfile = joinpath(tmp_dir, "test.sqlite") - + cp(dbfile, test_dbfile; force = true) chmod(test_dbfile, 0o777) @@ -54,12 +54,11 @@ function setup_clean_test_db(f::Function, args...) f(db) finally close(db) - rm(tmp_dir, recursive = true) + rm(tmp_dir; recursive = true) end end @testset "basics" begin - @testset "Julia to SQLite3 type conversion" begin @test SQLite.sqlitetype(Int) == "INT NOT NULL" @test SQLite.sqlitetype(Union{Float64,Missing}) == "REAL" @@ -71,7 +70,8 @@ end end @testset "DB Connection" begin - dbfile = joinpath(dirname(pathof(SQLite)), "../test/Chinook_Sqlite.sqlite") + dbfile = + joinpath(dirname(pathof(SQLite)), "../test/Chinook_Sqlite.sqlite") @test SQLite.DB(dbfile) isa SQLite.DB con = DBInterface.connect(SQLite.DB, dbfile) @test con isa SQLite.DB @@ -80,23 +80,36 @@ end @testset "SQLite.tables(db)" begin setup_clean_test_db() do db - results1 = SQLite.tables(db) - + @test isa(results1, SQLite.DBTables) @test length(results1) == 11 @test isa(results1[1], SQLite.DBTable) - + @test Tables.istable(results1) @test Tables.rowaccess(results1) @test Tables.rows(results1) == results1 - + @test results1[1].name == "Album" - @test results1[1].schema == Tables.schema(DBInterface.execute(db,"SELECT * FROM Album LIMIT 0")) - + @test results1[1].schema == Tables.schema( + DBInterface.execute(db, "SELECT * FROM Album LIMIT 0"), + ) + @test SQLite.DBTable("Album") == SQLite.DBTable("Album", nothing) - @test [t.name for t in results1] == ["Album", "Artist", "Customer", "Employee", "Genre", "Invoice", "InvoiceLine", "MediaType", "Playlist", "PlaylistTrack", "Track"] + @test [t.name for t in results1] == [ + "Album", + "Artist", + "Customer", + "Employee", + "Genre", + "Invoice", + "InvoiceLine", + "MediaType", + "Playlist", + "PlaylistTrack", + "Track", + ] end @testset "#209: SQLite.tables response when no tables in DB" begin @@ -110,16 +123,20 @@ end @testset "Issue #207: 32 bit integers" begin setup_clean_test_db() do db ds = - DBInterface.execute(db, "SELECT RANDOM() as a FROM Track LIMIT 1") |> - columntable + DBInterface.execute( + db, + "SELECT RANDOM() as a FROM Track LIMIT 1", + ) |> columntable @test ds.a[1] isa Int64 - end end @testset "Regular SQLite Tests" begin setup_clean_test_db() do db - @test_throws SQLiteException DBInterface.execute(db, "just some syntax error") + @test_throws SQLiteException DBInterface.execute( + db, + "just some syntax error", + ) # syntax correct, table missing @test_throws SQLiteException DBInterface.execute( db, @@ -130,7 +147,10 @@ end @testset "close!(query)" begin setup_clean_test_db() do db - qry = DBInterface.execute(db, "SELECT name FROM sqlite_master WHERE type='table';") + qry = DBInterface.execute( + db, + "SELECT name FROM sqlite_master WHERE type='table';", + ) DBInterface.close!(qry) DBInterface.close!(qry) # test it doesn't throw on double-close end @@ -139,8 +159,10 @@ end @testset "Query tables" begin setup_clean_test_db() do db ds = - DBInterface.execute(db, "SELECT name FROM sqlite_master WHERE type='table';") |> - columntable + DBInterface.execute( + db, + "SELECT name FROM sqlite_master WHERE type='table';", + ) |> columntable @test length(ds) == 1 @test keys(ds) == (:name,) @test length(ds.name) == 11 @@ -154,7 +176,9 @@ end setup_clean_test_db() do db # pipe approach - results = DBInterface.execute(db, "SELECT * FROM Employee;") |> columntable + results = + DBInterface.execute(db, "SELECT * FROM Employee;") |> + columntable @test length(results) == 15 @test length(results[1]) == 8 # callable approach @@ -163,12 +187,25 @@ end results, ) employees_stmt = DBInterface.prepare(db, "SELECT * FROM Employee") - @test isequal(columntable(DBInterface.execute(employees_stmt)), results) - @test isequal(DBInterface.execute(columntable, employees_stmt), results) + @test isequal( + columntable(DBInterface.execute(employees_stmt)), + results, + ) + @test isequal( + DBInterface.execute(columntable, employees_stmt), + results, + ) @testset "throwing from f()" begin f(::SQLite.Query) = error("I'm throwing!") - @test_throws ErrorException DBInterface.execute(f, employees_stmt) - @test_throws ErrorException DBInterface.execute(f, db, "SELECT * FROM Employee") + @test_throws ErrorException DBInterface.execute( + f, + employees_stmt, + ) + @test_throws ErrorException DBInterface.execute( + f, + db, + "SELECT * FROM Employee", + ) end DBInterface.close!(employees_stmt) end @@ -176,7 +213,6 @@ end @testset "isempty(::Query)" begin setup_clean_test_db() do db - @test !DBInterface.execute(isempty, db, "SELECT * FROM Employee") @test DBInterface.execute( isempty, @@ -199,14 +235,18 @@ end "SELECT * FROM Employee WHERE FirstName='Joanne'", ) @test empty_scheme.names == all_scheme.names - @test all(ea -> ea[1] <: ea[2], zip(empty_scheme.types, all_scheme.types)) + @test all( + ea -> ea[1] <: ea[2], + zip(empty_scheme.types, all_scheme.types), + ) empty_tbl = DBInterface.execute( columntable, db, "SELECT * FROM Employee WHERE FirstName='Joanne'", ) - all_tbl = DBInterface.execute(columntable, db, "SELECT * FROM Employee") + all_tbl = + DBInterface.execute(columntable, db, "SELECT * FROM Employee") @test propertynames(empty_tbl) == propertynames(all_tbl) @test all( col -> @@ -222,7 +262,9 @@ end DBInterface.execute(db, "create table temp as select * from album") DBInterface.execute(db, "alter table temp add column colyear int") DBInterface.execute(db, "update temp set colyear = 2014") - r = DBInterface.execute(db, "select * from temp limit 10") |> columntable + r = + DBInterface.execute(db, "select * from temp limit 10") |> + columntable @test length(r) == 4 && length(r[1]) == 10 @test all(==(2014), r[4]) @@ -232,13 +274,17 @@ end SQLite.transaction(db) DBInterface.execute(db, "update temp set colyear = 2015") SQLite.rollback(db) - r = DBInterface.execute(db, "select * from temp limit 10") |> columntable + r = + DBInterface.execute(db, "select * from temp limit 10") |> + columntable @test all(==(2014), r[4]) SQLite.transaction(db) DBInterface.execute(db, "update temp set colyear = 2015") SQLite.commit(db) - r = DBInterface.execute(db, "select * from temp limit 10") |> columntable + r = + DBInterface.execute(db, "select * from temp limit 10") |> + columntable @test all(==(2015), r[4]) end end @@ -250,7 +296,9 @@ end stmt = DBInterface.prepare(db, "update temp set dates = ?") DBInterface.execute(stmt, (Date(2014, 1, 1),)) - r = DBInterface.execute(db, "select * from temp limit 10") |> columntable + r = + DBInterface.execute(db, "select * from temp limit 10") |> + columntable @test length(r) == 4 && length(r[1]) == 10 @test isa(r[4][1], Date) @test all(Bool[x == Date(2014, 1, 1) for x in r[4]]) @@ -259,7 +307,9 @@ end rng = Dates.Date(2013):Dates.Day(1):Dates.Date(2013, 1, 5) dt = (i = collect(rng), j = collect(rng)) tablename = dt |> SQLite.load!(db, "temp") - r = DBInterface.execute(db, "select * from $tablename") |> columntable + r = + DBInterface.execute(db, "select * from $tablename") |> + columntable @test length(r) == 2 && length(r[1]) == 5 @test all([i for i in r[1]] .== collect(rng)) @test all([isa(i, Dates.Date) for i in r[1]]) @@ -269,29 +319,44 @@ end @testset "Prepared Statements" begin setup_clean_test_db() do db - DBInterface.execute(db, "CREATE TABLE temp AS SELECT * FROM Album") - r = DBInterface.execute(db, "SELECT * FROM temp LIMIT ?", [3]) |> columntable - @test length(r) == 3 && length(r[1]) == 3 r = - DBInterface.execute(db, "SELECT * FROM temp WHERE Title LIKE ?", ["%time%"]) |> + DBInterface.execute(db, "SELECT * FROM temp LIMIT ?", [3]) |> columntable + @test length(r) == 3 && length(r[1]) == 3 + r = + DBInterface.execute( + db, + "SELECT * FROM temp WHERE Title LIKE ?", + ["%time%"], + ) |> columntable @test r[1] == [76, 111, 187] DBInterface.execute( db, "INSERT INTO temp VALUES (?1, ?3, ?2)", [0, 0, "Test Album"], ) - r = DBInterface.execute(db, "SELECT * FROM temp WHERE AlbumId = 0") |> columntable + r = + DBInterface.execute( + db, + "SELECT * FROM temp WHERE AlbumId = 0", + ) |> columntable @test r[1][1] == 0 @test r[2][1] == "Test Album" @test r[3][1] == 0 SQLite.drop!(db, "temp") DBInterface.execute(db, "CREATE TABLE temp AS SELECT * FROM Album") - r = DBInterface.execute(db, "SELECT * FROM temp LIMIT :a", (a = 3,)) |> columntable + r = + DBInterface.execute( + db, + "SELECT * FROM temp LIMIT :a", + (a = 3,), + ) |> columntable @test length(r) == 3 && length(r[1]) == 3 - r = DBInterface.execute(db, "SELECT * FROM temp LIMIT :a", a = 3) |> columntable + r = + DBInterface.execute(db, "SELECT * FROM temp LIMIT :a"; a = 3) |> + columntable @test length(r) == 3 && length(r[1]) == 3 r = DBInterface.execute( @@ -307,20 +372,22 @@ end ) DBInterface.execute( db, - "INSERT INTO temp VALUES (@lid, :title, \$rid)", + "INSERT INTO temp VALUES (@lid, :title, \$rid)"; rid = 3, lid = 400, title = "Test2 Album", ) r = - DBInterface.execute(db, "SELECT * FROM temp WHERE AlbumId IN (0, 400)") |> - columntable + DBInterface.execute( + db, + "SELECT * FROM temp WHERE AlbumId IN (0, 400)", + ) |> columntable @test r[1] == [0, 400] @test r[2] == ["Test Album", "Test2 Album"] @test r[3] == [1, 3] SQLite.drop!(db, "temp") - SQLite.register(db, SQLite.regexp, nargs = 2, name = "regexp") + SQLite.register(db, SQLite.regexp; nargs = 2, name = "regexp") r = DBInterface.execute( db, @@ -330,7 +397,7 @@ end ) |> columntable @test r[1][1] == "Peacock" - SQLite.register(db, identity, nargs = 1, name = "identity") + SQLite.register(db, identity; nargs = 1, name = "identity") r = DBInterface.execute( db, @@ -340,7 +407,7 @@ end @test first(r.cmp) == 1 @test_throws AssertionError SQLite.register(db, triple, nargs = 186) - SQLite.register(db, triple, nargs = 1) + SQLite.register(db, triple; nargs = 1) r = DBInterface.execute( db, @@ -360,25 +427,39 @@ end @testset "Register functions" begin setup_clean_test_db() do db SQLite.@register db add4 - r = DBInterface.execute(db, "SELECT add4(AlbumId) FROM Album") |> columntable - s = DBInterface.execute(db, "SELECT AlbumId FROM Album") |> columntable + r = + DBInterface.execute(db, "SELECT add4(AlbumId) FROM Album") |> + columntable + s = + DBInterface.execute(db, "SELECT AlbumId FROM Album") |> + columntable @test r[1][1] == s[1][1] + 4 SQLite.@register db mult - r = DBInterface.execute(db, "SELECT GenreId, UnitPrice FROM Track") |> columntable + r = + DBInterface.execute( + db, + "SELECT GenreId, UnitPrice FROM Track", + ) |> columntable s = - DBInterface.execute(db, "SELECT mult(GenreId, UnitPrice) FROM Track") |> - columntable + DBInterface.execute( + db, + "SELECT mult(GenreId, UnitPrice) FROM Track", + ) |> columntable @test (r[1][1] * r[2][1]) == s[1][1] t = - DBInterface.execute(db, "SELECT mult(GenreId, UnitPrice, 3, 4) FROM Track") |> - columntable + DBInterface.execute( + db, + "SELECT mult(GenreId, UnitPrice, 3, 4) FROM Track", + ) |> columntable @test (r[1][1] * r[2][1] * 3 * 4) == t[1][1] SQLite.@register db sin u = - DBInterface.execute(db, "select sin(milliseconds) from track limit 5") |> - columntable + DBInterface.execute( + db, + "select sin(milliseconds) from track limit 5", + ) |> columntable @test all(-1 .< convert(Vector{Float64}, u[1]) .< 1) SQLite.register(db, hypot; nargs = 2, name = "hypotenuse") @@ -391,8 +472,10 @@ end SQLite.@register db str2arr r = - DBInterface.execute(db, "SELECT str2arr(LastName) FROM Employee LIMIT 2") |> - columntable + DBInterface.execute( + db, + "SELECT str2arr(LastName) FROM Employee LIMIT 2", + ) |> columntable @test r[1][2] == UInt8[0x45, 0x64, 0x77, 0x61, 0x72, 0x64, 0x73] SQLite.@register db big @@ -400,35 +483,70 @@ end @test r[1][1] == big(5) @test typeof(r[1][1]) == BigInt - SQLite.register(db, 0, doublesum_step, doublesum_final, name = "doublesum") - r = DBInterface.execute(db, "SELECT doublesum(UnitPrice) FROM Track") |> columntable - s = DBInterface.execute(db, "SELECT UnitPrice FROM Track") |> columntable + SQLite.register( + db, + 0, + doublesum_step, + doublesum_final; + name = "doublesum", + ) + r = + DBInterface.execute( + db, + "SELECT doublesum(UnitPrice) FROM Track", + ) |> columntable + s = + DBInterface.execute(db, "SELECT UnitPrice FROM Track") |> + columntable @test abs(r[1][1] - 2 * sum(convert(Vector{Float64}, s[1]))) < 0.02 - SQLite.register(db, 0, mycount) r = - DBInterface.execute(db, "SELECT mycount(TrackId) FROM PlaylistTrack") |> - columntable + DBInterface.execute( + db, + "SELECT mycount(TrackId) FROM PlaylistTrack", + ) |> columntable s = - DBInterface.execute(db, "SELECT count(TrackId) FROM PlaylistTrack") |> - columntable + DBInterface.execute( + db, + "SELECT count(TrackId) FROM PlaylistTrack", + ) |> columntable @test r[1][1] == s[1][1] SQLite.register(db, big(0), bigsum) r = - DBInterface.execute(db, "SELECT bigsum(TrackId) FROM PlaylistTrack") |> + DBInterface.execute( + db, + "SELECT bigsum(TrackId) FROM PlaylistTrack", + ) |> columntable + s = + DBInterface.execute(db, "SELECT TrackId FROM PlaylistTrack") |> columntable - s = DBInterface.execute(db, "SELECT TrackId FROM PlaylistTrack") |> columntable @test r[1][1] == big(sum(convert(Vector{Int}, s[1]))) DBInterface.execute(db, "CREATE TABLE points (x INT, y INT, z INT)") - DBInterface.execute(db, "INSERT INTO points VALUES (?, ?, ?)", (1, 2, 3)) - DBInterface.execute(db, "INSERT INTO points VALUES (?, ?, ?)", (4, 5, 6)) - DBInterface.execute(db, "INSERT INTO points VALUES (?, ?, ?)", (7, 8, 9)) + DBInterface.execute( + db, + "INSERT INTO points VALUES (?, ?, ?)", + (1, 2, 3), + ) + DBInterface.execute( + db, + "INSERT INTO points VALUES (?, ?, ?)", + (4, 5, 6), + ) + DBInterface.execute( + db, + "INSERT INTO points VALUES (?, ?, ?)", + (7, 8, 9), + ) SQLite.register(db, Point3D(0, 0, 0), sumpoint) - r = DBInterface.execute(db, "SELECT sumpoint(x, y, z) FROM points") |> columntable + r = + DBInterface.execute( + db, + "SELECT sumpoint(x, y, z) FROM points", + ) |> columntable @test r[1][1] == Point3D(12, 15, 18) SQLite.drop!(db, "points") @@ -437,12 +555,13 @@ end @test_throws SQLiteException SQLite.drop!(db2, "nonexistant") # should not throw anything - SQLite.drop!(db2, "nonexistant", ifexists = true) + SQLite.drop!(db2, "nonexistant"; ifexists = true) # should drop "tab2" - SQLite.drop!(db2, "tab2", ifexists = true) - @test filter(x -> x.name == "tab2", SQLite.tables(db2)) |> length == 0 + SQLite.drop!(db2, "tab2"; ifexists = true) + @test filter(x -> x.name == "tab2", SQLite.tables(db2)) |> length == + 0 - SQLite.drop!(db, "sqlite_stat1", ifexists = true) + SQLite.drop!(db, "sqlite_stat1"; ifexists = true) tables = SQLite.tables(db) @test length(tables) == 11 end @@ -464,7 +583,6 @@ end end end - @testset "Issue #104: bind!() fails with named parameters" begin db = SQLite.DB() #In case the order of tests is changed DBInterface.execute(db, "CREATE TABLE IF NOT EXISTS tbl(a INTEGER);") @@ -533,7 +651,11 @@ end @testset "Issue #180, Query" begin param = "Hello!" - query = DBInterface.execute(SQLite.DB(), "SELECT ?1 UNION ALL SELECT ?1", [param]) + query = DBInterface.execute( + SQLite.DB(), + "SELECT ?1 UNION ALL SELECT ?1", + [param], + ) param = "x" for row in query @test row[1] == "Hello!" @@ -565,9 +687,6 @@ end DBInterface.close!(db) end - - - @testset "SQLite.execute()" begin db = SQLite.DB() DBInterface.execute(db, "CREATE TABLE T (x INT UNIQUE)") @@ -586,15 +705,17 @@ end r = DBInterface.execute(columntable, db, "SELECT * FROM T") @test r[1] == [1, 2, 3] - SQLite.execute(q, x = 4) + SQLite.execute(q; x = 4) r = DBInterface.execute(columntable, db, "SELECT * FROM T") @test r[1] == [1, 2, 3, 4] - SQLite.execute(db, "INSERT INTO T VALUES(:x)", x = 5) + SQLite.execute(db, "INSERT INTO T VALUES(:x)"; x = 5) r = DBInterface.execute(columntable, db, "SELECT * FROM T") @test r[1] == [1, 2, 3, 4, 5] - r = DBInterface.execute(db, strip(" SELECT * FROM T ")) |> columntable + r = + DBInterface.execute(db, strip(" SELECT * FROM T ")) |> + columntable @test r[1] == [1, 2, 3, 4, 5] SQLite.createindex!(db, "T", "x", "x_index"; unique = false) @@ -622,7 +743,13 @@ end @test DBInterface.lastrowid(r) == 5 r = DBInterface.execute(db, "SELECT * FROM T") |> columntable - SQLite.load!(nothing, Tables.rows(r), db, "T2", SQLite.tableinfo(db, "T2")) + SQLite.load!( + nothing, + Tables.rows(r), + db, + "T2", + SQLite.tableinfo(db, "T2"), + ) r2 = DBInterface.execute(db, "SELECT * FROM T2") |> columntable @test r == r2 end @@ -631,14 +758,14 @@ end @test SQLite.esc_id(["1", "2", "3"]) == "\"1\",\"2\",\"3\"" end - - @testset "Issue #193: Throw informative error on duplicate column names" begin db = SQLite.DB() - @test_throws SQLiteException SQLite.load!((a = [1, 2, 3], A = [1, 2, 3]), db) + @test_throws SQLiteException SQLite.load!( + (a = [1, 2, 3], A = [1, 2, 3]), + db, + ) end - @testset "Issue #216: Table should map by name" begin db = SQLite.DB() @@ -661,7 +788,6 @@ end @test_throws SQLiteException SQLite.load!(tbl3, db, "data") end - @testset "Test busy_timeout" begin db = SQLite.DB() @test SQLite.busy_timeout(db, 300) == 0 @@ -670,8 +796,10 @@ end @testset "Issue #253: Ensure query column names are unique by default" begin db = SQLite.DB() res = - DBInterface.execute(db, "select 1 as x2, 2 as x2, 3 as x2, 4 as x2_2") |> - columntable + DBInterface.execute( + db, + "select 1 as x2, 2 as x2, 3 as x2, 4 as x2_2", + ) |> columntable @test res == (x2 = [1], x2_1 = [2], x2_2 = [3], x2_2_1 = [4]) end @@ -680,8 +808,10 @@ end tbl = (a = [1, 2, 3], b = ["a", "b", "c"]) SQLite.load!(tbl, db, "escape 10.0%") r = - DBInterface.execute(db, "SELECT * FROM $(SQLite.esc_id("escape 10.0%"))") |> - columntable + DBInterface.execute( + db, + "SELECT * FROM $(SQLite.esc_id("escape 10.0%"))", + ) |> columntable @test r == tbl SQLite.drop!(db, "escape 10.0%") end @@ -690,7 +820,9 @@ end db = SQLite.DB() tbl = NamedTuple{(:a, Symbol("50.0%"))}(([1, 2, 3], ["a", "b", "c"])) SQLite.load!(tbl, db, "escape_colnames") - r = DBInterface.execute(db, "SELECT * FROM escape_colnames") |> columntable + r = + DBInterface.execute(db, "SELECT * FROM escape_colnames") |> + columntable @test r == tbl SQLite.drop!(db, "escape_colnames") end @@ -763,7 +895,6 @@ end close(db) rm(dbfile) end - end # @testset struct UnknownSchemaTable end @@ -771,8 +902,9 @@ struct UnknownSchemaTable end Tables.isrowtable(::Type{UnknownSchemaTable}) = true Tables.rows(x::UnknownSchemaTable) = x Base.length(x::UnknownSchemaTable) = 3 -Base.iterate(::UnknownSchemaTable, st = 1) = +function Base.iterate(::UnknownSchemaTable, st = 1) st == 4 ? nothing : ((a = 1, b = 2 + st, c = 3 + st), st + 1) +end @testset "misc" begin @@ -795,7 +927,11 @@ Base.iterate(::UnknownSchemaTable, st = 1) = db, "create table tmp ( a INTEGER NOT NULL PRIMARY KEY, b INTEGER, c INTEGER )", ) - @test_throws SQLite.SQLiteException SQLite.load!(UnknownSchemaTable(), db, "tmp") + @test_throws SQLite.SQLiteException SQLite.load!( + UnknownSchemaTable(), + db, + "tmp", + ) SQLite.load!(UnknownSchemaTable(), db, "tmp"; replace = true) tbl = DBInterface.execute(db, "select * from tmp") |> columntable @test tbl == (a = [1], b = [5], c = [6]) @@ -808,11 +944,13 @@ Base.iterate(::UnknownSchemaTable, st = 1) = @test isequal(tbl.x, [missing, :a]) db = SQLite.DB() - DBInterface.execute(db, "create table tmp (a integer, b integer, c integer)") + DBInterface.execute( + db, + "create table tmp (a integer, b integer, c integer)", + ) stmt = DBInterface.prepare(db, "INSERT INTO tmp VALUES(?, ?, ?)") tbl = (a = [1, 1, 1], b = [3, 4, 5], c = [4, 5, 6]) DBInterface.executemany(stmt, tbl) tbl2 = DBInterface.execute(db, "select * from tmp") |> columntable @test tbl == tbl2 - end