Move spatialite context management to deleter

This commit is contained in:
Matthias Kuhn 2017-11-14 23:16:29 +01:00
parent 43329f50d6
commit 2b6d1f8882
2 changed files with 32 additions and 30 deletions

View File

@ -22,18 +22,10 @@
#include <sqlite3.h>
#include <spatialite.h>
spatialite_database_unique_ptr::spatialite_database_unique_ptr()
: std::unique_ptr< sqlite3, std::function<void( sqlite3 * )>> ( nullptr, [this]( sqlite3 * handle )->void
{
deleter( handle );
} )
{
}
int spatialite_database_unique_ptr::open( const QString &path )
{
#if defined(SPATIALITE_HAS_INIT_EX)
mSpatialiteContext = spatialite_alloc_connection();
get_deleter().mSpatialiteContext = spatialite_alloc_connection();
#else
spatialite_init( 0 );
#endif
@ -44,7 +36,7 @@ int spatialite_database_unique_ptr::open( const QString &path )
#if defined(SPATIALITE_HAS_INIT_EX)
if ( result == SQLITE_OK )
spatialite_init_ex( database, mSpatialiteContext, 0 );
spatialite_init_ex( database, get_deleter().mSpatialiteContext, 0 );
#endif
return result;
@ -53,7 +45,7 @@ int spatialite_database_unique_ptr::open( const QString &path )
int spatialite_database_unique_ptr::open_v2( const QString &path, int flags, const char *zVfs )
{
#if defined(SPATIALITE_HAS_INIT_EX)
void *conn = spatialite_alloc_connection();
get_deleter().mSpatialiteContext = spatialite_alloc_connection();
#else
spatialite_init( 0 );
#endif
@ -64,7 +56,7 @@ int spatialite_database_unique_ptr::open_v2( const QString &path, int flags, con
#if defined(SPATIALITE_HAS_INIT_EX)
if ( result == SQLITE_OK )
spatialite_init_ex( database, conn, 0 );
spatialite_init_ex( database, get_deleter().mSpatialiteContext, 0 );
#endif
return result;
@ -79,21 +71,24 @@ sqlite3_statement_unique_ptr spatialite_database_unique_ptr::prepare( const QStr
{
sqlite3_stmt *preparedStatement = nullptr;
const char *tail = nullptr;
resultCode = sqlite3_prepare( get(), sql.toUtf8(), sql.toUtf8().length(), &preparedStatement, &tail );
const QByteArray sqlUtf8 = sql.toUtf8();
resultCode = sqlite3_prepare( get(), sqlUtf8, sqlUtf8.length(), &preparedStatement, &tail );
sqlite3_statement_unique_ptr s;
s.reset( preparedStatement );
return s;
}
void spatialite_database_unique_ptr::deleter( sqlite3 *handle )
void QgsSpatialiteCloser::operator()( sqlite3 *handle )
{
#if defined(SPATIALITE_HAS_INIT_EX)
spatialite_cleanup_ex( mSpatialiteContext );
mSpatialiteContext = nullptr;
#endif
int res = sqlite3_close( handle );
if ( res != SQLITE_OK )
{
QgsDebugMsg( QString( "sqlite3_close() failed: %1" ).arg( res ) );
QgsDebugMsg( QStringLiteral( "sqlite3_close() failed: %1" ).arg( res ) );
}
}

View File

@ -24,6 +24,27 @@
#include "qgssqliteutils.h"
#include <functional>
/**
* \ingroup core
*
* Closes a spatialite database.
*
* \since QGIS 3.0
*/
struct CORE_EXPORT QgsSpatialiteCloser
{
/**
* Closes an spatialite \a database.
*/
void operator()( sqlite3 *database );
/**
* Keep track of the spatialite context. Set in open(_v2)
*/
void *mSpatialiteContext = nullptr;
};
/**
* \ingroup core
*
@ -32,12 +53,10 @@
*
* \since QGIS 3.0
*/
class CORE_EXPORT spatialite_database_unique_ptr : public std::unique_ptr< sqlite3, std::function<void( sqlite3 * )>>
class CORE_EXPORT spatialite_database_unique_ptr : public std::unique_ptr< sqlite3, QgsSpatialiteCloser>
{
public:
spatialite_database_unique_ptr();
/**
* Opens the database at the specified file \a path.
*
@ -62,18 +81,6 @@ class CORE_EXPORT spatialite_database_unique_ptr : public std::unique_ptr< sqlit
* argument will be filled with the sqlite3 result code.
*/
sqlite3_statement_unique_ptr prepare( const QString &sql, int &resultCode );
private:
/**
* Will be set as deleter for this pointer in the constructor.
*/
void deleter( sqlite3 *handle );
/**
* Keep track of the spatialite context. Set in open(_v2), unset in deleter.
*/
void *mSpatialiteContext = nullptr;
};
#endif // QGSSPATIALITEUTILS_H