Skip to content

Commit f36bf1e

Browse files
committed
add execute(f, db, sql)
1 parent e544f99 commit f36bf1e

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

src/DBInterface.jl

+24-8
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ macro prepare(getDB, sql)
5757
end
5858
end
5959

60+
"""
61+
DBInterface.close!(stmt::DBInterface.Statement)
62+
63+
Close a prepared statement so further queries cannot be executed.
64+
"""
65+
close!(stmt::Statement)
66+
6067
"Any object that iterates \"rows\", which are objects that are property-accessible and indexable. See `DBInterface.execute` for more details on fetching query results."
6168
abstract type Cursor end
6269

@@ -79,6 +86,7 @@ const StatementParams = Union{PositionalStatementParams, NamedStatementParams}
7986
"""
8087
DBInterface.execute(conn::DBInterface.Connection, sql::AbstractString, [params]) => DBInterface.Cursor
8188
DBInterface.execute(stmt::DBInterface.Statement, [params]) => DBInterface.Cursor
89+
DBInterface.execute(f::Callable, conn::DBInterface.Connection, sql::AbstractString, [params])
8290
8391
Database packages should overload `DBInterface.execute` for a valid, prepared `DBInterface.Statement` subtype (the first method
8492
signature is defined in DBInterface.jl using `DBInterface.prepare`), which takes an optional `params` argument, which should be
@@ -92,15 +100,30 @@ to subtype `DBInterface.Cursor` explicitly as long as they satisfy the interface
92100
do not return results, an iterator is still expected to be returned that just iterates `nothing`, i.e. an "empty" iterator.
93101
94102
Note that `DBInterface.execute` returns ***a single*** `DBInterface.Cursor`, which represents a single resultset from the database.
95-
For use-cases involving multiple resultsets from a single query, see `DBInterface.executemultiple`.
103+
For use-cases involving multiple result-sets from a single query, see `DBInterface.executemultiple`.
104+
105+
If function `f` is provided, `DBInterface.execute` will return the result of applying `f` to the `DBInterface.Cursor` object
106+
and close the prepared statement upon exit.
96107
"""
97108
function execute end
98109

99110
execute(conn::Connection, sql::AbstractString, params::StatementParams) = execute(prepare(conn, sql), params)
100111

112+
function execute(f::Base.Callable, conn::Connection, sql::AbstractString, params::StatementParams)
113+
stmt = prepare(conn, sql)
114+
try
115+
cursor = execute(stmt, params)
116+
return f(cursor)
117+
finally
118+
close!(stmt)
119+
end
120+
end
121+
101122
# keyarg versions
102123
execute(stmt::Statement; kwargs...) = execute(stmt, kwargs.data)
103124
execute(conn::Connection, sql::AbstractString; kwargs...) = execute(conn, sql, kwargs.data) # FIXME should be in DBInterface
125+
execute(f::Base.Callable, conn::Connection, sql::AbstractString; kwargs...) = execute(f, conn, sql, kwargs.data)
126+
104127

105128
struct LazyIndex{T} <: AbstractVector{Any}
106129
x::T
@@ -157,13 +180,6 @@ executemultiple(conn::Connection, sql::AbstractString, params::StatementParams)
157180
executemultiple(stmt::Statement; kwargs...) = executemultiple(stmt, kwargs.data)
158181
executemultiple(conn::Connection, sql::AbstractString; kwargs...) = executemultiple(conn, sql, kwargs.data)
159182

160-
"""
161-
DBInterface.close!(stmt::DBInterface.Statement)
162-
163-
Close a prepared statement so further queries cannot be executed.
164-
"""
165-
close!(stmt::Statement)
166-
167183
"""
168184
DBInterface.lastrowid(x::Cursor) => Int
169185

0 commit comments

Comments
 (0)