diff --git a/Project.toml b/Project.toml index 123cb6f..5e4a70f 100644 --- a/Project.toml +++ b/Project.toml @@ -9,6 +9,7 @@ Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" [compat] +Tables = "1" julia = "1" [extras] diff --git a/src/Table.jl b/src/Table.jl index 9dab645..724c001 100644 --- a/src/Table.jl +++ b/src/Table.jl @@ -66,8 +66,7 @@ end end end -Tables.istable(::Type{<:Table}) = true -Tables.rowaccess(::Type{<:Table}) = true +Tables.isrowtable(::Type{<:Table}) = true Tables.columnaccess(::Type{<:Table}) = true Tables.schema(::Table{T}) where {T} = Tables.Schema(T) Tables.materializer(::Table) = Table @@ -199,6 +198,31 @@ function Base.append!(t::Table{<:NamedTuple{names}}, t2::Table{<:NamedTuple{name return t end +_asnamedtuple(T) = data -> _asnamedtuple(T, data) +function _asnamedtuple(::Type{T}, data) where {names, T<:NamedTuple{names}} + if data isa NamedTuple + return T(data) + else + return T(Tuple(getproperty(data, n) for n in names)) + end +end + +function append_columnaccess!(t::Table, t2) + cols = _asnamedtuple(NamedTuple{columnnames(t)}, columns(t2)) + map(append!, columns(t), cols) + return t +end + +append_rows!(t::Table, rows) = + mapfoldl(_asnamedtuple(NamedTuple{columnnames(t)}), push!, rows; init = t) + +function Base.append!(t::Table, rows) + if Tables.isrowtable(rows) && Tables.columnaccess(rows) + return append_columnaccess!(t, rows) + end + return append_rows!(t, rows) +end + function Base.popfirst!(t::Table) return map(popfirst!, columns(t)) end diff --git a/test/Table.jl b/test/Table.jl index 9939416..1ed13b9 100644 --- a/test/Table.jl +++ b/test/Table.jl @@ -188,6 +188,26 @@ @test isequal(Table(t |> rowtable), t) end + @testset "append!(_, rows(::$(typeof(t2))))" for t2 in Any[ + [(a=3, b=4)], + (a=[3], b=[4]), + ] + t = Table(a=[1], b=[2]) + @test append!(t, Tables.rows(t2)) == Table(a = [1, 3], b = [2, 4]) + end + + @testset "append! error handling" begin + err = nothing + @test try + append!(Table(a = [1], b = [2]), nothing) + false + catch err + true + end + @test err isa MethodError + @test err.f === iterate + end + @testset "group" begin t = Table(a = [1,2,1], b = [2.0, 4.0, 6.0]) out = group(getproperty(:a), t)