From bc06b317460aae8a06f37a2aef70ecd9ce6a59b8 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 9 Nov 2011 17:19:05 -0800 Subject: [PATCH 1/2] test reading from an empty sqlite db --- tests/data/sqlite/empty.db | Bin 0 -> 2048 bytes tests/python_tests/sqlite_test.py | 9 +++++++++ 2 files changed, 9 insertions(+) create mode 100644 tests/data/sqlite/empty.db diff --git a/tests/data/sqlite/empty.db b/tests/data/sqlite/empty.db new file mode 100644 index 0000000000000000000000000000000000000000..98816e6c2be4af7b6e90a23aa100b3438dade7b7 GIT binary patch literal 2048 zcmeH`!AiqG5QaBJ=*gSV>)v9aLbWg8wr*=NH5!A^)3RwMCAi5hn{A|_SHtLkSFE_=#>OE9!4(XoI=u&nMU|c3gnw`G;G}EfhQg(S-?cbI`C8+{N!CSUi%T z%$G;dknVHSp^VR(gvZ&G#cAT=rRS5dYyw9R=g^!KbQ03M1E!s#dyt2A(VS=PDp922 z*es)DVYuyk9-+)()fF|V0j*gRRI) Date: Wed, 9 Nov 2011 17:44:50 -0800 Subject: [PATCH 2/2] sqlite: proper cleanup if rtree index creation fails --- plugins/input/sqlite/sqlite_utils.hpp | 117 +++++++++++++++++--------- 1 file changed, 75 insertions(+), 42 deletions(-) diff --git a/plugins/input/sqlite/sqlite_utils.hpp b/plugins/input/sqlite/sqlite_utils.hpp index 87c5a593c..fb1c31947 100644 --- a/plugins/input/sqlite/sqlite_utils.hpp +++ b/plugins/input/sqlite/sqlite_utils.hpp @@ -37,6 +37,7 @@ #include #include #include +#include // sqlite extern "C" { @@ -130,16 +131,17 @@ public: int flags; #endif + bool existed = boost::filesystem::exists(index_db); boost::shared_ptr ds = boost::make_shared(index_db,flags); - + + ds->execute("PRAGMA synchronous=OFF"); + ds->execute("BEGIN TRANSACTION"); + // first drop the index if it already exists std::ostringstream spatial_index_drop_sql; spatial_index_drop_sql << "DROP TABLE IF EXISTS " << index_table; ds->execute(spatial_index_drop_sql.str()); - ds->execute("PRAGMA synchronous=OFF"); - ds->execute("BEGIN TRANSACTION"); - // create the spatial index std::ostringstream create_idx; create_idx << "create virtual table " @@ -156,60 +158,91 @@ public: prepared_index_statement ps(ds,insert_idx.str()); - bool first = true; - while (rs->is_valid() && rs->step_next()) + bool one_success = false; + try { - int size; - const char* data = (const char*) rs->column_blob(0, size); - if (data) + bool first = true; + while (rs->is_valid() && rs->step_next()) { - boost::ptr_vector paths; - // TODO - contraint fails if multiple_geometries = true - bool multiple_geometries = false; - mapnik::geometry_utils::from_wkb(paths, data, size, multiple_geometries, mapnik::wkbAuto); - for (unsigned i=0; icolumn_blob(0, size); + if (data) { - mapnik::box2d const& bbox = paths[i].envelope(); - if (bbox.valid()) + boost::ptr_vector paths; + // TODO - contraint fails if multiple_geometries = true + bool multiple_geometries = false; + mapnik::geometry_utils::from_wkb(paths, data, size, multiple_geometries, mapnik::wkbAuto); + for (unsigned i=0; i const& bbox = paths[i].envelope(); + if (bbox.valid()) { - first = false; - extent = bbox; + if (first) + { + first = false; + extent = bbox; + } + else + { + extent.expand_to_include(bbox); + } + + ps.bind(bbox); + + const int type_oid = rs->column_type(1); + if (type_oid != SQLITE_INTEGER) + { + std::ostringstream error_msg; + error_msg << "Sqlite Plugin: invalid type for key field '" + << rs->column_name(1) << "' when creating index '" << index_table + << "' type was: " << type_oid << ""; + throw mapnik::datasource_exception(error_msg.str()); + } + + const sqlite_int64 pkid = rs->column_integer64(1); + ps.bind(pkid); } else - { - extent.expand_to_include(bbox); - } - - ps.bind(bbox); - - const int type_oid = rs->column_type(1); - if (type_oid != SQLITE_INTEGER) { std::ostringstream error_msg; - error_msg << "Sqlite Plugin: invalid type for key field '" - << rs->column_name(1) << "' when creating index '" << index_table - << "' type was: " << type_oid << ""; + error_msg << "SQLite Plugin: encountered invalid bbox at '" + << rs->column_name(1) << "' == " << rs->column_integer64(1); throw mapnik::datasource_exception(error_msg.str()); } - const sqlite_int64 pkid = rs->column_integer64(1); - ps.bind(pkid); + ps.step_next(); + one_success = true; } - else - { - std::ostringstream error_msg; - error_msg << "SQLite Plugin: encountered invalid bbox at '" - << rs->column_name(1) << "' == " << rs->column_integer64(1); - throw mapnik::datasource_exception(error_msg.str()); - } - - ps.step_next(); } } } - ds->execute("COMMIT"); + catch (mapnik::datasource_exception const& ex) + { + ds->execute("ROLLBACK"); + if (!existed) + { + try + { + boost::filesystem::remove(index_db); + } + catch (...) {}; + } + throw mapnik::datasource_exception(ex.what()); + } + + if (one_success) + { + ds->execute("COMMIT"); + } + else if (!existed) + { + ds->execute("ROLLBACK"); + try + { + boost::filesystem::remove(index_db); + } + catch (...) {}; + } } static bool detect_extent(boost::shared_ptr ds,