diff --git a/src/JDBC.jl b/src/JDBC.jl index 4fe19b9..15da065 100644 --- a/src/JDBC.jl +++ b/src/JDBC.jl @@ -640,7 +640,7 @@ export getTableMetaData, JDBCRowIterator include("interface.jl") -include("datastreams.jl") +include("tables.jl") end # module diff --git a/src/datastreams.jl b/src/tables.jl similarity index 75% rename from src/datastreams.jl rename to src/tables.jl index 1a96c86..a3e129a 100644 --- a/src/datastreams.jl +++ b/src/tables.jl @@ -1,4 +1,4 @@ -using DataStreams +using Tables const column_types = Dict( JDBC_COLTYPE_ARRAY=>Array, @@ -57,37 +57,30 @@ colname(s::Source, col::Int) = getColumnName(s.md, col) ncols(s::Source) = getColumnCount(s.md) coltypes(s::Source) = Type[coltype(s, i) for i ∈ 1:ncols(s)] -colnames(s::Source) = String[colname(s, i) for i ∈ 1:ncols(s)] +colnames(s::Source) = Symbol[colname(s, i) for i ∈ 1:ncols(s)] -# WARNING: this does not seem to actually work -Data.reset!(s::Source) = beforeFirst!(s.rs) +Tables.istable(::Type{<:Source}) = true +Tables.rowaccess(::Type{<:Source}) = true +Tables.rows(s::Source) = s +Tables.schema(s::Source) = Tables.Schema(colnames(s), coltypes(s)) -Data.isdone(s::Source, row::Int, col::Int) = isdone(s.rs) - -Data.schema(s::Source) = Data.Schema(coltypes(s), colnames(s), missing) - -Data.accesspattern(s::Source) = Data.Sequential - -Data.streamtype(::Type{Source}, ::Type{Data.Field}) = true -Data.streamtype(::Type{Source}, ::Type{Data.Column}) = false +Base.IteratorSize(::Type{<:Source}) = Base.SizeUnknown() +Base.eltype(s::Source) = namedtupletype(Tables.schema(s)) +namedtupletype(::Tables.Schema{names, types}) where {names, types} = NamedTuple{names, types} # TODO currently jdbc_get_method is very inefficient pullfield(s::Source, col::Int) = jdbc_get_method(getColumnType(s.md, col))(s.rs, col) -# does not store current row number as a persistent state -function Data.streamfrom(s::Source, ::Type{Data.Field}, ::Type{T}, row::Int, col::Int) where T - convert(T, pullfield(s, col))::T -end -function Data.streamfrom(s::Source, ::Type{Data.Field}, ::Type{Union{T, Missing}}, - row::Int, col::Int) where T - o = pullfield(s, col) - if wasNull(s.rs) - return missing - end - convert(T, o)::T +jdbcconvert(::Type{T}, s, x) where {T} = convert(T, x) +jdbcconvert(::Type{Union{T, Missing}}, s, x) where {T} = wasNull(s.rs) ? missing : convert(T, x) + +function Base.iterate(s::Source, NT::NamedTuple{names, types}=namedtupletype(s)) where {names, types} + isdone(s.rs) && return nothing + return NT(convert(fieldtype(types, i), s, pullfield(s, i)) for i = 1:fieldcount(types)), NT end load(::Type{T}, s::Source) where {T} = Data.close!(Data.stream!(s, T)) +load(::Type{T}, s::Source) where {T} = Tables.materializer(T)(s) load(::Type{T}, rs::JResultSet) where {T} = load(T, Source(rs)) load(::Type{T}, stmt::JStatement, query::AbstractString) where {T} = load(T, Source(stmt, query)) load(::Type{T}, csr::Union{JDBC.Cursor,JDBCRowIterator}) where {T} = load(T, Source(csr))