|
1 | | -using DataStreams |
| 1 | +using Tables |
2 | 2 |
|
3 | 3 | const column_types = Dict( |
4 | 4 | JDBC_COLTYPE_ARRAY=>Array, |
@@ -57,41 +57,34 @@ colname(s::Source, col::Int) = getColumnName(s.md, col) |
57 | 57 | ncols(s::Source) = getColumnCount(s.md) |
58 | 58 |
|
59 | 59 | coltypes(s::Source) = Type[coltype(s, i) for i ∈ 1:ncols(s)] |
60 | | -colnames(s::Source) = String[colname(s, i) for i ∈ 1:ncols(s)] |
| 60 | +colnames(s::Source) = Symbol[Symbol(colname(s, i)) for i ∈ 1:ncols(s)] |
61 | 61 |
|
62 | | -# WARNING: this does not seem to actually work |
63 | | -Data.reset!(s::Source) = beforeFirst!(s.rs) |
| 62 | +Tables.istable(::Type{<:Source}) = true |
| 63 | +Tables.rowaccess(::Type{<:Source}) = true |
| 64 | +Tables.rows(s::Source) = s |
| 65 | +Tables.schema(s::Source) = Tables.Schema(colnames(s), coltypes(s)) |
64 | 66 |
|
65 | | -Data.isdone(s::Source, row::Int, col::Int) = isdone(s.rs) |
66 | | - |
67 | | -Data.schema(s::Source) = Data.Schema(coltypes(s), colnames(s), missing) |
68 | | - |
69 | | -Data.accesspattern(s::Source) = Data.Sequential |
70 | | - |
71 | | -Data.streamtype(::Type{Source}, ::Type{Data.Field}) = true |
72 | | -Data.streamtype(::Type{Source}, ::Type{Data.Column}) = false |
| 67 | +Base.IteratorSize(::Type{<:Source}) = Base.SizeUnknown() |
| 68 | +Base.eltype(s::Source) = namedtupletype(Tables.schema(s)) |
| 69 | +namedtupletype(::Tables.Schema{names, types}) where {names, types} = NamedTuple{names, types} |
| 70 | +namedtupletype(s::Source) = namedtupletype(Tables.schema(s)) |
73 | 71 |
|
74 | 72 | # TODO currently jdbc_get_method is very inefficient |
75 | 73 | pullfield(s::Source, col::Int) = jdbc_get_method(getColumnType(s.md, col))(s.rs, col) |
76 | 74 |
|
77 | | -# does not store current row number as a persistent state |
78 | | -function Data.streamfrom(s::Source, ::Type{Data.Field}, ::Type{T}, row::Int, col::Int) where T |
79 | | - convert(T, pullfield(s, col))::T |
80 | | -end |
81 | | -function Data.streamfrom(s::Source, ::Type{Data.Field}, ::Type{Union{T, Missing}}, |
82 | | - row::Int, col::Int) where T |
83 | | - o = pullfield(s, col) |
84 | | - if wasNull(s.rs) |
85 | | - return missing |
86 | | - end |
87 | | - convert(T, o)::T |
| 75 | +jdbcconvert(::Type{T}, s, x) where {T} = convert(T, x) |
| 76 | +jdbcconvert(::Type{Union{T, Missing}}, s, x) where {T} = wasNull(s.rs) ? missing : convert(T, x) |
| 77 | + |
| 78 | +function Base.iterate(s::Source, NT::Type{NamedTuple{names, types}}=namedtupletype(s)) where {names, types} |
| 79 | + isdone(s.rs) && return nothing |
| 80 | + NT(jdbcconvert(fieldtype(types, i), s, pullfield(s, i)) for i ∈ 1:fieldcount(types)), NT |
88 | 81 | end |
89 | 82 |
|
90 | | -load(::Type{T}, s::Source) where {T} = Data.close!(Data.stream!(s, T)) |
| 83 | +load(::Type{T}, s::Source) where {T} = T(Tables.materializer(T)(s)) |
91 | 84 | load(::Type{T}, rs::JResultSet) where {T} = load(T, Source(rs)) |
92 | 85 | load(::Type{T}, stmt::JStatement, query::AbstractString) where {T} = load(T, Source(stmt, query)) |
93 | 86 | load(::Type{T}, csr::Union{JDBC.Cursor,JDBCRowIterator}) where {T} = load(T, Source(csr)) |
94 | | -function load(::Type{T}, csr::Cursor, q::AbstractString) where T |
| 87 | +function load(::Type{T}, csr::Cursor, q::AbstractString) where {T} |
95 | 88 | execute!(csr, q) |
96 | 89 | load(T, csr) |
97 | 90 | end |
|
0 commit comments