Skip to content

Commit 69313ee

Browse files
authored
make it easier to work with metadata by providing more default behaviors (#56)
1 parent ca91305 commit 69313ee

File tree

3 files changed

+82
-13
lines changed

3 files changed

+82
-13
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "DataAPI"
22
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
33
authors = ["quinnj <[email protected]>"]
4-
version = "1.12.0"
4+
version = "1.13.0"
55

66
[compat]
77
julia = "1"

src/DataAPI.jl

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,28 @@ mapping for `key` is missing. If `style=true` return `(default, :default)`.
346346
"""
347347
function metadata end
348348

349+
"""
350+
metadata(x; style::Bool=false)
351+
352+
Return a dictionary mapping all metadata keys to metadata values associated
353+
with object `x`. Throw an error if `x` does not support reading metadata.
354+
355+
If `style=true` values are tuples of metadata value and metadata style. Metadata
356+
style is an additional information about the kind of metadata that is stored for
357+
the `key`.
358+
359+
$STYLE_INFO
360+
361+
The returned dictionary may be freshly allocated on each call to `metadata` and
362+
is considered to be owned by `x` so it must not be modified.
363+
"""
364+
function metadata(x::T; style::Bool=false) where {T}
365+
if !metadatasupport(T).read
366+
throw(ArgumentError("Objects of type $T do not support reading metadata"))
367+
end
368+
return Dict(key => metadata(x, key, style=style) for key in metadatakeys(x))
369+
end
370+
349371
"""
350372
metadatakeys(x)
351373
@@ -356,10 +378,10 @@ Throw an error if `x` does not support reading metadata.
356378
function metadatakeys end
357379

358380
"""
359-
metadata!(x, key::AbstractString, value; style)
381+
metadata!(x, key::AbstractString, value; style::Symbol=:default)
360382
361383
Set metadata for object `x` for key `key` to have value `value`
362-
and style `style` and return `x`.
384+
and style `style` (`:default` by default) and return `x`.
363385
Throw an error if `x` does not support setting metadata.
364386
365387
$STYLE_INFO
@@ -404,6 +426,41 @@ If `style=true` return `(default, :default)`.
404426
"""
405427
function colmetadata end
406428

429+
"""
430+
colmetadata(x, [col]; style::Bool=false)
431+
432+
If `col` is not passed return a dictionary mapping columns represented as
433+
`Symbol` that have associated metadata to dictionaries mapping all
434+
metadata keys to metadata values associated with table `x` for a given column.
435+
436+
If `col` is passed return a dictionary mapping all column metadata keys to metadata values
437+
associated with column `col` of table `x`. Throw an error if `x` does not
438+
support reading metadata for column `col` or column `col` is not present in `x`.
439+
440+
If `style=true` values are tuples of metadata value and metadata style. Metadata
441+
style is an additional information about the kind of metadata that is stored for
442+
the `key`.
443+
444+
$STYLE_INFO
445+
446+
The returned dictionary may be freshly allocated on each call to `colmetadata`
447+
and is considered to be owned by `x` so it must not be modified.
448+
"""
449+
function colmetadata(x::T, col; style::Bool=false) where {T}
450+
if !colmetadatasupport(T).read
451+
throw(ArgumentError("Objects of type $T do not support reading column metadata"))
452+
end
453+
return Dict(key => colmetadata(x, col, key, style=style) for key in colmetadatakeys(x, col))
454+
end
455+
456+
function colmetadata(x::T; style::Bool=false) where {T}
457+
if !colmetadatasupport(T).read
458+
throw(ArgumentError("Objects of type $T do not support reading column metadata"))
459+
end
460+
return Dict(col => Dict(key => colmetadata(x, col, key, style=style) for key in keys)
461+
for (col, keys) in colmetadatakeys(x))
462+
end
463+
407464
"""
408465
colmetadatakeys(x, [col])
409466
@@ -421,10 +478,10 @@ If `x` does not support column metadata return `()`.
421478
function colmetadatakeys end
422479

423480
"""
424-
colmetadata!(x, col, key::AbstractString, value; style)
481+
colmetadata!(x, col, key::AbstractString, value; style::Symbol=:default)
425482
426483
Set metadata for table `x` for column `col` for key `key` to have value `value`
427-
and style `style` and return `x`.
484+
and style `style` (`:default` by default) and return `x`.
428485
Throw an error if `x` does not support setting metadata for column `col`.
429486
430487
$COL_INFO

test/runtests.jl

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,7 @@ end
3535

3636
DataAPI.metadatakeys(x::TestMeta) = keys(x.table)
3737

38-
function DataAPI.metadata!(x::TestMeta, key::AbstractString, value; style)
39-
x.table[key] = (value, style)
40-
return x
41-
end
42-
43-
function DataAPI.metadata!(x::TestMeta, key::AbstractString, value; style)
38+
function DataAPI.metadata!(x::TestMeta, key::AbstractString, value; style::Symbol=:default)
4439
x.table[key] = (value, style)
4540
return x
4641
end
@@ -52,7 +47,8 @@ function DataAPI.colmetadata(x::TestMeta, col::Symbol, key::AbstractString; styl
5247
return style ? x.col[col][key] : x.col[col][key][1]
5348
end
5449

55-
function DataAPI.colmetadata(x::TestMeta, col::Symbol, key::AbstractString, default; style::Bool=false)
50+
function DataAPI.colmetadata(x::TestMeta, col::Symbol, key::AbstractString, default;
51+
style::Bool=false)
5652
haskey(x.table, col) && haskey(x.table[col], key) && return DataAPI.metadata(x, key, style=style)
5753
return style ? (default, :default) : default
5854
end
@@ -67,7 +63,8 @@ function DataAPI.colmetadatakeys(x::TestMeta)
6763
return (col => keys(x.col[col]) for col in keys(x.col))
6864
end
6965

70-
function DataAPI.colmetadata!(x::TestMeta, col::Symbol, key::AbstractString, value; style)
66+
function DataAPI.colmetadata!(x::TestMeta, col::Symbol, key::AbstractString, value;
67+
style::Symbol=:default)
7168
if haskey(x.col, col)
7269
x.col[col][key] = (value, style)
7370
else
@@ -264,7 +261,9 @@ end
264261
@test_throws MethodError DataAPI.deletemetadata!(1, "a")
265262
@test_throws MethodError DataAPI.emptymetadata!(1)
266263
@test_throws MethodError DataAPI.metadata(1, "a")
264+
@test_throws ArgumentError DataAPI.metadata(1)
267265
@test_throws MethodError DataAPI.metadata(1, "a", style=true)
266+
@test_throws ArgumentError DataAPI.metadata(1, style=true)
268267
@test_throws MethodError DataAPI.metadatakeys(1)
269268

270269
@test_throws MethodError DataAPI.colmetadata!(1, :col, "a", 10, style=:default)
@@ -274,7 +273,11 @@ end
274273
@test_throws MethodError DataAPI.emptycolmetadata!(1, 1)
275274
@test_throws MethodError DataAPI.emptycolmetadata!(1)
276275
@test_throws MethodError DataAPI.colmetadata(1, :col, "a")
276+
@test_throws ArgumentError DataAPI.colmetadata(1, :col)
277+
@test_throws ArgumentError DataAPI.colmetadata(1)
277278
@test_throws MethodError DataAPI.colmetadata(1, :col, "a", style=true)
279+
@test_throws ArgumentError DataAPI.colmetadata(1, :col, style=true)
280+
@test_throws ArgumentError DataAPI.colmetadata(1, style=true)
278281
@test_throws MethodError DataAPI.colmetadata!(1, 1, "a", 10, style=:default)
279282
@test_throws MethodError DataAPI.colmetadata(1, 1, "a")
280283
@test_throws MethodError DataAPI.colmetadata(1, 1, "a", style=true)
@@ -290,14 +293,18 @@ end
290293
@test DataAPI.colmetadatasupport(TestMeta) == (read=true, write=true)
291294

292295
@test isempty(DataAPI.metadatakeys(tm))
296+
@test DataAPI.metadata(tm) == Dict()
297+
@test DataAPI.metadata(tm, style=true) == Dict()
293298
@test DataAPI.metadata!(tm, "a", "100", style=:note) == tm
294299
@test collect(DataAPI.metadatakeys(tm)) == ["a"]
295300
@test_throws KeyError DataAPI.metadata(tm, "b")
296301
@test DataAPI.metadata(tm, "b", 123) == 123
297302
@test_throws KeyError DataAPI.metadata(tm, "b", style=true)
298303
@test DataAPI.metadata(tm, "b", 123, style=true) == (123, :default)
299304
@test DataAPI.metadata(tm, "a") == "100"
305+
@test DataAPI.metadata(tm) == Dict("a" => "100")
300306
@test DataAPI.metadata(tm, "a", style=true) == ("100", :note)
307+
@test DataAPI.metadata(tm, style=true) == Dict("a" => ("100", :note))
301308
DataAPI.deletemetadata!(tm, "a")
302309
@test isempty(DataAPI.metadatakeys(tm))
303310
@test DataAPI.metadata!(tm, "a", "100", style=:note) == tm
@@ -306,6 +313,7 @@ end
306313

307314
@test DataAPI.colmetadatakeys(tm) == ()
308315
@test DataAPI.colmetadatakeys(tm, :col) == ()
316+
@test DataAPI.colmetadata(tm) == Dict()
309317
@test DataAPI.colmetadata!(tm, :col, "a", "100", style=:note) == tm
310318
@test [k => collect(v) for (k, v) in DataAPI.colmetadatakeys(tm)] == [:col => ["a"]]
311319
@test collect(DataAPI.colmetadatakeys(tm, :col)) == ["a"]
@@ -316,7 +324,11 @@ end
316324
@test_throws KeyError DataAPI.colmetadata(tm, :col2, "a")
317325
@test_throws KeyError DataAPI.colmetadata(tm, :col2, "a", style=true)
318326
@test DataAPI.colmetadata(tm, :col, "a") == "100"
327+
@test DataAPI.colmetadata(tm, :col) == Dict("a" => "100")
328+
@test DataAPI.colmetadata(tm) == Dict(:col => Dict("a" => "100"))
319329
@test DataAPI.colmetadata(tm, :col, "a", style=true) == ("100", :note)
330+
@test DataAPI.colmetadata(tm, :col, style=true) == Dict("a" => ("100", :note))
331+
@test DataAPI.colmetadata(tm, style=true) == Dict(:col => Dict("a" => ("100", :note)))
320332
DataAPI.deletecolmetadata!(tm, :col, "a")
321333
@test isempty(DataAPI.colmetadatakeys(tm, :col))
322334
@test DataAPI.colmetadata!(tm, :col, "a", "100", style=:note) == tm

0 commit comments

Comments
 (0)