Skip to content

Commit 913489b

Browse files
committed
Rename to DBInterface
1 parent 08284bb commit 913489b

File tree

6 files changed

+141
-141
lines changed

6 files changed

+141
-141
lines changed

LICENSE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
The DBI.jl package is licensed under the MIT "Expat" License:
1+
The DBInterface.jl package is licensed under the MIT "Expat" License:
22

33
> Copyright (c) 2019: JuliaDatabase Contributors.
44
>

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name = "DBI"
1+
name = "DBInterface"
22
uuid = "a10d1c49-ce27-4219-8d33-6db1a4562965"
33
authors = ["Jacob Quinn <[email protected]>"]
44
version = "1.0.0"

README.md

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
# DBI.jl
1+
# DBInterface.jl
22

33
### Purpose
4-
DBI.jl provides interface definitions to allow common database operations to be implemented consistently
4+
DBInterface.jl provides interface definitions to allow common database operations to be implemented consistently
55
across various database packages.
66

77
### For Users
8-
To use DBI.jl, select an implementing database package, then utilize the consistent DBI.jl interface methods:
8+
To use DBInterface.jl, select an implementing database package, then utilize the consistent DBInterface.jl interface methods:
99
```julia
10-
conn = DBI.connect(T, args...; kw...) # create a connection to a specific database T; required parameters are database-specific
10+
conn = DBInterface.connect(T, args...; kw...) # create a connection to a specific database T; required parameters are database-specific
1111

12-
stmt = DBI.prepare(conn, sql) # prepare a sql statement against the connection; returns a statement object
12+
stmt = DBInterface.prepare(conn, sql) # prepare a sql statement against the connection; returns a statement object
1313

14-
results = DBI.execute!(stmt) # execute a prepared statement; returns an iterator of rows (property-accessible & indexable)
14+
results = DBInterface.execute!(stmt) # execute a prepared statement; returns an iterator of rows (property-accessible & indexable)
1515

1616
# example of using a query resultset
1717
for row in results
@@ -24,26 +24,26 @@ end
2424
df = DataFrame(results)
2525
CSV.write("results.csv", results)
2626

27-
results = DBI.execute!(conn, sql) # convenience method if statement preparation/re-use isn't needed
27+
results = DBInterface.execute!(conn, sql) # convenience method if statement preparation/re-use isn't needed
2828

29-
stmt = DBI.prepare(conn, "INSERT INTO test_table VALUES(?, ?)") # prepare a statement with positional parameters
29+
stmt = DBInterface.prepare(conn, "INSERT INTO test_table VALUES(?, ?)") # prepare a statement with positional parameters
3030

31-
DBI.execute!(stmt, 1, 3.14) # execute the prepared INSERT statement, passing 1 and 3.14 as positional parameters
31+
DBInterface.execute!(stmt, 1, 3.14) # execute the prepared INSERT statement, passing 1 and 3.14 as positional parameters
3232

33-
stmt = DBI.prepare(conn, "INSERT INTO test_table VALUES(:col1, :col2)") # prepare a statement with named parameters
33+
stmt = DBInterface.prepare(conn, "INSERT INTO test_table VALUES(:col1, :col2)") # prepare a statement with named parameters
3434

35-
DBI.execute!(stmt; col1=1, col2=3.14) # execute the prepared INSERT statement, with 1 and 3.14 as named parameters
35+
DBInterface.execute!(stmt; col1=1, col2=3.14) # execute the prepared INSERT statement, with 1 and 3.14 as named parameters
3636

37-
DBI.executemany!(stmt; col1=[1,2,3,4,5], col2=[3.14, 1.23, 2.34 3.45, 4.56]) # execute the prepared statement multiple times for each set of named parameters; each named parameter must be an indexable collection
37+
DBInterface.executemany!(stmt; col1=[1,2,3,4,5], col2=[3.14, 1.23, 2.34 3.45, 4.56]) # execute the prepared statement multiple times for each set of named parameters; each named parameter must be an indexable collection
3838
```
3939

4040
### For Database Package Developers
4141
See the documentation for the following to understand required types and inheritance, as well as functions to overload:
4242
```julia
43-
DBI.Connection
44-
DBI.connect
45-
DBI.close!
46-
DBI.Statement
47-
DBI.prepare
48-
DBI.execute!
43+
DBInterface.Connection
44+
DBInterface.connect
45+
DBInterface.close!
46+
DBInterface.Statement
47+
DBInterface.prepare
48+
DBInterface.execute!
4949
```

src/DBI.jl

-119
This file was deleted.

