Merge branch 'master' into gsoc-crundel
This commit is contained in:
commit
aff0fdc821
3 changed files with 84 additions and 42 deletions
|
@ -37,6 +37,7 @@
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/filesystem/operations.hpp>
|
||||||
|
|
||||||
// sqlite
|
// sqlite
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -130,16 +131,17 @@ public:
|
||||||
int flags;
|
int flags;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool existed = boost::filesystem::exists(index_db);
|
||||||
boost::shared_ptr<sqlite_connection> ds = boost::make_shared<sqlite_connection>(index_db,flags);
|
boost::shared_ptr<sqlite_connection> ds = boost::make_shared<sqlite_connection>(index_db,flags);
|
||||||
|
|
||||||
|
ds->execute("PRAGMA synchronous=OFF");
|
||||||
|
ds->execute("BEGIN TRANSACTION");
|
||||||
|
|
||||||
// first drop the index if it already exists
|
// first drop the index if it already exists
|
||||||
std::ostringstream spatial_index_drop_sql;
|
std::ostringstream spatial_index_drop_sql;
|
||||||
spatial_index_drop_sql << "DROP TABLE IF EXISTS " << index_table;
|
spatial_index_drop_sql << "DROP TABLE IF EXISTS " << index_table;
|
||||||
ds->execute(spatial_index_drop_sql.str());
|
ds->execute(spatial_index_drop_sql.str());
|
||||||
|
|
||||||
ds->execute("PRAGMA synchronous=OFF");
|
|
||||||
ds->execute("BEGIN TRANSACTION");
|
|
||||||
|
|
||||||
// create the spatial index
|
// create the spatial index
|
||||||
std::ostringstream create_idx;
|
std::ostringstream create_idx;
|
||||||
create_idx << "create virtual table "
|
create_idx << "create virtual table "
|
||||||
|
@ -156,60 +158,91 @@ public:
|
||||||
|
|
||||||
prepared_index_statement ps(ds,insert_idx.str());
|
prepared_index_statement ps(ds,insert_idx.str());
|
||||||
|
|
||||||
bool first = true;
|
bool one_success = false;
|
||||||
while (rs->is_valid() && rs->step_next())
|
try
|
||||||
{
|
{
|
||||||
int size;
|
bool first = true;
|
||||||
const char* data = (const char*) rs->column_blob(0, size);
|
while (rs->is_valid() && rs->step_next())
|
||||||
if (data)
|
|
||||||
{
|
{
|
||||||
boost::ptr_vector<mapnik::geometry_type> paths;
|
int size;
|
||||||
// TODO - contraint fails if multiple_geometries = true
|
const char* data = (const char*) rs->column_blob(0, size);
|
||||||
bool multiple_geometries = false;
|
if (data)
|
||||||
mapnik::geometry_utils::from_wkb(paths, data, size, multiple_geometries, mapnik::wkbAuto);
|
|
||||||
for (unsigned i=0; i<paths.size(); ++i)
|
|
||||||
{
|
{
|
||||||
mapnik::box2d<double> const& bbox = paths[i].envelope();
|
boost::ptr_vector<mapnik::geometry_type> paths;
|
||||||
if (bbox.valid())
|
// 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<paths.size(); ++i)
|
||||||
{
|
{
|
||||||
if (first)
|
mapnik::box2d<double> const& bbox = paths[i].envelope();
|
||||||
|
if (bbox.valid())
|
||||||
{
|
{
|
||||||
first = false;
|
if (first)
|
||||||
extent = bbox;
|
{
|
||||||
|
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
|
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;
|
std::ostringstream error_msg;
|
||||||
error_msg << "Sqlite Plugin: invalid type for key field '"
|
error_msg << "SQLite Plugin: encountered invalid bbox at '"
|
||||||
<< rs->column_name(1) << "' when creating index '" << index_table
|
<< rs->column_name(1) << "' == " << rs->column_integer64(1);
|
||||||
<< "' type was: " << type_oid << "";
|
|
||||||
throw mapnik::datasource_exception(error_msg.str());
|
throw mapnik::datasource_exception(error_msg.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
const sqlite_int64 pkid = rs->column_integer64(1);
|
ps.step_next();
|
||||||
ps.bind(pkid);
|
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<sqlite_connection> ds,
|
static bool detect_extent(boost::shared_ptr<sqlite_connection> ds,
|
||||||
|
|
BIN
tests/data/sqlite/empty.db
Normal file
BIN
tests/data/sqlite/empty.db
Normal file
Binary file not shown.
|
@ -196,6 +196,15 @@ if 'sqlite' in mapnik2.DatasourceCache.instance().plugin_names():
|
||||||
eq_(feature['rowid'],1)
|
eq_(feature['rowid'],1)
|
||||||
eq_(feature['fips'],u'AC')
|
eq_(feature['fips'],u'AC')
|
||||||
|
|
||||||
|
|
||||||
|
def test_empty_db():
|
||||||
|
ds = mapnik2.SQLite(file='../data/sqlite/empty.db',
|
||||||
|
table='empty',
|
||||||
|
)
|
||||||
|
fs = ds.featureset()
|
||||||
|
feature = fs.next()
|
||||||
|
eq_(feature,None)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
setup()
|
setup()
|
||||||
[eval(run)() for run in dir() if 'test_' in run]
|
[eval(run)() for run in dir() if 'test_' in run]
|
||||||
|
|
Loading…
Reference in a new issue