diff --git a/REQUIRE b/REQUIRE index cf0a3c9c..7e02d284 100644 --- a/REQUIRE +++ b/REQUIRE @@ -2,3 +2,5 @@ julia 0.6 Compat 0.19 NamedTuples 2.1.0 PooledArrays +TableTraits 0.0.1 +TableTraitsUtils 0.0.1 diff --git a/src/IndexedTables.jl b/src/IndexedTables.jl index e6b65bc9..450a6273 100644 --- a/src/IndexedTables.jl +++ b/src/IndexedTables.jl @@ -435,4 +435,7 @@ include("join.jl") # query and aggregate include("query.jl") +# TableTraits.jl integration +include("tabletraits.jl") + end # module diff --git a/src/tabletraits.jl b/src/tabletraits.jl new file mode 100644 index 00000000..e2dccfc4 --- /dev/null +++ b/src/tabletraits.jl @@ -0,0 +1,48 @@ +using TableTraits +using TableTraitsUtils + +TableTraits.isiterable(x::IndexedTable) = true +TableTraits.isiterabletable(x::IndexedTable) = true + +function TableTraits.getiterator{S<:IndexedTable}(source::S) + return rows(source) +end + +function IndexedTable(x; idxcols::Union{Void,Vector{Symbol}}=nothing, datacols::Union{Void,Vector{Symbol}}=nothing) + if isiterabletable(x) + iter = getiterator(x) + + source_colnames = TableTraits.column_names(iter) + + if idxcols==nothing && datacols==nothing + idxcols = source_colnames[1:end-1] + datacols = [source_colnames[end]] + elseif idxcols==nothing + idxcols = setdiff(source_colnames,datacols) + elseif datacols==nothing + datacols = setdiff(source_colnames, idxcols) + end + + if length(setdiff(idxcols, source_colnames))>0 + error("Unknown idxcol") + end + + if length(setdiff(datacols, source_colnames))>0 + error("Unknown datacol") + end + + source_data, source_names = TableTraitsUtils.create_columns_from_iterabletable(x) + + idxcols_indices = [findfirst(source_colnames,i) for i in idxcols] + datacols_indices = [findfirst(source_colnames,i) for i in datacols] + + idx_storage = Columns(source_data[idxcols_indices]..., names=source_colnames[idxcols_indices]) + data_storage = Columns(source_data[datacols_indices]..., names=source_colnames[datacols_indices]) + + return IndexedTable(idx_storage, data_storage) + elseif idxcols==nothing && datacols==nothing + return convert(IndexedTable, x) + else + throw(ArgumentError("x cannot be turned into an IndexedTable.")) + end +end diff --git a/test/runtests.jl b/test/runtests.jl index 81dbdb0b..19c1d486 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,3 +1,4 @@ include("test_core.jl") include("test_query.jl") include("test_utils.jl") +include("test_tabletraits.jl") diff --git a/test/test_tabletraits.jl b/test/test_tabletraits.jl new file mode 100644 index 00000000..a6d18844 --- /dev/null +++ b/test/test_tabletraits.jl @@ -0,0 +1,39 @@ +using IndexedTables +using TableTraits +using NamedTuples +using Base.Test + +@testset "TableTraits" begin + +source_it = IndexedTable(Columns(a=[1,2,3]), Columns(b=[1.,2.,3.], c=["A","B","C"])) + +@test isiterable(source_it) == true + +target_array = collect(getiterator(source_it)) + +@test length(target_array) == 3 +@test target_array[1] == @NT(a=1, b=1., c="A") +@test target_array[2] == @NT(a=2, b=2., c="B") +@test target_array[3] == @NT(a=3, b=3., c="C") + +source_array = [@NT(a=1,b=1.,c="A"), @NT(a=2,b=2.,c="B"), @NT(a=3,b=3.,c="C")] + +it1 = IndexedTable(source_array) +@test length(it1) == 3 +@test it1[1,1.].c == "A" +@test it1[2,2.].c == "B" +@test it1[3,3.].c == "C" + +it2 = IndexedTable(source_array, idxcols=[:a]) +@test length(it2) == 3 +@test it2[1] == @NT(b=1., c="A") +@test it2[2] == @NT(b=2., c="B") +@test it2[3] == @NT(b=3., c="C") + +it3 = IndexedTable(source_array, datacols=[:b, :c]) +@test length(it3) == 3 +@test it3[1] == @NT(b=1., c="A") +@test it3[2] == @NT(b=2., c="B") +@test it3[3] == @NT(b=3., c="C") + +end