src/DBInterface.jl

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
module DBInterface
2+
3+
"Database packages should subtype `DBInterface.Connection` which represents a connection to a database"
4+
abstract type Connection end
5+
6+
"""
7+
DBInterface.connect(DB, args...; kw...) => DBInterface.Connection
8+
9+
Database packages should overload `DBInterface.connect` for a specific `DB` `DBInterface.Connection` subtype
10+
that returns a valid, live database connection that can be queried against.
11+
"""
12+
function connect end
13+
14+
connect(T, args...; kw...) = throw(NotImplementedError("`DBInterface.connect` not implemented for `$T`"))
15+
16+
"""
17+
DBInterface.close!(conn::DBInterface.Connection)
18+
19+
Immediately closes a database connection so further queries cannot be processed.
20+
"""
21+
function close! end
22+
23+
close!(conn::DBInterface.Connection) = throw(NotImplementedError("`DBInterface.close!` not implemented for `$(typeof(conn))`"))
24+
25+
"Database packages should provide a `DBInterface.Statement` subtype which represents a valid, prepared SQL statement that can be executed repeatedly"
26+
abstract type Statement end
27+
28+
"""
29+
DBInterface.prepare(conn::DBInterface.Connection, sql::AbstractString) => DBInterface.Statement
30+
31+
Database packages should overload `DBInterface.prepare` for a specific `DBInterface.Connection` subtype, that validates and prepares
32+
a SQL statement given as an `AbstractString` `sql` argument, and returns a `DBInterface.Statement` subtype. It is expected
33+
that `DBInterface.Statement`s are only valid for the lifetime of the `DBInterface.Connection` object against which they are prepared.
34+
"""
35+
function prepare end
36+
37+
prepare(conn::DBInterface.Connection, sql::AbstractString) = throw(NotImplementedError("`DBInterface.prepare` not implemented for `$(typeof(conn))`"))
38+
39+
"Any object that iterates \"rows\", which are objects that are property-accessible and indexable. See `DBInterface.execute!` for more details on fetching query results."
40+
abstract type Cursor end
41+
42+
"""
43+
DBInterface.execute!(conn::DBInterface.Connection, sql::AbstractString, args...; kw...) => DBInterface.Cursor
44+
DBInterface.execute!(stmt::DBInterface.Statement, args...; kw...) => DBInterface.Cursor
45+
46+
Database packages should overload `DBInterface.execute!` for a valid, prepared `DBInterface.Statement` subtype (the first method
47+
signature is defined in DBInterface.jl using `DBInterface.prepare`), which takes zero or more `args` or `kw` arguments that should
48+
be bound against the `stmt` (`args` as positional parameters, `kw` as named parameters, but not mixed) before executing the query
49+
against the database. `DBInterface.execute!` should return a valid `DBInterface.Cursor` object, which is any iterator of "rows",
50+
which themselves must be property-accessible (i.e. implement `propertynames` and `getproperty` for value access by name),
51+
and indexable (i.e. implement `length` and `getindex` for value access by index). These "result" objects do not need
52+
to subtype `DBInterface.Cursor` explicitly as long as they satisfy the interface. For DDL/DML SQL statements, which typically
53+
do not return results, an iterator is still expected to be returned that just iterates `nothing`, i.e. an "empty" iterator.
54+
"""
55+
function execute! end
56+
57+
execute!(stmt::DBInterface.Statement, args...; kw...) = throw(NotImplementedError("`DBInterface.execute!` not implemented for `$(typeof(stmt))`"))
58+
59+
DBInterface.execute!(conn::Connection, sql::AbstractString, args...; kw...) = DBInterface.execute!(DBInterface.prepare(conn, sql), args...; kw...)
60+
61+
struct ParameterError
62+
msg::String
63+
end
64+
65+
"""
66+
DBInterface.executemany!(conn::DBInterface.Connect, sql::AbstractString, args...; kw...) => Nothing
67+
DBInterface.executemany!(stmt::DBInterface.Statement, args...; kw...) => Nothing
68+
69+
Similar to
70+
"""
71+
function executemany!(stmt::DBInterface.Statement, args...; kw...)
72+
if !isempty(args)
73+
arg = args[1]
74+
len = length(arg)
75+
all(x -> length(x) == len, args) || throw(ParameterError("positional parameters provided to `DBInterface.executemany!` do not all have the same number of parameters"))
76+
for i = 1:len
77+
xargs = map(x -> x[i], args)
78+
DBInterface.execute!(stmt, xargs...)
79+
end
80+
elseif !isempty(kw)
81+
k = kw[1]
82+
len = length(k)
83+
all(x -> length(x) == len, kw) || throw(ParameterError("named parameters provided to `DBInterface.executemany!` do not all have the same number of parameters"))
84+
for i = 1:len
85+
xargs = collect(k=>v[i] for (k, v) in kw)
86+
DBInterface.execute!(stmt; xargs...)
87+
end
88+
else
89+
DBInterface.execute!(stmt)
90+
end
91+
return
92+
end
93+
94+
DBInterface.executemany!(conn::Connection, sql::AbstractString, args...; kw...) = DBInterface.executemany!(DBInterface.prepare(conn, sql), args...; kw...)
95+
96+
"""
97+
DBInterface.close!(x::Cursor) => Nothing
98+
99+
Immediately close a resultset cursor. Database packages should overload for the provided resultset `Cursor` object.
100+
"""
101+
close!(x) = throw(NotImplementedError("`DBInterface.close!` not implemented for `$(typeof(x))`"))
102+
103+
# exception handling
104+
"Error for signaling a database package hasn't implemented an interface method"
105+
struct NotImplementedError <: Exception
106+
msg::String
107+
end
108+
109+
"Standard warning object for various database operations"
110+
struct Warning
111+
msg::String
112+
end
113+
114+
"Fallback, generic error object for database operations"
115+
struct Error <: Exception
116+
msg::String
117+
end
118+
119+
end # module

test/runtests.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
using DBI, Test
1+
using DBInterface, Test
22

3-
@test_throws DBI.NotImplementedError DBI.connect(Int64)
3+
@test_throws DBInterface.NotImplementedError DBInterface.connect(Int64)

0 commit comments

Comments
 (0)