Skip to content
Permalink
Browse files
adopt 'new' spatialite initialization scheme via thin wrapper around …
…sqlite3_open and sqlite3_close (fixes #12771)

(cherry picked from commit 252aaab, 23ef9da, d4b72a2, c7cb963 and e255d6c)
  • Loading branch information
jef-n committed May 27, 2015
1 parent 571a594 commit d7ca190295079957a8d0ef446cd834351020e901
@@ -199,6 +199,16 @@ ENDIF (WITH_POSTGRESQL)

FIND_PACKAGE(SPATIALITE REQUIRED)

IF(SPATIALITE_VERSION_GE_4_0_0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPATIALITE_VERSION_GE_4_0_0")
ENDIF(SPATIALITE_VERSION_GE_4_0_0)
IF(SPATIALITE_VERSION_G_4_1_1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPATIALITE_VERSION_G_4_1_1")
ENDIF(SPATIALITE_VERSION_G_4_1_1)
IF(SPATIALITE_HAS_INIT_EX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPATIALITE_HAS_INIT_EX")
ENDIF(SPATIALITE_HAS_INIT_EX)

IF (NOT PROJ_FOUND OR NOT GEOS_FOUND OR NOT GDAL_FOUND)
MESSAGE (SEND_ERROR "Some dependencies were not found!")
ENDIF (NOT PROJ_FOUND OR NOT GEOS_FOUND OR NOT GDAL_FOUND)
@@ -70,6 +70,7 @@ IF (SPATIALITE_FOUND)
ENDIF(APPLE)
check_library_exists("${SPATIALITE_LIBRARY}" gaiaDropTable "" SPATIALITE_VERSION_GE_4_0_0)
check_library_exists("${SPATIALITE_LIBRARY}" gaiaStatisticsInvalidate "" SPATIALITE_VERSION_G_4_1_1)
check_library_exists("${SPATIALITE_LIBRARY}" spatialite_init_ex "" SPATIALITE_HAS_INIT_EX)

ELSE (SPATIALITE_FOUND)

@@ -29,6 +29,7 @@
#include "prepare_protocol.h"
#include "util.h"
#include "sqlitecompat.h"
#include "spatialite.h"

#include "pythread.h"

@@ -81,7 +82,6 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
}

self->initialized = 1;
spatialite_init(0);
self->begin_statement = NULL;

self->statement_cache = NULL;
@@ -106,7 +106,15 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
}

Py_BEGIN_ALLOW_THREADS
#if defined(SPATIALITE_HAS_INIT_EX)
self->slconn = spatialite_alloc_connection();
#else
spatialite_init( 0 );
#endif
rc = sqlite3_open(PyString_AsString(database_utf8), &self->db);
#if defined(SPATIALITE_HAS_INIT_EX)
spatialite_init_ex( self->db, self->slconn, 0 );
#endif
Py_END_ALLOW_THREADS

Py_DECREF(database_utf8);
@@ -272,6 +280,9 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self)
if (self->db) {
Py_BEGIN_ALLOW_THREADS
sqlite3_close(self->db);
#if defined(SPATIALITE_HAS_INIT_EX)
spatialite_cleanup_ex( self->slconn );
#endif
Py_END_ALLOW_THREADS
} else if (self->apsw_connection) {
ret = PyObject_CallMethod(self->apsw_connection, "close", "");
@@ -372,6 +383,9 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args)
} else {
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_close(self->db);
#if defined(SPATIALITE_HAS_INIT_EX)
spatialite_cleanup_ex( self->slconn );
#endif
Py_END_ALLOW_THREADS

if (rc != SQLITE_OK) {
@@ -33,12 +33,11 @@
#include "sqlite3.h"
#include "spatialite.h"

// int spatialite_init(int verbose);

typedef struct
{
PyObject_HEAD
sqlite3* db;
void *slconn;

/* 1 if we are currently within a transaction, i. e. if a BEGIN has been
* issued */
@@ -14,14 +14,11 @@
***************************************************************************/

#include "qgsosmdatabase.h"

#include <spatialite.h>

#include "qgsslconnect.h"
#include "qgsgeometry.h"
#include "qgslogger.h"



QgsOSMDatabase::QgsOSMDatabase( const QString& dbFileName )
: mDbFileName( dbFileName )
, mDatabase( 0 )
@@ -32,7 +29,6 @@ QgsOSMDatabase::QgsOSMDatabase( const QString& dbFileName )
, mStmtWayNodePoints( 0 )
, mStmtWayTags( 0 )
{

}

QgsOSMDatabase::~QgsOSMDatabase()
@@ -49,11 +45,8 @@ bool QgsOSMDatabase::isOpen() const

bool QgsOSMDatabase::open()
{
// load spatialite extension
spatialite_init( 0 );

// open database
int res = sqlite3_open_v2( mDbFileName.toUtf8().data(), &mDatabase, SQLITE_OPEN_READWRITE, 0 );
int res = QgsSLConnect::sqlite3_open_v2( mDbFileName.toUtf8().data(), &mDatabase, SQLITE_OPEN_READWRITE, 0 );
if ( res != SQLITE_OK )
{
mError = QString( "Failed to open database [%1]: %2" ).arg( res ).arg( mDbFileName );
@@ -93,7 +86,7 @@ bool QgsOSMDatabase::close()
Q_ASSERT( mStmtNode == 0 );

// close database
if ( sqlite3_close( mDatabase ) != SQLITE_OK )
if ( QgsSLConnect::sqlite3_close( mDatabase ) != SQLITE_OK )
{
//mError = ( char * ) "Closing SQLite3 database failed.";
//return false;
@@ -14,8 +14,7 @@
***************************************************************************/

#include "qgsosmimport.h"

#include <spatialite.h>
#include "qgsslconnect.h"

#include <QStringList>
#include <QXmlStreamReader>
@@ -57,9 +56,6 @@ bool QgsOSMXmlImport::import()
}
}

// load spatialite extension
spatialite_init( 0 );

if ( !createDatabase() )
{
// mError is set in createDatabase()
@@ -137,7 +133,7 @@ bool QgsOSMXmlImport::createDatabase()
{
char **results;
int rows, columns;
if ( sqlite3_open_v2( mDbFileName.toUtf8().data(), &mDatabase, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0 ) != SQLITE_OK )
if ( QgsSLConnect::sqlite3_open_v2( mDbFileName.toUtf8().data(), &mDatabase, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0 ) != SQLITE_OK )
return false;

bool above41 = false;
@@ -238,7 +234,7 @@ bool QgsOSMXmlImport::closeDatabase()

Q_ASSERT( mStmtInsertNode == 0 );

sqlite3_close( mDatabase );
QgsSLConnect::sqlite3_close( mDatabase );
mDatabase = 0;
return true;
}
@@ -24,10 +24,11 @@
#include "qgsapplication.h"
#include "qgsproviderregistry.h"
#include "qgisapp.h" // <- for theme icons
#include <qgsvectorlayer.h>
#include <qgsmaplayerregistry.h>
#include "qgsvectorlayer.h"
#include "qgsmaplayerregistry.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsgenericprojectionselector.h"
#include "qgsslconnect.h"

#include "qgslogger.h"

@@ -196,14 +197,11 @@ void QgsNewSpatialiteLayerDialog::on_pbnFindSRID_clicked()
// to build filter for projection selector
sqlite3 *db = 0;
bool status = true;
if ( !db )
int rc = sqlite3_open_v2( mDatabaseComboBox->currentText().toUtf8(), &db, SQLITE_OPEN_READONLY, NULL );
if ( rc != SQLITE_OK )
{
int rc = sqlite3_open_v2( mDatabaseComboBox->currentText().toUtf8(), &db, SQLITE_OPEN_READONLY, NULL );
if ( rc != SQLITE_OK )
{
QMessageBox::warning( this, tr( "SpatiaLite Database" ), tr( "Unable to open the database" ) );
return;
}
QMessageBox::warning( this, tr( "SpatiaLite Database" ), tr( "Unable to open the database" ) );
return;
}

// load up the srid table
@@ -213,7 +211,7 @@ void QgsNewSpatialiteLayerDialog::on_pbnFindSRID_clicked()

QSet<QString> myCRSs;

int rc = sqlite3_prepare( db, sql.toUtf8(), sql.toUtf8().length(), &ppStmt, &pzTail );
rc = sqlite3_prepare( db, sql.toUtf8(), sql.toUtf8().length(), &ppStmt, &pzTail );
// XXX Need to free memory from the error msg if one is set
if ( rc == SQLITE_OK )
{
@@ -381,10 +379,8 @@ bool QgsNewSpatialiteLayerDialog::apply()
.arg( quotedValue( leGeometryColumn->text() ) );
QgsDebugMsg( sqlCreateIndex ); // OK

spatialite_init( 0 );

sqlite3 *db;
int rc = sqlite3_open( mDatabaseComboBox->currentText().toUtf8(), &db );
int rc = QgsSLConnect::sqlite3_open( mDatabaseComboBox->currentText().toUtf8(), &db );
if ( rc != SQLITE_OK )
{
QMessageBox::warning( this,
@@ -447,6 +443,8 @@ bool QgsNewSpatialiteLayerDialog::apply()
}
}
}

QgsSLConnect::sqlite3_close( db );
}

return false;
@@ -173,6 +173,7 @@ SET(QGIS_CORE_SRCS
qgsvectorlayerundocommand.cpp
qgsvectorsimplifymethod.cpp
qgsxmlutils.cpp
qgsslconnect.cpp

composer/qgsaddremoveitemcommand.cpp
composer/qgsaddremovemultiframecommand.cpp
@@ -29,6 +29,7 @@
#include "qgsvectordataprovider.h"
#include "qgsvectorlayereditbuffer.h"
#include "qgsvectorlayerjoinbuffer.h"
#include "qgsslconnect.h"

#include <QDir>
#include <QDomDocument>
@@ -74,9 +75,8 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,
QString dbPath = QDir( offlineDataPath ).absoluteFilePath( offlineDbFile );
if ( createSpatialiteDB( dbPath ) )
{
spatialite_init( 0 );
sqlite3* db;
int rc = sqlite3_open( dbPath.toUtf8().constData(), &db );
int rc = QgsSLConnect::sqlite3_open( dbPath.toUtf8().constData(), &db );
if ( rc != SQLITE_OK )
{
showWarning( tr( "Could not open the spatialite database" ) );
@@ -156,7 +156,7 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString& offlineDataPath,

emit progressStopped();

sqlite3_close( db );
QgsSLConnect::sqlite3_close( db );

// save offline project
QString projectTitle = QgsProject::instance()->title();
@@ -380,8 +380,7 @@ bool QgsOfflineEditing::createSpatialiteDB( const QString& offlineDbPath )

// creating/opening the new database
QString dbPath = newDb.fileName();
spatialite_init( 0 );
ret = sqlite3_open_v2( dbPath.toUtf8().constData(), &sqlite_handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL );
ret = QgsSLConnect::sqlite3_open_v2( dbPath.toUtf8().constData(), &sqlite_handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL );
if ( ret )
{
// an error occurred
@@ -397,13 +396,13 @@ bool QgsOfflineEditing::createSpatialiteDB( const QString& offlineDbPath )
{
showWarning( tr( "Unable to activate FOREIGN_KEY constraints" ) );
sqlite3_free( errMsg );
sqlite3_close( sqlite_handle );
QgsSLConnect::sqlite3_close( sqlite_handle );
return false;
}
initializeSpatialMetadata( sqlite_handle );

// all done: closing the DB connection
sqlite3_close( sqlite_handle );
QgsSLConnect::sqlite3_close( sqlite_handle );

return true;
}
@@ -0,0 +1,89 @@
/***************************************************************************
qgsslconnect.cpp - thin wrapper class to connect to spatialite databases
----------------------
begin : May 2015
copyright : (C) 2015 by Jürgen fischer
email : jef at norbit dot de
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsslconnect.h"

#include <sqlite3.h>
#include <spatialite.h>

#if defined(SPATIALITE_HAS_INIT_EX)
QHash<sqlite3 *, void *> QgsSLConnect::mSLconns;
#endif

int QgsSLConnect::sqlite3_open( const char *filename, sqlite3 **ppDb )
{
#if defined(SPATIALITE_HAS_INIT_EX)
void *conn = spatialite_alloc_connection();
#else
spatialite_init( 0 );
#endif

int res = ::sqlite3_open( filename, ppDb );

#if defined(SPATIALITE_HAS_INIT_EX)
if ( res == SQLITE_OK )
{
spatialite_init_ex( *ppDb, conn, 0 );
mSLconns.insert( *ppDb, conn );
}
#endif

return res;
}

int QgsSLConnect::sqlite3_close( sqlite3 *db )
{
int res = ::sqlite3_close( db );

#if defined(SPATIALITE_HAS_INIT_EX)
if ( mSLconns.contains( db ) )
spatialite_cleanup_ex( mSLconns.take( db ) );
#endif

return res;
}

int QgsSLConnect::sqlite3_open_v2( const char *filename, sqlite3 **ppDb, int flags, const char *zVfs )
{
#if defined(SPATIALITE_HAS_INIT_EX)
void *conn = spatialite_alloc_connection();
#else
spatialite_init( 0 );
#endif

int res = ::sqlite3_open_v2( filename, ppDb, flags, zVfs );

#if defined(SPATIALITE_HAS_INIT_EX)
if ( res == SQLITE_OK )
{
spatialite_init_ex( *ppDb, conn, 0 );
mSLconns.insert( *ppDb, conn );
}
#endif

return res;
}

int QgsSLConnect::sqlite3_close_v2( sqlite3 *db )
{
int res = ::sqlite3_close( db );

#if defined(SPATIALITE_HAS_INIT_EX)
if ( mSLconns.contains( db ) )
spatialite_cleanup_ex( mSLconns.take( db ) );
#endif

return res;
}

0 comments on commit d7ca190

Please sign in to comment.