Skip to content

Commit a6e4fb7

Browse files
authored
Wrap catalog functions (#374)
* Wrap SQLTables and SQLColumns catalog functions * Add tests for catalog functions
1 parent 284fa0d commit a6e4fb7

File tree

5 files changed

+100
-0
lines changed

5 files changed

+100
-0
lines changed

docs/src/index.md

+6
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ DBInterface.executemultiple
171171
ODBC.load
172172
```
173173

174+
### Catalog functions
175+
```@docs
176+
ODBC.tables
177+
ODBC.columns
178+
```
179+
174180
### ODBC administrative functions
175181
```@docs
176182
ODBC.drivers

src/API.jl

+34
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,40 @@ function diagnostics(h::Handle)
564564
return String(take!(io))
565565
end
566566

567+
function catalogstr(str::AbstractString)
568+
buf = cwstring(str)
569+
return (buf, length(buf))
570+
end
571+
572+
catalogstr(::Union{Nothing, Missing}) =
573+
return (C_NULL, 0)
574+
575+
function SQLTables(stmt::Ptr{Cvoid}, catalogname, schemaname, tablename, tabletype)
576+
c, clen = catalogstr(catalogname)
577+
s, slen = catalogstr(schemaname)
578+
t, tlen = catalogstr(tablename)
579+
tt, ttlen = catalogstr(tabletype)
580+
@odbc(:SQLTablesW,
581+
(Ptr{Cvoid}, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT),
582+
stmt, c, clen, s, slen, t, tlen, tt, ttlen)
583+
end
584+
585+
tables(stmt::Handle, catalogname, schemaname, tablename, tabletype) =
586+
@checksuccess stmt SQLTables(getptr(stmt), catalogname, schemaname, tablename, tabletype)
587+
588+
function SQLColumns(stmt::Ptr{Cvoid}, catalogname, schemaname, tablename, columnname)
589+
c, clen = catalogstr(catalogname)
590+
s, slen = catalogstr(schemaname)
591+
t, tlen = catalogstr(tablename)
592+
col, collen = catalogstr(columnname)
593+
@odbc(:SQLColumnsW,
594+
(Ptr{Cvoid}, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT, Ptr{SQLWCHAR}, SQLSMALLINT),
595+
stmt, c, clen, s, slen, t, tlen, col, collen)
596+
end
597+
598+
columns(stmt::Handle, catalogname, schemaname, tablename, columnname) =
599+
@checksuccess stmt SQLColumns(getptr(stmt), catalogname, schemaname, tablename, columnname)
600+
567601
macro checkinst(expr)
568602
esc(quote
569603
ret = $expr

src/ODBC.jl

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ include("API.jl")
88
include("utils.jl")
99
include("dbinterface.jl")
1010
include("load.jl")
11+
include("catalog.jl")
1112

1213
"""
1314
ODBC.setdebug(debug::Bool=true, tracefile::String=joinpath(tempdir(), "odbc.log"))

src/catalog.jl

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Catalog functions.
2+
3+
"""
4+
tables(conn; catalogname=nothing, schemaname=nothing, tablename=nothing, tabletype=nothing) -> ODBC.Cursor
5+
6+
Find tables by the given criteria. This function returns a `Cursor` object that
7+
produces one row per matching table.
8+
9+
Search criteria include:
10+
* `catalogname`: search pattern for catalog names
11+
* `schemaname`: search pattern for schema names
12+
* `tablename`: search pattern for table names
13+
* `tabletypes`: comma-separated list of table types
14+
15+
A search pattern may contain an underscore (`_`) to represent any single character
16+
and a percent sign (`%`) to represent any sequence of zero or more characters.
17+
Use an escape character (driver-specific, but usually `\\`) to include underscores,
18+
percent signs, and escape characters as literals.
19+
"""
20+
function tables(conn; catalogname=nothing, schemaname=nothing, tablename=nothing, tabletype=nothing)
21+
clear!(conn)
22+
stmt = API.Handle(API.SQL_HANDLE_STMT, API.getptr(conn.dbc))
23+
conn.stmts[stmt] = 0
24+
conn.cursorstmt = stmt
25+
API.enableasync(stmt)
26+
API.tables(stmt, catalogname, schemaname, tablename, tabletype)
27+
return Cursor(stmt)
28+
end
29+
30+
"""
31+
columns(conn; catalogname=nothing, schemaname=nothing, tablename=nothing, columnname=nothing) -> ODBC.Cursor
32+
33+
Find columns by the given criteria. This function returns a `Cursor` object that
34+
produces one row per matching column.
35+
36+
Search criteria include:
37+
* `catalogname`: name of the catalog
38+
* `schemaname`: search pattern for schema names
39+
* `tablename`: search pattern for table names
40+
* `columnname`: search pattern for column names
41+
42+
A search pattern may contain an underscore (`_`) to represent any single character
43+
and a percent sign (`%`) to represent any sequence of zero or more characters.
44+
Use an escape character (driver-specific, but usually `\\`) to include underscores,
45+
percent signs, and escape characters as literals.
46+
"""
47+
function columns(conn; catalogname=nothing, schemaname=nothing, tablename=nothing, columnname=nothing)
48+
clear!(conn)
49+
stmt = API.Handle(API.SQL_HANDLE_STMT, API.getptr(conn.dbc))
50+
conn.stmts[stmt] = 0
51+
conn.cursorstmt = stmt
52+
API.enableasync(stmt)
53+
API.columns(stmt, catalogname, schemaname, tablename, columnname)
54+
return Cursor(stmt)
55+
end

test/runtests.jl

+4
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ DBInterface.execute(conn, "INSERT INTO big_decimal (`dec`) VALUES (1234567890123
283283
ret = DBInterface.execute(conn, "select * from big_decimal") |> columntable
284284
@test ret.dec[1] == d128"1.2345678901234567891e17"
285285

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

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

0 commit comments

Comments
 (0)