Skip to content
Permalink
Browse files

Switch more places to using spatialite_database_unique_ptr

  • Loading branch information
m-kuhn committed Nov 15, 2017
1 parent 4df65ac commit 28f13778ee612237af499a7a21b3347506bb7a20
@@ -24,7 +24,11 @@
#include "qgssqliteutils.h"

/**
* \ingroup core
*
* Closes a spatialite database.
*
* \since QGIS 3.0
*/
struct CORE_EXPORT QgsSpatialiteCloser
{
@@ -36,8 +40,12 @@ struct CORE_EXPORT QgsSpatialiteCloser
};

/**
* \ingroup core
*
* Unique pointer for spatialite databases, which automatically closes
* the database when the pointer goes out of scope or is reset.
*
* \since QGIS 3.0
*/
class CORE_EXPORT spatialite_database_unique_ptr : public std::unique_ptr< sqlite3, QgsSpatialiteCloser>
{
@@ -28,7 +28,11 @@ struct sqlite3;
struct sqlite3_stmt;

/**
* \ingroup core
*
* Closes a sqlite3 database.
*
* \since QGIS 3.0
*/
struct CORE_EXPORT QgsSqlite3Closer
{
@@ -52,8 +56,12 @@ struct CORE_EXPORT QgsSqlite3StatementFinalizer
};

/**
* \ingroup core
*
* Unique pointer for sqlite3 prepared statements, which automatically finalizes
* the statement when the pointer goes out of scope or is reset.
*
* \since QGIS 3.0
*/
class CORE_EXPORT sqlite3_statement_unique_ptr : public std::unique_ptr< sqlite3_stmt, QgsSqlite3StatementFinalizer>
{
@@ -73,8 +81,12 @@ class CORE_EXPORT sqlite3_statement_unique_ptr : public std::unique_ptr< sqlite3


/**
* \ingroup core
*
* Unique pointer for sqlite3 databases, which automatically closes
* the database when the pointer goes out of scope or is reset.
*
* \since QGIS 3.0
*/
class CORE_EXPORT sqlite3_database_unique_ptr : public std::unique_ptr< sqlite3, QgsSqlite3Closer>
{
@@ -13,7 +13,6 @@
* *
***************************************************************************/
#include "qgsspatialiteconnection.h"
#include "qgsslconnect.h"
#include "qgssettings.h"
#include "qgslogger.h"
#include "qgsspatialiteutils.h"
@@ -71,7 +70,7 @@ QgsSpatiaLiteConnection::Error QgsSpatiaLiteConnection::fetchTables( bool loadGe
if ( ret )
return FailedToOpen;

ret = checkHasMetadataTables( handle );
ret = checkHasMetadataTables( database.get() );
if ( !mErrorMsg.isNull() || ret == LayoutUnknown )
{
// unexpected error; invalid SpatiaLite DB
@@ -700,8 +699,6 @@ bool QgsSqliteHandle::checkMetadata( sqlite3 *handle )

QgsSqliteHandle *QgsSqliteHandle::openDb( const QString &dbPath, bool shared )
{
sqlite3 *sqlite_handle = nullptr;

//QMap < QString, QgsSqliteHandle* >&handles = QgsSqliteHandle::handles;

if ( shared && sHandles.contains( dbPath ) )
@@ -712,29 +709,29 @@ QgsSqliteHandle *QgsSqliteHandle::openDb( const QString &dbPath, bool shared )
}

QgsDebugMsg( QString( "New sqlite connection for " ) + dbPath );
if ( QgsSLConnect::sqlite3_open_v2( dbPath.toUtf8().constData(), &sqlite_handle, shared ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY | SQLITE_OPEN_NOMUTEX, nullptr ) )
spatialite_database_unique_ptr database;
if ( database.open_v2( dbPath, shared ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY | SQLITE_OPEN_NOMUTEX, nullptr ) )
{
// failure
QgsDebugMsg( QString( "Failure while connecting to: %1\n%2" )
.arg( dbPath,
QString::fromUtf8( sqlite3_errmsg( sqlite_handle ) ) ) );
QString::fromUtf8( sqlite3_errmsg( database.get() ) ) ) );
return nullptr;
}

// checking the DB for sanity
if ( !checkMetadata( sqlite_handle ) )
if ( !checkMetadata( database.get() ) )
{
// failure
QgsDebugMsg( QString( "Failure while connecting to: %1\n\ninvalid metadata tables" ).arg( dbPath ) );
QgsSLConnect::sqlite3_close( sqlite_handle );
return nullptr;
}
// activating Foreign Key constraints
( void )sqlite3_exec( sqlite_handle, "PRAGMA foreign_keys = 1", nullptr, nullptr, nullptr );
( void )sqlite3_exec( database.get(), "PRAGMA foreign_keys = 1", nullptr, nullptr, nullptr );

QgsDebugMsg( "Connection to the database was successful" );

QgsSqliteHandle *handle = new QgsSqliteHandle( sqlite_handle, dbPath, shared );
QgsSqliteHandle *handle = new QgsSqliteHandle( database.release(), dbPath, shared );
if ( shared )
sHandles.insert( dbPath, handle );

@@ -746,7 +743,6 @@ void QgsSqliteHandle::closeDb( QgsSqliteHandle *&handle )
if ( handle->ref == -1 )
{
// not shared
handle->sqliteClose();
delete handle;
}
else
@@ -760,7 +756,6 @@ void QgsSqliteHandle::closeDb( QgsSqliteHandle *&handle )

if ( --i.value()->ref == 0 )
{
i.value()->sqliteClose();
delete i.value();
sHandles.remove( i.key() );
}
@@ -771,22 +766,6 @@ void QgsSqliteHandle::closeDb( QgsSqliteHandle *&handle )

void QgsSqliteHandle::closeAll()
{
QMap < QString, QgsSqliteHandle * >::iterator i;
for ( i = sHandles.begin(); i != sHandles.end(); ++i )
{
i.value()->sqliteClose();
delete i.value();
}

qDeleteAll( sHandles );
sHandles.clear();
}

void QgsSqliteHandle::sqliteClose()
{
if ( sqlite_handle )
{
QgsSLConnect::sqlite3_close( sqlite_handle );
sqlite_handle = nullptr;
}
}

@@ -18,6 +18,8 @@
#include <QStringList>
#include <QObject>

#include "qgsspatialiteutils.h"

extern "C"
{
#include <sqlite3.h>
@@ -137,15 +139,15 @@ class QgsSqliteHandle
public:
QgsSqliteHandle( sqlite3 *handle, const QString &dbPath, bool shared )
: ref( shared ? 1 : -1 )
, sqlite_handle( handle )
, mDbPath( dbPath )
, mIsValid( true )
{
mDatabase.reset( handle );
}

sqlite3 *handle()
{
return sqlite_handle;
return mDatabase.get();
}

QString dbPath() const
@@ -162,12 +164,6 @@ class QgsSqliteHandle
{
mIsValid = false;
}

//
// libsqlite3 wrapper
//
void sqliteClose();

static QgsSqliteHandle *openDb( const QString &dbPath, bool shared = true );
static bool checkMetadata( sqlite3 *handle );
static void closeDb( QgsSqliteHandle *&handle );
@@ -181,7 +177,7 @@ class QgsSqliteHandle

private:
int ref;
sqlite3 *sqlite_handle = nullptr;
spatialite_database_unique_ptr mDatabase;
QString mDbPath;
bool mIsValid;

@@ -25,12 +25,11 @@ email : a.furieri@lqt.it
#include "qgslogger.h"
#include "qgsmessagelog.h"
#include "qgsvectorlayerexporter.h"
#include "qgsslconnect.h"
#include "qgsspatialiteutils.h"
#include "qgsspatialiteprovider.h"
#include "qgsspatialiteconnpool.h"
#include "qgsspatialitefeatureiterator.h"
#include "qgsfeedback.h"
#include "qgsspatialiteutils.h"

#include "qgsjsonutils.h"
#include "qgsvectorlayer.h"
@@ -50,6 +50,7 @@
#include <qstringlist.h>
#include <qvector.h>
#include <qdebug.h>
#include "qgsspatialiteutils.h"

#if defined Q_OS_WIN
# include <qt_windows.h>
@@ -58,7 +59,6 @@
#endif

#include <sqlite3.h>
#include <qgsslconnect.h>

Q_DECLARE_OPAQUE_POINTER(sqlite3*)
Q_DECLARE_OPAQUE_POINTER(sqlite3_stmt*)
@@ -106,8 +106,8 @@ static QSqlError qMakeError(sqlite3 *access, const QString &descr, QSqlError::Er
class QSpatiaLiteDriverPrivate
{
public:
inline QSpatiaLiteDriverPrivate() : access(0) {}
sqlite3 *access;
inline QSpatiaLiteDriverPrivate() {}
spatialite_database_unique_ptr access;
QList <QSpatiaLiteResult *> results;
};

@@ -311,7 +311,7 @@ QSpatiaLiteResult::QSpatiaLiteResult(const QSpatiaLiteDriver* db)
: QSqlCachedResult(db)
{
d = new QSpatiaLiteResultPrivate(this);
d->access = db->d->access;
d->access = db->d->access.get();
db->d->results.append(this);
}

@@ -498,7 +498,7 @@ QSpatiaLiteDriver::QSpatiaLiteDriver(sqlite3 *connection, QObject *parent)
: QSqlDriver(parent)
{
d = new QSpatiaLiteDriverPrivate();
d->access = connection;
d->access.reset( connection );
setOpen(true);
setOpenError(false);
}
@@ -563,13 +563,16 @@ bool QSpatiaLiteDriver::open(const QString & db, const QString &, const QString

sqlite3_enable_shared_cache(sharedCache);

if (QgsSLConnect::sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, nullptr ) == SQLITE_OK) {
sqlite3_busy_timeout(d->access, timeOut);
spatialite_database_unique_ptr database;


if (d->access.open_v2(db, openMode, nullptr ) == SQLITE_OK) {
sqlite3_busy_timeout(d->access.get(), timeOut);
setOpen(true);
setOpenError(false);
return true;
} else {
setLastError(qMakeError(d->access, tr("Error opening database"),
setLastError(qMakeError(d->access.get(), tr("Error opening database"),
QSqlError::ConnectionError));
setOpenError(true);
return false;
@@ -582,10 +585,7 @@ void QSpatiaLiteDriver::close()
foreach (QSpatiaLiteResult *result, d->results)
result->d->finalize();

if (QgsSLConnect::sqlite3_close(d->access) != SQLITE_OK)
setLastError(qMakeError(d->access, tr("Error closing database"),
QSqlError::ConnectionError));
d->access = 0;
d->access.reset();
setOpen(false);
setOpenError(false);
}
@@ -733,7 +733,7 @@ QSqlRecord QSpatiaLiteDriver::record(const QString &tbl) const

QVariant QSpatiaLiteDriver::handle() const
{
return QVariant::fromValue(d->access);
return QVariant::fromValue(d->access.get());
}

QString QSpatiaLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
@@ -92,6 +92,9 @@ class Q_EXPORT_SQLDRIVER_SQLITE QSpatiaLiteDriver : public QSqlDriver
friend class QSpatiaLiteResult;
public:
explicit QSpatiaLiteDriver(QObject *parent = 0);
/**
* Ownership of \a connection is taken.
*/
explicit QSpatiaLiteDriver(sqlite3 *connection, QObject *parent = 0);
~QSpatiaLiteDriver();
bool hasFeature(DriverFeature f) const;

0 comments on commit 28f1377

Please sign in to comment.
You can’t perform that action at this time.