Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getconnection/transaction #40

Merged
merged 1 commit into from
Oct 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ across various database packages.
## Functions
```@docs
DBInterface.connect
DBInterface.getconnection
DBInterface.prepare
DBInterface.@prepare
DBInterface.execute
DBInterface.transaction
DBInterface.executemany
DBInterface.executemultiple
DBInterface.close!
Expand Down
28 changes: 25 additions & 3 deletions src/DBInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ close!(conn::Connection)
"Database packages should provide a `DBInterface.Statement` subtype which represents a valid, prepared SQL statement that can be executed repeatedly"
abstract type Statement end

"""
DBInterface.getconnection(::DBInterface.Statement)

For a valid `DBInterface.Statement`, return the `DBInterface.Connection` the statement
is associated with.
"""
function getconnection end

"""
DBInterface.prepare(conn::DBInterface.Connection, sql::AbstractString) => DBInterface.Statement
DBInterface.prepare(f::Function, sql::AbstractString) => DBInterface.Statement
Expand Down Expand Up @@ -145,6 +153,18 @@ execute(conn::Connection, sql::AbstractString; kwargs...) = execute(conn, sql, v
execute(f::Base.Callable, conn::Connection, sql::AbstractString; kwargs...) = execute(f, conn, sql, values(kwargs))
execute(f::Base.Callable, stmt::Statement; kwargs...) = execute(f, stmt, values(kwargs))

"""
DBInterface.transaction(f, conn::DBInterface.Connection)

Open a transaction against a database connection `conn`, execute a closure `f`,
then "commit" the transaction after executing the closure function. The default
definition in DBInterface.jl is a no-op in that it just executes the closure
function with no transaction. Used in `DBInterface.executemany` to wrap the
individual execute calls in a transaction since this often leads to much better
performance in database systems.
"""
transaction(f, ::Connection) = f()

struct LazyIndex{T} <: AbstractVector{Any}
x::T
i::Int
Expand All @@ -170,9 +190,11 @@ function executemany(stmt::Statement, params)
param = params[1]
len = length(param)
all(x -> length(x) == len, params) || throw(ParameterError("parameters provided to `DBInterface.executemany!` do not all have the same number of parameters"))
for i = 1:len
xargs = LazyIndex(params, i)
execute(stmt, xargs)
transaction(getconnection(stmt)) do
for i = 1:len
xargs = LazyIndex(params, i)
execute(stmt, xargs)
end
end
else
execute(stmt)
Expand Down