Skip to content

Commit

Permalink
Wrap catalog functions (#374)
Browse files Browse the repository at this point in the history
* Wrap SQLTables and SQLColumns catalog functions

* Add tests for catalog functions
  • Loading branch information
xitology authored Jun 3, 2023
1 parent 284fa0d commit a6e4fb7
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ DBInterface.executemultiple
ODBC.load
```

### Catalog functions
```@docs
ODBC.tables
ODBC.columns
```

### ODBC administrative functions
```@docs
ODBC.drivers
Expand Down
34 changes: 34 additions & 0 deletions src/API.jl
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,40 @@ function diagnostics(h::Handle)
return String(take!(io))
end

function catalogstr(str::AbstractString)
buf = cwstring(str)
return (buf, length(buf))
end

catalogstr(::Union{Nothing, Missing}) =
return (C_NULL, 0)

function SQLTables(stmt::Ptr{Cvoid}, catalogname, schemaname, tablename, tabletype)
c, clen = catalogstr(catalogname)
s, slen = catalogstr(schemaname)
t, tlen = catalogstr(tablename)
tt, ttlen = catalogstr(tabletype)
@odbc(:SQLTablesW,
(Ptr{Cvoid}, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT),
stmt, c, clen, s, slen, t, tlen, tt, ttlen)
end

tables(stmt::Handle, catalogname, schemaname, tablename, tabletype) =
@checksuccess stmt SQLTables(getptr(stmt), catalogname, schemaname, tablename, tabletype)

function SQLColumns(stmt::Ptr{Cvoid}, catalogname, schemaname, tablename, columnname)
c, clen = catalogstr(catalogname)
s, slen = catalogstr(schemaname)
t, tlen = catalogstr(tablename)
col, collen = catalogstr(columnname)
@odbc(:SQLColumnsW,
(Ptr{Cvoid}, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT),
stmt, c, clen, s, slen, t, tlen, col, collen)
end

columns(stmt::Handle, catalogname, schemaname, tablename, columnname) =
@checksuccess stmt SQLColumns(getptr(stmt), catalogname, schemaname, tablename, columnname)

macro checkinst(expr)
esc(quote
ret = $expr
Expand Down
1 change: 1 addition & 0 deletions src/ODBC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ include("API.jl")
include("utils.jl")
include("dbinterface.jl")
include("load.jl")
include("catalog.jl")

"""
ODBC.setdebug(debug::Bool=true, tracefile::String=joinpath(tempdir(), "odbc.log"))
Expand Down
55 changes: 55 additions & 0 deletions src/catalog.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Catalog functions.

"""
tables(conn; catalogname=nothing, schemaname=nothing, tablename=nothing, tabletype=nothing) -> ODBC.Cursor
Find tables by the given criteria. This function returns a `Cursor` object that
produces one row per matching table.
Search criteria include:
* `catalogname`: search pattern for catalog names
* `schemaname`: search pattern for schema names
* `tablename`: search pattern for table names
* `tabletypes`: comma-separated list of table types
A search pattern may contain an underscore (`_`) to represent any single character
and a percent sign (`%`) to represent any sequence of zero or more characters.
Use an escape character (driver-specific, but usually `\\`) to include underscores,
percent signs, and escape characters as literals.
"""
function tables(conn; catalogname=nothing, schemaname=nothing, tablename=nothing, tabletype=nothing)
clear!(conn)
stmt = API.Handle(API.SQL_HANDLE_STMT, API.getptr(conn.dbc))
conn.stmts[stmt] = 0
conn.cursorstmt = stmt
API.enableasync(stmt)
API.tables(stmt, catalogname, schemaname, tablename, tabletype)
return Cursor(stmt)
end

"""
columns(conn; catalogname=nothing, schemaname=nothing, tablename=nothing, columnname=nothing) -> ODBC.Cursor
Find columns by the given criteria. This function returns a `Cursor` object that
produces one row per matching column.
Search criteria include:
* `catalogname`: name of the catalog
* `schemaname`: search pattern for schema names
* `tablename`: search pattern for table names
* `columnname`: search pattern for column names
A search pattern may contain an underscore (`_`) to represent any single character
and a percent sign (`%`) to represent any sequence of zero or more characters.
Use an escape character (driver-specific, but usually `\\`) to include underscores,
percent signs, and escape characters as literals.
"""
function columns(conn; catalogname=nothing, schemaname=nothing, tablename=nothing, columnname=nothing)
clear!(conn)
stmt = API.Handle(API.SQL_HANDLE_STMT, API.getptr(conn.dbc))
conn.stmts[stmt] = 0
conn.cursorstmt = stmt
API.enableasync(stmt)
API.columns(stmt, catalogname, schemaname, tablename, columnname)
return Cursor(stmt)
end
4 changes: 4 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ DBInterface.execute(conn, "INSERT INTO big_decimal (`dec`) VALUES (1234567890123
ret = DBInterface.execute(conn, "select * from big_decimal") |> columntable
@test ret.dec[1] == d128"1.2345678901234567891e17"

ret = ODBC.tables(conn, tablename="emp%") |> columntable
@test ret.TABLE_NAME == ["Employee", "Employee2", "Employee_copy"]
ret = ODBC.columns(conn, tablename="emp%", columnname="望研") |> columntable
@test ret.COLUMN_NAME == ["望研"]

DBInterface.execute(conn, """DROP USER IF EXISTS 'authtest'""")
DBInterface.execute(conn, """CREATE USER 'authtest' IDENTIFIED BY 'authtestpw'""")
Expand Down

0 comments on commit a6e4fb7

Please sign in to comment.