From ddeca1e81e7d3829b12f0fc73ab8a291faafb4c9 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 5 Dec 2011 12:03:38 -0800 Subject: [PATCH] csv plugin: ensure that the datasource throws if invalid attributes are queried to keep consistent with other datasource - refs #792 --- plugins/input/csv/csv_datasource.cpp | 27 +++++++++++++++++++++++++-- tests/python_tests/csv_test.py | 13 +++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index 6492bdb57..6280d16f4 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -851,8 +851,31 @@ mapnik::featureset_ptr csv_datasource::features(mapnik::query const& q) const { if (!is_bound_) bind(); - // TODO - should we check q.property_names() and throw if not found in headers_? - // const std::set& attribute_names = q.property_names(); + const std::set& attribute_names = q.property_names(); + std::set::const_iterator pos = attribute_names.begin(); + while (pos != attribute_names.end()) + { + bool found_name = false; + for (int i = 0; i < headers_.size(); ++i) + { + if (headers_[i] == *pos) + { + found_name = true; + break; + } + } + + if (! found_name) + { + std::ostringstream s; + + s << "CSV Plugin: no attribute '" << *pos << "'. Valid attributes are: " + << boost::algorithm::join(headers_, ",") << "."; + + throw mapnik::datasource_exception(s.str()); + } + ++pos; + } return boost::make_shared(q.get_bbox(),features_); } diff --git a/tests/python_tests/csv_test.py b/tests/python_tests/csv_test.py index 61a31b5f4..f84442ebb 100644 --- a/tests/python_tests/csv_test.py +++ b/tests/python_tests/csv_test.py @@ -214,6 +214,19 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names(): eq_(feat['null'],'') eq_(feat['boolean'],'false') + @raises(RuntimeError) + def test_that_nonexistant_query_field_throws(**kwargs): + ds = get_csv_ds('lon_lat.csv') + eq_(len(ds.fields()),2) + eq_(ds.fields(),['lon','lat']) + eq_(ds.field_types(),['int','int']) + query = mapnik.Query(ds.envelope()) + for fld in ds.fields(): + query.add_property_name(fld) + # also add an invalid one, triggering throw + query.add_property_name('bogus') + fs = ds.features(query) + if __name__ == "__main__": setup() [eval(run)(visual=True) for run in dir() if 'test_' in run]