add reading metadata from Arrow.Table
diff --git a/src/table.jl b/src/table.jl
index 882a99b..37885dd 100644
--- a/src/table.jl
+++ b/src/table.jl
@@ -360,6 +360,53 @@
getmetadata(t::Table) = getfield(t, :metadata)[]
getmetadata(::Any) = nothing
+DataAPI.metadatasupport(::Type{Table}) = (read=true, write=false)
+DataAPI.colmetadatasupport(::Type{Table}) = (read=true, write=false)
+
+function DataAPI.metadata(t::Table, key::AbstractString; style::Bool=false)
+ meta = getmetadata(t)[key]
+ return style ? (meta, :default) : meta
+end
+
+function DataAPI.metadata(t::Table, key::AbstractString, default; style::Bool=false)
+ meta = getmetadata(t)
+ if meta !== nothing
+ haskey(meta, key) && return style ? meta[key] : (meta[key], :default)
+ end
+ return style ? (default, :default) : default
+end
+
+function DataAPI.metadatakeys(t::Table)
+ meta = getmetadata(t)
+ meta === nothing && return ()
+ return keys(meta)
+end
+
+function DataAPI.colmetadata(t::Table, col, key::AbstractString; style::Bool=false)
+ meta = getmetadata(t[col])[key]
+ return style ? (meta, :default) : meta
+end
+
+function DataAPI.colmetadata(t::Table, col, key::AbstractString, default; style::Bool=false)
+ meta = getmetadata(t[col])
+ if meta !== nothing
+ haskey(meta, key) && return style ? (meta[key], :default) : meta[key]
+ end
+ return style ? (default, :default) : default
+end
+
+function DataAPI.colmetadatakeys(t::Table, col)
+ meta = getmetadata(t[col])
+ meta === nothing && return ()
+ return keys(meta)
+end
+
+function DataAPI.colmetadatakeys(t::Table)
+ return (col => DataAPI.colmetadatakeys(t, col) for
+ col in Tables.columnnames(t) if
+ getmetadata(t[col]) !== nothing)
+end
+
Tables.istable(::Table) = true
Tables.columnaccess(::Table) = true
Tables.columns(t::Table) = Tables.CopiedColumns(t)
diff --git a/test/runtests.jl b/test/runtests.jl
index 48ca399..9def564 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -1016,4 +1016,44 @@
# end
end # @testset "misc"
+
+ @testset "DataAPI.metadata" begin
+ df = DataFrame(a=1, b=2, c=3)
+ for i in 1:2
+ io = IOBuffer()
+ if i == 1 # skip writing metadata in the first iteration
+ Arrow.write(io, df)
+ else
+ Arrow.write(io, df, metadata=metadata(df), colmetadata=colmetadata(df))
+ end
+ seekstart(io)
+ tbl = Arrow.Table(io)
+
+ @test DataAPI.metadatasupport(typeof(tbl)) == (read=true, write=false)
+ @test metadata(tbl) == metadata(df)
+ @test metadata(tbl; style=true) == metadata(df; style=true)
+ @test_throws Exception metadata(tbl, "xyz")
+ @test metadata(tbl, "xyz", "something") == "something"
+ @test metadata(tbl, "xyz", "something"; style=true) == ("something", :default)
+ @test metadatakeys(tbl) == metadatakeys(df)
+
+ @test DataAPI.colmetadatasupport(typeof(tbl)) == (read=true, write=false)
+ @test colmetadata(tbl) == colmetadata(df)
+ @test colmetadata(tbl; style=true) == colmetadata(df; style=true)
+ @test_throws MethodError colmetadata(tbl, "xyz")
+ @test_throws KeyError colmetadata(tbl, :xyz)
+ @test colmetadata(tbl, :b) == colmetadata(df, :b)
+ @test_throws MethodError colmetadata(tbl, :b, "xyz")
+ @test colmetadata(tbl, :b, "xyz", "something") == "something"
+ @test colmetadata(tbl, :b, "xyz", "something"; style=true) == ("something", :default)
+ @test Set(colmetadatakeys(tbl)) == Set(colmetadatakeys(df))
+
+ # add metadata for the second iteration
+ metadata!(df, "tkey", "tvalue")
+ metadata!(df, "tkey2", "tvalue2")
+ colmetadata!(df, :a, "ackey", "acvalue")
+ colmetadata!(df, :a, "ackey2", "acvalue2")
+ colmetadata!(df, :c, "cckey", "ccvalue")
+ end
+ end # @testset "DataAPI.metadata"
end