Skip to content

Commit d6651ba

Browse files
authored
Merge pull request #67 from tk3369/tables1-update
Tables.jl 1.0 update
2 parents d3a3bea + e584a1c commit d6651ba

File tree

3 files changed

+83
-49
lines changed

3 files changed

+83
-49
lines changed

Project.toml

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
name = "SASLib"
22
uuid = "df8f2f22-cfef-5733-af3f-96770d497d85"
33
authors = ["Tom Kwong <tk3369@gmail.com>"]
4-
version = "1.2.0"
4+
version = "1.2.1"
55

66
[deps]
77
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
8+
IteratorInterfaceExtensions = "82899510-4779-5014-852e-03e436cf321d"
89
StringEncodings = "69024149-9ee7-55f6-a4c4-859efe599b68"
10+
TableTraits = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
911
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
1012
TabularDisplay = "3eeacb1d-13c2-54cc-9b18-30c86af3cadb"
11-
TableTraits = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
12-
IteratorInterfaceExtensions = "82899510-4779-5014-852e-03e436cf321d"
1313

1414
[compat]
15+
IteratorInterfaceExtensions = "0.1.1, 1"
1516
StringEncodings = "0.3"
17+
TableTraits = "0.4.1, 1"
18+
Tables = "1.0"
1619
TabularDisplay = "1"
17-
Tables = "0.2.3"
1820
julia = "1"
19-
IteratorInterfaceExtensions = "0.1.1, 1"
20-
TableTraits = "0.4.1, 1"
2121

2222
[extras]
2323
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

src/tables.jl

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
1+
# This file implements Tables interface and provide compatibility
2+
# to the Queryverse ecosystem.
3+
4+
# -----------------------------------------------------------------------------
5+
# Tables.jl implementation
6+
17
Tables.istable(::Type{<:ResultSet}) = true
28

3-
Tables.rowaccess(::Type{<:ResultSet}) = true
9+
# AbstractColumns interface
410
Tables.columnaccess(::Type{<:ResultSet}) = true
11+
Tables.columns(rs::ResultSet) = rs
12+
Tables.getcolumn(rs::ResultSet, i::Int) = rs[names(rs)[i]]
513

14+
# AbstractRow interface
15+
Tables.rowaccess(::Type{<:ResultSet}) = true
616
Tables.rows(rs::ResultSet) = rs
7-
Tables.columns(rs::ResultSet) = rs
817

18+
# Schema definition
919
Tables.schema(rs::ResultSet) = Tables.Schema(names(rs), eltype.(columns(rs)))
1020

21+
# -----------------------------------------------------------------------------
22+
# Queryverse compatibility
23+
1124
IteratorInterfaceExtensions.getiterator(rs::ResultSet) = Tables.datavaluerows(rs)
1225
TableTraits.isiterabletable(x::ResultSet) = true

test/runtests.jl

+62-41
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ using SharedArrays: SharedArray
77
using Tables
88
import IteratorInterfaceExtensions, TableTraits
99

10-
function getpath(dir, file)
10+
function getpath(dir, file)
1111
path = joinpath(dir, file)
1212
#println("================ $path ================")
1313
path
@@ -59,7 +59,7 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
5959
end
6060

6161
@testset "case insensitive dict" begin
62-
function testdict(lowercase_key, mixedcase_key, second_lowercase_key)
62+
function testdict(lowercase_key, mixedcase_key, second_lowercase_key)
6363

6464
T = typeof(lowercase_key)
6565
d = SASLib.CIDict{T,Int}()
@@ -108,7 +108,7 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
108108

