Skip to content

Commit

Permalink
Fix Tables schema for empty layers (#441)
Browse files Browse the repository at this point in the history
* Fix empty layer handling.

* Add tests. Fix macro escaping.
  • Loading branch information
evetion authored Nov 16, 2024
1 parent 4f7a7d6 commit 2e0a4a7
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
24 changes: 22 additions & 2 deletions src/tables.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
function Tables.schema(layer::AbstractFeatureLayer)::Nothing
return nothing
function Tables.schema(
layer::AbstractFeatureLayer,
)::Union{Nothing,Tables.Schema}
# If the layer has no features, calculate the schema from the layer
# otherwise let the features build the schema on the fly
# If we always build the schema, all isnullable (by default true) fields
# will result in columns with Union{Missing}.
nfeature(layer) == 0 || return nothing
ld = layerdefn(layer)
geom_names, field_names, _, fielddefns = schema_names(ld)
names = (geom_names..., field_names...)
types = Type[_datatype(getgeomdefn(ld, i - 1)) for i in 1:ngeom(ld)]
append!(types, map(_datatype, fielddefns))
return Tables.Schema(names, types)
end

function _datatype(fielddefn::IFieldDefnView)
return T = convert(DataType, getfieldtype(fielddefn))
end

function _datatype(fielddefn::IGeomFieldDefnView)
return IGeometry{gettype(fielddefn)}
end

Tables.istable(::Type{<:AbstractFeatureLayer})::Bool = true
Expand Down
6 changes: 3 additions & 3 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -207,23 +207,23 @@ macro ogrerr(code, message)
"Unknown error."
end

error($message * " ($detailmsg)")
error($(esc(message)) * " ($detailmsg)")
end
end
end

macro cplerr(code, message)
return quote
if $(esc(code)) != GDAL.CE_None
error($message)
error($(esc(message)))
end
end
end

macro cplwarn(code, message)
return quote
if $(esc(code)) != GDAL.CE_None
@warn $message
@warn $(esc(message))
end
end
end
Expand Down
39 changes: 39 additions & 0 deletions test/test_tables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,45 @@ using Tables
)
end
end
@testset "Handle empty layers" begin
AG.read(
joinpath(@__DIR__, "data/multi_geom.csv"),
options = [
"GEOM_POSSIBLE_NAMES=point,linestring",
"KEEP_GEOM_COLUMNS=NO",
],
) do ds
layer = AG.copy(AG.getlayer(ds, 0))

# With features, no schema is defined
@test isnothing(Tables.schema(layer))
# And tables are built up from features
table = Tables.columntable(layer)
@test Tables.columnnames(table) ==
(:point, :linestring, :id, :zoom, :location)
@test Tables.rowcount(table) == 2

for i in 1:AG.nfeature(layer)
AG.deletefeature!(layer, i)
end

# Without features, schema is still defined and table is empty
@test Tables.schema(layer) == Tables.Schema(
(:point, :linestring, :id, :zoom, :location),
(
AG.IGeometry{AG.wkbUnknown},
AG.IGeometry{AG.wkbUnknown},
String,
String,
String,
),
)
table = Tables.columntable(layer)
@test Tables.rowcount(table) == 0
@test Tables.columnnames(table) ==
(:point, :linestring, :id, :zoom, :location)
end
end

clean_test_dataset_files()
end
Expand Down
8 changes: 4 additions & 4 deletions test/test_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import GDAL
import ArchGDAL as AG

"Test both that an ErrorException is thrown and that the message is as expected"
function eval_ogrerr(err, expected_message)
@test (@test_throws ErrorException AG.@ogrerr err "e:").value.msg ==
"e: ($expected_message)"
function eval_ogrerr(err, expected_message, placeholder = "")
@test (@test_throws ErrorException AG.@ogrerr err "e $(placeholder):").value.msg ==
"e $(placeholder): ($expected_message)"
end

@testset "test_utils.jl" begin
Expand All @@ -18,7 +18,7 @@ end

@testset "OGR Errors" begin
@test isnothing(AG.@ogrerr GDAL.OGRERR_NONE "not an error")
eval_ogrerr(GDAL.OGRERR_NOT_ENOUGH_DATA, "Not enough data.")
eval_ogrerr(GDAL.OGRERR_NOT_ENOUGH_DATA, "Not enough data.", "foo")
eval_ogrerr(GDAL.OGRERR_NOT_ENOUGH_MEMORY, "Not enough memory.")
eval_ogrerr(
GDAL.OGRERR_UNSUPPORTED_GEOMETRY_TYPE,
Expand Down

0 comments on commit 2e0a4a7

Please sign in to comment.