Skip to content
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
4 changes: 3 additions & 1 deletion src/DBInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ Similar in usage to `DBInterface.execute`, but allows passing multiple sets of p
of a single scalar value per parameter, an indexable collection should be passed for each parameter. By default, each set of
parameters will be looped over and `DBInterface.execute` will be called for each. Note that no result sets or cursors are returned
for any execution, so the usage is mainly intended for bulk INSERT statements. For compatibility, a `NamedTuple` or keyword batch
is passed to each execution positionally in field order. Use an `AbstractDict` batch when each execution must retain parameter names.
is passed to each execution positionally in field order. Both connection and prepared-statement forms accept keyword batches.
Use an `AbstractDict` batch when each execution must retain parameter names.
"""
function executemany(stmt::Statement, params)
param_collections = _parameter_collections(params)
Expand Down Expand Up @@ -343,6 +344,7 @@ function executemany(conn::Connection, sql::AbstractString, params)
end
end

executemany(stmt::Statement; kwargs...) = executemany(stmt, values(kwargs))
executemany(conn::Connection, sql::AbstractString; kwargs...) = executemany(conn, sql, values(kwargs))

"""
Expand Down
17 changes: 17 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,23 @@ end
@test all(params -> params isa AbstractVector, named_statement.executions)
@test all(cursor -> cursor.closed, named_statement.cursors)

keyword_statement = DBInterface.prepare(connection, "keywords")
DBInterface.executemany(keyword_statement; id=[1, 2], name=["one", "two"])
@test collect.(keyword_statement.executions) == [[1, "one"], [2, "two"]]
@test all(cursor -> cursor.closed, keyword_statement.cursors)
@test !keyword_statement.closed
@test_throws DBInterface.ParameterError DBInterface.executemany(keyword_statement; id=[1, 2], name=["one"])
@test length(keyword_statement.executions) == 2
DBInterface.executemany(keyword_statement; id=Int[], name=String[])
@test length(keyword_statement.executions) == 2

no_params_statement = DBInterface.prepare(connection, "no parameters")
DBInterface.executemany(no_params_statement)
@test length(no_params_statement.executions) == 1
@test isempty(only(no_params_statement.executions))
@test only(no_params_statement.cursors).closed
@test !no_params_statement.closed

dictionary_statement = DBInterface.prepare(connection, "dictionary")
DBInterface.executemany(dictionary_statement, Dict(:id => [1, 2], :name => ["one", "two"]))
@test Dict.(dictionary_statement.executions) == [
Expand Down
Loading