109109
@testset "read basic test files (test*.sas7bdat)" begin
110110
dir = "data_pandas"
111-
files = filter(x -> endswith(x, "sas7bdat") && startswith(x, "test"),
111+
files = filter(x -> endswith(x, "sas7bdat") && startswith(x, "test"),
112112
Base.Filesystem.readdir("$dir"))
113113
for f in files
114114
result = readfile(dir, f)
@@ -150,7 +150,7 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
150150
rs = readsas(fname, include_columns=[:MONTH, :YEAR])
151151
@test size(rs, 2) == 2
152152
@test sort(names(rs)) == sort([:MONTH, :YEAR])
153-
153+
154154
rs = readsas(fname, include_columns=[1, 2, 7])
155155
@test size(rs, 2) == 3
156156
@test sort(names(rs)) == sort([:ACTUAL, :PREDICT, :PRODUCT])
@@ -171,12 +171,12 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
171171

172172
# test bad include/exclude param
173173
# see https://discourse.julialang.org/t/test-warn-doesnt-work-with-warn-in-0-7/9001
174-
@test_logs (:warn, "Unknown include column blah") (:warn,
174+
@test_logs (:warn, "Unknown include column blah") (:warn,
175175
"Unknown include column Year") readsas(fname, include_columns=[:blah, :Year])
176-
@test_logs (:warn, "Unknown exclude column blah") (:warn,
176+
@test_logs (:warn, "Unknown exclude column blah") (:warn,
177177
"Unknown exclude column Year") readsas(fname, exclude_columns=[:blah, :Year])
178178
# error handling
179-
@test_throws SASLib.ConfigError readsas(fname,
179+
@test_throws SASLib.ConfigError readsas(fname,
180180
include_columns=[1], exclude_columns=[1])
181181
end
182182

@@ -187,8 +187,8 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
187187
@test size(rs) == (1440, 10)
188188
@test size(rs,1) == 1440
189189
@test size(rs,2) == 10
190-
@test length(columns(rs)) == 10
191-
@test length(names(rs)) == 10
190+
@test length(columns(rs)) == 10
191+
@test length(names(rs)) == 10
192192

193193
# cell indexing
194194
@test rs[1][1] 925.0
@@ -204,40 +204,61 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
204204

205205
# iteration
206206
@test sum(r[1] for r in rs) 730337.0
207-
207+
208208
# portion of result set
209209
@test typeof(rs[1:2]) == SASLib.ResultSet
210210
@test typeof(rs[:ACTUAL, :PREDICT]) == SASLib.ResultSet
211211
@test rs[1:2][1][1] 925.0
212212
@test rs[:ACTUAL, :PREDICT][1][1] 925.0
213213

214214
# setindex!
215-
rs[1,1] = 100.0
216-
@test rs[1,1] 100.0
217-
rs[1,:ACTUAL] = 200.0
218-
@test rs[1,:ACTUAL] 200.0
215+
let rscopy = deepcopy(rs)
216+
rs[1,1] = 100.0
217+
@test rs[1,1] 100.0
218+
rs[1,:ACTUAL] = 200.0
219+
@test rs[1,:ACTUAL] 200.0
220+
end
219221

220222
# display related
221223
@test show(rs) == nothing
222224
@test SASLib.sizestr(rs) == "1440 rows x 10 columns"
223225

224-
# Tables.jl interface - getproperty test
225-
@test rs.ACTUAL == rs[:ACTUAL]
226-
@test names(rs) == propertynames(rs)
226+
# Tables.jl
227+
let twocols = rs[:ACTUAL, :PREDICT]
228+
229+
# General
230+
@test Tables.istable(typeof(rs))
231+
@test Tables.rowaccess(typeof(rs))
232+
@test Tables.columnaccess(typeof(rs))
233+
234+
# AbstractRow interface
235+
let row = twocols[3] # (ACTUAL = 608.0, PREDICT = 846.0)
236+
@test Tables.getcolumn(row, 1) 608.0
237+
@test Tables.getcolumn(row, :ACTUAL) 608.0
238+
@test Tables.columnnames(row) === (:ACTUAL, :PREDICT)
239+
end
227240

228-
# Tables.jl coverage - indirect tests / usage
229-
@test Tables.schema(rs).names == Tuple(names(rs))
230-
@test Tables.schema(rs).types == Tuple(eltype.([rs[s] for s in names(rs)]))
231-
@test length(Tables.rowtable(rs)) == 1440
232-
@test length(Tables.columntable(rs)) == 10
233-
@test size(Tables.matrix(rs[:ACTUAL, :PREDICT])) == (1440,2)
241+
# AbstractColumns interface
242+
let tab = Tables.columns(twocols)
243+
@test Tables.getcolumn(tab, 1) isa Array{Float64,1}
244+
@test Tables.getcolumn(tab, 1) |> size === (1440,)
245+
@test Tables.getcolumn(tab, :ACTUAL) isa Array{Float64,1}
246+
@test Tables.getcolumn(tab, :ACTUAL) |> size === (1440,)
247+
@test Tables.columnnames(tab) === propertynames(twocols)
248+
end
234249

235-
# Tables.jl coverage - direct tests
236-
@test Tables.istable(typeof(rs)) === true
237-
@test Tables.rowaccess(typeof(rs)) === true
238-
@test Tables.columnaccess(typeof(rs)) === true
239-
@test Tables.rows(rs) |> first |> propertynames |> Tuple == Tuple(names(rs))
240-
@test Tables.columns(rs) |> propertynames |> Tuple == Tuple(names(rs))
250+
# Usages
251+
@test size(Tables.matrix(twocols)) == (1440, 2)
252+
end
253+
254+
# old tests
255+
#@test Tables.schema(rs).names == Tuple(names(rs))
256+
#@test Tables.schema(rs).types == Tuple(eltype.([rs[s] for s in names(rs)]))
257+
#@test length(Tables.rowtable(rs)) == 1440
258+
#@test length(Tables.columntable(rs)) == 10
259+
#@test size(Tables.matrix(rs[:ACTUAL, :PREDICT])) == (1440,2)
260+
#@test Tables.rows(rs) |> first |> propertynames |> Tuple == Tuple(names(rs))
261+
#@test Tables.columns(rs) |> propertynames |> Tuple == Tuple(names(rs))
241262

242263
# Queryverse integration
243264
@test TableTraits.isiterabletable(rs) == true
@@ -333,18 +354,18 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
333354
end
334355

335356
@testset "array constructors" begin
336-
357+
337358
rs = readfile("data_AHS2013", "homimp.sas7bdat")
338359
@test typeof(rs[:RAS]) == SASLib.ObjectPool{String,UInt16}
339360

340361
# string_array_fn test for specific string columns
341-
rs = readfile("data_AHS2013", "homimp.sas7bdat",
362+
rs = readfile("data_AHS2013", "homimp.sas7bdat",
342363
string_array_fn = Dict(:RAS => REGULAR_STR_ARRAY))
343364
@test typeof(rs[:RAS]) == Array{String,1}
344365
@test typeof(rs[:RAH]) != Array{String,1}
345366

346367
# string_array_fn test for all string columns
347-
rs = readfile("data_AHS2013", "homimp.sas7bdat",
368+
rs = readfile("data_AHS2013", "homimp.sas7bdat",
348369
string_array_fn = Dict(:_all_ => REGULAR_STR_ARRAY))
349370
@test typeof(rs[:RAS]) == Array{String,1}
350371
@test typeof(rs[:RAH]) == Array{String,1}
@@ -354,13 +375,13 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
354375

355376
# number_array_fn test by column name
356377
makesharedarray(n) = SharedArray{Float64}(n)
357-
rs = readfile("data_misc", "numeric_1000000_2.sas7bdat",
378+
rs = readfile("data_misc", "numeric_1000000_2.sas7bdat",
358379
number_array_fn = Dict(:f => makesharedarray))
359380
@test typeof(rs[:f]) == SharedArray{Float64,1}
360381
@test typeof(rs[:x]) == Array{Float64,1}
361382

362383
# number_array_fn test for all numeric columns
363-
rs = readfile("data_misc", "numeric_1000000_2.sas7bdat",
384+
rs = readfile("data_misc", "numeric_1000000_2.sas7bdat",
364385
number_array_fn = Dict(:_all_ => makesharedarray))
365386
@test typeof(rs[:f]) == SharedArray{Float64,1}
366387
@test typeof(rs[:x]) == SharedArray{Float64,1}
@@ -371,31 +392,31 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
371392
@testset "user specified column types" begin
372393

373394
# normal use case
374-
rs = readfile("data_pandas", "productsales.sas7bdat";
395+
rs = readfile("data_pandas", "productsales.sas7bdat";
375396
verbose_level = 0, column_types = Dict(:YEAR => Int16, :QUARTER => Int8))
376397
@test eltype(rs[:YEAR]) == Int16
377398
@test eltype(rs[:QUARTER]) == Int8
378399

379400
# error handling - warn() when a column cannot be converted
380-
rs = readfile("data_pandas", "productsales.sas7bdat";
401+
rs = readfile("data_pandas", "productsales.sas7bdat";
381402
verbose_level = 0, column_types = Dict(:YEAR => Int8, :QUARTER => Int8))
382403
@test eltype(rs[:YEAR]) == Float64
383404
@test eltype(rs[:QUARTER]) == Int8
384405
#TODO expect warning for :YEAR conversion
385406

386407
# case insensitive column symbol
387-
rs = readfile("data_pandas", "productsales.sas7bdat";
408+
rs = readfile("data_pandas", "productsales.sas7bdat";
388409
verbose_level = 0, column_types = Dict(:Quarter => Int8))
389410
@test eltype(rs[:QUARTER]) == Int8
390411

391412
# conversion to custom types
392-
rs = readfile("data_pandas", "productsales.sas7bdat";
413+
rs = readfile("data_pandas", "productsales.sas7bdat";
393414
verbose_level = 0, column_types = Dict(:Year => YearStr))
394415
@test eltype(rs[:YEAR]) == YearStr
395416

396417
# test Union type
397-
let T = Union{Int,Missing}
398-
rs = readfile("data_pandas", "productsales.sas7bdat";
418+
let T = Union{Int,Missing}
419+
rs = readfile("data_pandas", "productsales.sas7bdat";
399420
verbose_level = 0, column_types = Dict(:Year => T))
400421
@test eltype(rs[:YEAR]) == T
401422
end
@@ -410,7 +431,7 @@ Base.convert(::Type{YearStr}, v::Float64) = YearStr(string(round(Int, v)))
410431
@testset "just reads" begin
411432
for dir in ["data_pandas", "data_reikoch", "data_AHS2013", "data_misc"]
412433
for f in readdir(dir)
413-
if endswith(f, ".sas7bdat") &&
434+
if endswith(f, ".sas7bdat") &&
414435
!(f in ["zero_variables.sas7bdat"])
415436
rs = readfile(dir, f)
416437
@test size(rs, 1) > 0

0 commit comments

Comments
 (0)