mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
Use std::unique_ptr with custom deleter for spatialite and sqlite
This commit is contained in:
parent
340f7abbb0
commit
4df65aca37
@ -10,8 +10,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsAuxiliaryLayer : QgsVectorLayer
|
||||
{
|
||||
%Docstring
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "qgsprojectionselectiondialog.h"
|
||||
#include "qgscrscache.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgssqliteutils.h"
|
||||
|
||||
//qt includes
|
||||
#include <QFileInfo>
|
||||
@ -42,121 +43,6 @@ extern "C"
|
||||
#include <proj_api.h>
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a sqlite3 database.
|
||||
*/
|
||||
struct QgsSqlite3Closer
|
||||
{
|
||||
|
||||
/**
|
||||
* Closes an sqlite \a database.
|
||||
*/
|
||||
void operator()( sqlite3 *database )
|
||||
{
|
||||
sqlite3_close( database );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalizes an sqlite3 statement.
|
||||
*/
|
||||
struct QgsSqlite3StatementFinalizer
|
||||
{
|
||||
|
||||
/**
|
||||
* Finalizes an sqlite3 \a statement.
|
||||
*/
|
||||
void operator()( sqlite3_stmt *statement )
|
||||
{
|
||||
sqlite3_finalize( statement );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Unique pointer for sqlite3 prepared statements, which automatically finalizes
|
||||
* the statement when the pointer goes out of scope or is reset.
|
||||
*/
|
||||
class sqlite3_statement_unique_ptr : public std::unique_ptr< sqlite3_stmt, QgsSqlite3StatementFinalizer>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Steps to the next record in the statement, returning the sqlite3 result code.
|
||||
*/
|
||||
int step()
|
||||
{
|
||||
return sqlite3_step( get() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the column value from the current statement row as a string.
|
||||
*/
|
||||
QString columnAsText( int column )
|
||||
{
|
||||
return QString::fromUtf8( ( char * ) sqlite3_column_text( get(), column ) );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unique pointer for sqlite3 databases, which automatically closes
|
||||
* the database when the pointer goes out of scope or is reset.
|
||||
*/
|
||||
class sqlite3_database_unique_ptr : public std::unique_ptr< sqlite3, QgsSqlite3Closer>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Opens the database at the specified file \a path.
|
||||
*
|
||||
* Returns the sqlite error code, or SQLITE_OK if open was successful.
|
||||
*/
|
||||
int open( const QString &path )
|
||||
{
|
||||
sqlite3 *database = nullptr;
|
||||
int result = sqlite3_open( path.toUtf8(), &database );
|
||||
reset( database );
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the database at the specified file \a path.
|
||||
*
|
||||
* Returns the sqlite error code, or SQLITE_OK if open was successful.
|
||||
*/
|
||||
int open_v2( const QString &path, int flags, const char *zVfs )
|
||||
{
|
||||
sqlite3 *database = nullptr;
|
||||
int result = sqlite3_open_v2( path.toUtf8(), &database, flags, zVfs );
|
||||
reset( database );
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the most recent error message encountered by the database.
|
||||
*/
|
||||
QString errorMessage() const
|
||||
{
|
||||
return QString( sqlite3_errmsg( get() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a \a sql statement, returning the result. The \a resultCode
|
||||
* argument will be filled with the sqlite3 result code.
|
||||
*/
|
||||
sqlite3_statement_unique_ptr prepare( const QString &sql, int &resultCode )
|
||||
{
|
||||
sqlite3_stmt *preparedStatement = nullptr;
|
||||
const char *tail = nullptr;
|
||||
resultCode = sqlite3_prepare( get(), sql.toUtf8(), sql.toUtf8().length(), &preparedStatement, &tail );
|
||||
sqlite3_statement_unique_ptr s;
|
||||
s.reset( preparedStatement );
|
||||
return s;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
QgsCustomProjectionDialog::QgsCustomProjectionDialog( QWidget *parent, Qt::WindowFlags fl )
|
||||
: QDialog( parent, fl )
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
#include "qgsproject.h"
|
||||
#include "qgscoordinatereferencesystem.h"
|
||||
#include "qgsprojectionselectiondialog.h"
|
||||
#include "qgsslconnect.h"
|
||||
#include "qgsspatialiteutils.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgssettings.h"
|
||||
|
||||
@ -382,8 +382,8 @@ bool QgsNewSpatialiteLayerDialog::apply()
|
||||
quotedValue( leGeometryColumn->text() ) );
|
||||
QgsDebugMsg( sqlCreateIndex ); // OK
|
||||
|
||||
sqlite3 *db = nullptr;
|
||||
int rc = QgsSLConnect::sqlite3_open( mDatabaseComboBox->currentText().toUtf8(), &db );
|
||||
spatialite_database_unique_ptr database;
|
||||
int rc = database.open( mDatabaseComboBox->currentText() );
|
||||
if ( rc != SQLITE_OK )
|
||||
{
|
||||
QMessageBox::warning( this,
|
||||
@ -393,7 +393,7 @@ bool QgsNewSpatialiteLayerDialog::apply()
|
||||
else
|
||||
{
|
||||
char *errmsg = nullptr;
|
||||
rc = sqlite3_exec( db, sql.toUtf8(), nullptr, nullptr, &errmsg );
|
||||
rc = sqlite3_exec( database.get(), sql.toUtf8(), nullptr, nullptr, &errmsg );
|
||||
if ( rc != SQLITE_OK )
|
||||
{
|
||||
QMessageBox::warning( this,
|
||||
@ -404,7 +404,7 @@ bool QgsNewSpatialiteLayerDialog::apply()
|
||||
else
|
||||
{
|
||||
// create the geometry column and the spatial index
|
||||
rc = sqlite3_exec( db, sqlAddGeom.toUtf8(), nullptr, nullptr, &errmsg );
|
||||
rc = sqlite3_exec( database.get(), sqlAddGeom.toUtf8(), nullptr, nullptr, &errmsg );
|
||||
if ( rc != SQLITE_OK )
|
||||
{
|
||||
QMessageBox::warning( this,
|
||||
@ -415,7 +415,7 @@ bool QgsNewSpatialiteLayerDialog::apply()
|
||||
else
|
||||
{
|
||||
// create the spatial index
|
||||
rc = sqlite3_exec( db, sqlCreateIndex.toUtf8(), nullptr, nullptr, &errmsg );
|
||||
rc = sqlite3_exec( database.get(), sqlCreateIndex.toUtf8(), nullptr, nullptr, &errmsg );
|
||||
if ( rc != SQLITE_OK )
|
||||
{
|
||||
QMessageBox::warning( this,
|
||||
@ -446,8 +446,6 @@ bool QgsNewSpatialiteLayerDialog::apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QgsSLConnect::sqlite3_close( db );
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@ -267,12 +267,13 @@ SET(QGIS_CORE_SRCS
|
||||
qgsscalecalculator.cpp
|
||||
qgsscaleutils.cpp
|
||||
qgssimplifymethod.cpp
|
||||
qgsslconnect.cpp
|
||||
qgssnappingutils.cpp
|
||||
qgsspatialindex.cpp
|
||||
qgssqlexpressioncompiler.cpp
|
||||
qgssqliteexpressioncompiler.cpp
|
||||
qgssqlstatement.cpp
|
||||
qgssqliteutils.cpp
|
||||
qgsspatialiteutils.cpp
|
||||
qgsstatisticalsummary.cpp
|
||||
qgsstringstatisticalsummary.cpp
|
||||
qgsstringutils.cpp
|
||||
@ -924,6 +925,9 @@ SET(QGIS_CORE_HDRS
|
||||
qgssimplifymethod.h
|
||||
qgssnappingutils.h
|
||||
qgsspatialindex.h
|
||||
qgsspatialiteutils.h
|
||||
qgssqlstatement.h
|
||||
qgssqliteutils.h
|
||||
qgssqlexpressioncompiler.h
|
||||
qgssqlstatement.h
|
||||
qgsstatisticalsummary.h
|
||||
|
||||
@ -17,13 +17,14 @@
|
||||
|
||||
#include "qgsauxiliarystorage.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsslconnect.h"
|
||||
#include "qgsspatialiteutils.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsvectorlayerlabeling.h"
|
||||
#include "qgsdiagramrenderer.h"
|
||||
#include "qgsmemoryproviderutils.h"
|
||||
#include "qgssymbollayer.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <QFile>
|
||||
|
||||
const QString AS_JOINFIELD = "ASPK";
|
||||
@ -509,8 +510,7 @@ QgsAuxiliaryStorage::QgsAuxiliaryStorage( const QgsProject &project, bool copy )
|
||||
mFileName = asFileName;
|
||||
}
|
||||
|
||||
sqlite3 *handler = open( mFileName );
|
||||
close( handler );
|
||||
open( mFileName );
|
||||
}
|
||||
|
||||
QgsAuxiliaryStorage::QgsAuxiliaryStorage( const QString &filename, bool copy )
|
||||
@ -519,8 +519,7 @@ QgsAuxiliaryStorage::QgsAuxiliaryStorage( const QString &filename, bool copy )
|
||||
{
|
||||
initTmpFileName();
|
||||
|
||||
sqlite3 *handler = open( filename );
|
||||
close( handler );
|
||||
open( filename );
|
||||
}
|
||||
|
||||
QgsAuxiliaryStorage::~QgsAuxiliaryStorage()
|
||||
@ -568,20 +567,19 @@ QgsAuxiliaryLayer *QgsAuxiliaryStorage::createAuxiliaryLayer( const QgsField &fi
|
||||
if ( mValid && layer )
|
||||
{
|
||||
const QString table( layer->id() );
|
||||
sqlite3 *handler = openDB( currentFileName() );
|
||||
spatialite_database_unique_ptr database;
|
||||
database = openDB( currentFileName() );
|
||||
|
||||
if ( !tableExists( table, handler ) )
|
||||
if ( !tableExists( table, database.get() ) )
|
||||
{
|
||||
if ( !createTable( field.typeName(), table, handler ) )
|
||||
if ( !createTable( field.typeName(), table, database.get() ) )
|
||||
{
|
||||
close( handler );
|
||||
return alayer;
|
||||
}
|
||||
}
|
||||
|
||||
alayer = new QgsAuxiliaryLayer( field.name(), currentFileName(), table, layer );
|
||||
alayer->startEditing();
|
||||
close( handler );
|
||||
}
|
||||
|
||||
return alayer;
|
||||
@ -594,17 +592,16 @@ bool QgsAuxiliaryStorage::deleteTable( const QgsDataSourceUri &ogrUri )
|
||||
|
||||
if ( !uri.database().isEmpty() && !uri.table().isEmpty() )
|
||||
{
|
||||
sqlite3 *handler = openDB( uri.database() );
|
||||
spatialite_database_unique_ptr database;
|
||||
database = openDB( uri.database() );
|
||||
|
||||
if ( handler )
|
||||
if ( database )
|
||||
{
|
||||
QString sql = QString( "DROP TABLE %1" ).arg( uri.table() );
|
||||
rc = exec( sql, handler );
|
||||
rc = exec( sql, database.get() );
|
||||
|
||||
sql = QString( "VACUUM" );
|
||||
rc = exec( sql, handler );
|
||||
|
||||
close( handler );
|
||||
sql = QStringLiteral( "VACUUM" );
|
||||
rc = exec( sql, database.get() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,14 +615,13 @@ bool QgsAuxiliaryStorage::duplicateTable( const QgsDataSourceUri &ogrUri, const
|
||||
|
||||
if ( !uri.table().isEmpty() && !uri.database().isEmpty() )
|
||||
{
|
||||
sqlite3 *handler = openDB( uri.database() );
|
||||
spatialite_database_unique_ptr database;
|
||||
database = openDB( uri.database() );
|
||||
|
||||
if ( handler )
|
||||
if ( database )
|
||||
{
|
||||
QString sql = QString( "CREATE TABLE %1 AS SELECT * FROM %2" ).arg( newTable, uri.table() );
|
||||
rc = exec( sql, handler );
|
||||
|
||||
close( handler );
|
||||
QString sql = QStringLiteral( "CREATE TABLE %1 AS SELECT * FROM %2" ).arg( newTable, uri.table() );
|
||||
rc = exec( sql, database.get() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,23 +671,9 @@ void QgsAuxiliaryStorage::debugMsg( const QString &sql, sqlite3 *handler )
|
||||
QgsDebugMsg( errMsg );
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::openDB( const QString &filename )
|
||||
{
|
||||
sqlite3 *handler = nullptr;
|
||||
|
||||
bool rc = QgsSLConnect::sqlite3_open_v2( filename.toUtf8().constData(), &handler, SQLITE_OPEN_READWRITE, nullptr );
|
||||
if ( rc )
|
||||
{
|
||||
debugMsg( "sqlite3_open_v2", handler );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::createTable( const QString &type, const QString &table, sqlite3 *handler )
|
||||
{
|
||||
const QString sql = QString( "CREATE TABLE IF NOT EXISTS '%1' ( '%2' %3 )" ).arg( table ).arg( AS_JOINFIELD ).arg( type );
|
||||
const QString sql = QStringLiteral( "CREATE TABLE IF NOT EXISTS '%1' ( '%2' %3 )" ).arg( table ).arg( AS_JOINFIELD ).arg( type );
|
||||
|
||||
if ( !exec( sql, handler ) )
|
||||
return false;
|
||||
@ -699,29 +681,42 @@ bool QgsAuxiliaryStorage::createTable( const QString &type, const QString &table
|
||||
return true;
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::createDB( const QString &filename )
|
||||
spatialite_database_unique_ptr QgsAuxiliaryStorage::createDB( const QString &filename )
|
||||
{
|
||||
sqlite3 *handler = nullptr;
|
||||
int rc;
|
||||
|
||||
// open/create database
|
||||
rc = QgsSLConnect::sqlite3_open_v2( filename.toUtf8().constData(), &handler, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
|
||||
spatialite_database_unique_ptr database;
|
||||
rc = database.open_v2( filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
|
||||
if ( rc )
|
||||
{
|
||||
debugMsg( "sqlite3_open_v2", handler );
|
||||
return handler;
|
||||
debugMsg( QStringLiteral( "sqlite3_open_v2" ), database.get() );
|
||||
return database;
|
||||
}
|
||||
|
||||
// activating Foreign Key constraints
|
||||
if ( !exec( "PRAGMA foreign_keys = 1", handler ) )
|
||||
return handler;
|
||||
if ( !exec( QStringLiteral( "PRAGMA foreign_keys = 1" ), database.get() ) )
|
||||
return database;
|
||||
|
||||
return handler;
|
||||
return database;
|
||||
}
|
||||
|
||||
spatialite_database_unique_ptr QgsAuxiliaryStorage::openDB( const QString &filename )
|
||||
{
|
||||
spatialite_database_unique_ptr database;
|
||||
int rc = database.open_v2( filename, SQLITE_OPEN_READWRITE, nullptr );
|
||||
|
||||
if ( rc )
|
||||
{
|
||||
debugMsg( "sqlite3_open_v2", database.get() );
|
||||
}
|
||||
|
||||
return database;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::tableExists( const QString &table, sqlite3 *handler )
|
||||
{
|
||||
const QString sql = QString( "SELECT 1 FROM sqlite_master WHERE type='table' AND name='%1'" ).arg( table );
|
||||
const QString sql = QStringLiteral( "SELECT 1 FROM sqlite_master WHERE type='table' AND name='%1'" ).arg( table );
|
||||
int rows = 0;
|
||||
int columns = 0;
|
||||
char **results = nullptr;
|
||||
@ -739,13 +734,13 @@ bool QgsAuxiliaryStorage::tableExists( const QString &table, sqlite3 *handler )
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::open( const QString &filename )
|
||||
spatialite_database_unique_ptr QgsAuxiliaryStorage::open( const QString &filename )
|
||||
{
|
||||
sqlite3 *handler = nullptr;
|
||||
spatialite_database_unique_ptr database;
|
||||
|
||||
if ( filename.isEmpty() )
|
||||
{
|
||||
if ( ( handler = createDB( currentFileName() ) ) )
|
||||
if ( ( database = createDB( currentFileName() ) ) )
|
||||
mValid = true;
|
||||
}
|
||||
else if ( QFile::exists( filename ) )
|
||||
@ -753,37 +748,28 @@ sqlite3 *QgsAuxiliaryStorage::open( const QString &filename )
|
||||
if ( mCopy )
|
||||
QFile::copy( filename, mTmpFileName );
|
||||
|
||||
if ( ( handler = openDB( currentFileName() ) ) )
|
||||
if ( ( database = openDB( currentFileName() ) ) )
|
||||
mValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ( handler = createDB( currentFileName() ) ) )
|
||||
if ( ( database = createDB( currentFileName() ) ) )
|
||||
mValid = true;
|
||||
}
|
||||
|
||||
return handler;
|
||||
return database;
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::open( const QgsProject &project )
|
||||
spatialite_database_unique_ptr QgsAuxiliaryStorage::open( const QgsProject &project )
|
||||
{
|
||||
return open( filenameForProject( project ) );
|
||||
}
|
||||
|
||||
void QgsAuxiliaryStorage::close( sqlite3 *handler )
|
||||
{
|
||||
if ( handler )
|
||||
{
|
||||
QgsSLConnect::sqlite3_close_v2( handler );
|
||||
handler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsAuxiliaryStorage::filenameForProject( const QgsProject &project )
|
||||
{
|
||||
const QFileInfo info = project.fileInfo();
|
||||
const QString path = info.path() + QDir::separator() + info.baseName();
|
||||
return path + "." + QgsAuxiliaryStorage::extension();
|
||||
return path + '.' + QgsAuxiliaryStorage::extension();
|
||||
}
|
||||
|
||||
void QgsAuxiliaryStorage::initTmpFileName()
|
||||
@ -820,7 +806,7 @@ QgsDataSourceUri QgsAuxiliaryStorage::parseOgrUri( const QgsDataSourceUri &uri )
|
||||
if ( tableParts.count() < 1 )
|
||||
return newUri;
|
||||
|
||||
const QString tableName = tableParts[0].replace( "layername=", "" );
|
||||
const QString tableName = tableParts[0].replace( QStringLiteral( "layername=" ), QStringLiteral( "" ) );
|
||||
|
||||
newUri.setDataSource( QString(), tableName, QString() );
|
||||
newUri.setDatabase( databasePath );
|
||||
|
||||
@ -24,9 +24,7 @@
|
||||
#include "qgsdiagramrenderer.h"
|
||||
#include "qgsvectorlayerjoininfo.h"
|
||||
#include "qgsproperty.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "qgsspatialiteutils.h"
|
||||
#include <QString>
|
||||
|
||||
class QgsProject;
|
||||
@ -385,15 +383,14 @@ class CORE_EXPORT QgsAuxiliaryStorage
|
||||
static QString extension();
|
||||
|
||||
private:
|
||||
sqlite3 *open( const QString &filename = QString() );
|
||||
sqlite3 *open( const QgsProject &project );
|
||||
spatialite_database_unique_ptr open( const QString &filename = QString() );
|
||||
spatialite_database_unique_ptr open( const QgsProject &project );
|
||||
|
||||
void initTmpFileName();
|
||||
|
||||
static QString filenameForProject( const QgsProject &project );
|
||||
static sqlite3 *createDB( const QString &filename );
|
||||
static sqlite3 *openDB( const QString &filename );
|
||||
static void close( sqlite3 *handler );
|
||||
static spatialite_database_unique_ptr createDB( const QString &filename );
|
||||
static spatialite_database_unique_ptr openDB( const QString &filename );
|
||||
static bool tableExists( const QString &table, sqlite3 *handler );
|
||||
static bool createTable( const QString &type, const QString &table, sqlite3 *handler );
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsvectorlayereditbuffer.h"
|
||||
#include "qgsvectorlayerjoinbuffer.h"
|
||||
#include "qgsslconnect.h"
|
||||
#include "qgsspatialiteutils.h"
|
||||
#include "qgsfeatureiterator.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsvectorlayerutils.h"
|
||||
@ -87,8 +87,8 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString &offlineDataPath,
|
||||
QString dbPath = QDir( offlineDataPath ).absoluteFilePath( offlineDbFile );
|
||||
if ( createSpatialiteDB( dbPath ) )
|
||||
{
|
||||
sqlite3 *db = nullptr;
|
||||
int rc = QgsSLConnect::sqlite3_open( dbPath.toUtf8().constData(), &db );
|
||||
spatialite_database_unique_ptr database;
|
||||
int rc = database.open( dbPath );
|
||||
if ( rc != SQLITE_OK )
|
||||
{
|
||||
showWarning( tr( "Could not open the SpatiaLite database" ) );
|
||||
@ -96,7 +96,7 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString &offlineDataPath,
|
||||
else
|
||||
{
|
||||
// create logging tables
|
||||
createLoggingTables( db );
|
||||
createLoggingTables( database.get() );
|
||||
|
||||
emit progressStarted();
|
||||
|
||||
@ -140,7 +140,7 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString &offlineDataPath,
|
||||
if ( vl )
|
||||
{
|
||||
QString origLayerId = vl->id();
|
||||
QgsVectorLayer *newLayer = copyVectorLayer( vl, db, dbPath, onlySelected );
|
||||
QgsVectorLayer *newLayer = copyVectorLayer( vl, database.get(), dbPath, onlySelected );
|
||||
if ( newLayer )
|
||||
{
|
||||
layerIdMapping.insert( origLayerId, newLayer );
|
||||
@ -175,8 +175,6 @@ bool QgsOfflineEditing::convertToOfflineProject( const QString &offlineDataPath,
|
||||
|
||||
emit progressStopped();
|
||||
|
||||
QgsSLConnect::sqlite3_close( db );
|
||||
|
||||
// save offline project
|
||||
QString projectTitle = QgsProject::instance()->title();
|
||||
if ( projectTitle.isEmpty() )
|
||||
@ -394,7 +392,6 @@ void QgsOfflineEditing::initializeSpatialMetadata( sqlite3 *sqlite_handle )
|
||||
bool QgsOfflineEditing::createSpatialiteDB( const QString &offlineDbPath )
|
||||
{
|
||||
int ret;
|
||||
sqlite3 *sqlite_handle = nullptr;
|
||||
char *errMsg = nullptr;
|
||||
QFile newDb( offlineDbPath );
|
||||
if ( newDb.exists() )
|
||||
@ -412,30 +409,25 @@ bool QgsOfflineEditing::createSpatialiteDB( const QString &offlineDbPath )
|
||||
|
||||
// creating/opening the new database
|
||||
QString dbPath = newDb.fileName();
|
||||
ret = QgsSLConnect::sqlite3_open_v2( dbPath.toUtf8().constData(), &sqlite_handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
|
||||
spatialite_database_unique_ptr database;
|
||||
ret = database.open_v2( dbPath, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
|
||||
if ( ret )
|
||||
{
|
||||
// an error occurred
|
||||
QString errCause = tr( "Could not create a new database\n" );
|
||||
errCause += QString::fromUtf8( sqlite3_errmsg( sqlite_handle ) );
|
||||
sqlite3_close( sqlite_handle );
|
||||
errCause += database.errorMessage();
|
||||
showWarning( errCause );
|
||||
return false;
|
||||
}
|
||||
// activating Foreign Key constraints
|
||||
ret = sqlite3_exec( sqlite_handle, "PRAGMA foreign_keys = 1", nullptr, nullptr, &errMsg );
|
||||
ret = sqlite3_exec( database.get(), "PRAGMA foreign_keys = 1", nullptr, nullptr, &errMsg );
|
||||
if ( ret != SQLITE_OK )
|
||||
{
|
||||
showWarning( tr( "Unable to activate FOREIGN_KEY constraints" ) );
|
||||
sqlite3_free( errMsg );
|
||||
QgsSLConnect::sqlite3_close( sqlite_handle );
|
||||
return false;
|
||||
}
|
||||
initializeSpatialMetadata( sqlite_handle );
|
||||
|
||||
// all done: closing the DB connection
|
||||
QgsSLConnect::sqlite3_close( sqlite_handle );
|
||||
|
||||
initializeSpatialMetadata( database.get() );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,100 +0,0 @@
|
||||
/***************************************************************************
|
||||
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 "qgslogger.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <spatialite.h>
|
||||
|
||||
#if defined(SPATIALITE_HAS_INIT_EX)
|
||||
QHash<sqlite3 *, void *> QgsSLConnect::sSLconns;
|
||||
#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 );
|
||||
sSLconns.insert( *ppDb, conn );
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int QgsSLConnect::sqlite3_close( sqlite3 *db )
|
||||
{
|
||||
int res = ::sqlite3_close( db );
|
||||
|
||||
#if defined(SPATIALITE_HAS_INIT_EX)
|
||||
if ( sSLconns.contains( db ) )
|
||||
spatialite_cleanup_ex( sSLconns.take( db ) );
|
||||
#endif
|
||||
|
||||
if ( res != SQLITE_OK )
|
||||
{
|
||||
QgsDebugMsg( QString( "sqlite3_close() failed: %1" ).arg( res ) );
|
||||
}
|
||||
|
||||
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 );
|
||||
sSLconns.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 ( sSLconns.contains( db ) )
|
||||
spatialite_cleanup_ex( sSLconns.take( db ) );
|
||||
#endif
|
||||
|
||||
if ( res != SQLITE_OK )
|
||||
{
|
||||
QgsDebugMsg( QString( "sqlite3_close() failed: %1" ).arg( res ) );
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsslconnect.h - 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSSLCONNECT_H
|
||||
#define QGSSLCONNECT_H
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
#include <QHash>
|
||||
|
||||
#include "qgis_core.h"
|
||||
|
||||
struct sqlite3;
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsSLConnect
|
||||
* \note not available in Python bindings
|
||||
*/
|
||||
class CORE_EXPORT QgsSLConnect
|
||||
{
|
||||
public:
|
||||
static int sqlite3_open( const char *filename, sqlite3 **ppDb );
|
||||
static int sqlite3_close( sqlite3 * );
|
||||
|
||||
static int sqlite3_open_v2( const char *filename, sqlite3 **ppDb, int flags, const char *zVfs );
|
||||
static int sqlite3_close_v2( sqlite3 * );
|
||||
|
||||
#if defined(SPATIALITE_HAS_INIT_EX)
|
||||
private:
|
||||
static QHash<sqlite3 *, void *> sSLconns;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
88
src/core/qgsspatialiteutils.cpp
Normal file
88
src/core/qgsspatialiteutils.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
/***************************************************************************
|
||||
qgsspatialiteutils.cpp
|
||||
-------------------
|
||||
begin : Nov, 2017
|
||||
copyright : (C) 2017 by Matthias Kuhn
|
||||
email : matthias@opengis.ch
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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 "qgsspatialiteutils.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <spatialite.h>
|
||||
|
||||
int spatialite_database_unique_ptr::open( const QString &path )
|
||||
{
|
||||
|
||||
#if defined(SPATIALITE_HAS_INIT_EX)
|
||||
void *conn = spatialite_alloc_connection();
|
||||
#else
|
||||
spatialite_init( 0 );
|
||||
#endif
|
||||
|
||||
sqlite3 *database = nullptr;
|
||||
int result = sqlite3_open( path.toUtf8(), &database );
|
||||
reset( database );
|
||||
|
||||
#if defined(SPATIALITE_HAS_INIT_EX)
|
||||
if ( result == SQLITE_OK )
|
||||
spatialite_init_ex( database, conn, 0 );
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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();
|
||||
#else
|
||||
spatialite_init( 0 );
|
||||
#endif
|
||||
|
||||
sqlite3 *database = nullptr;
|
||||
int result = sqlite3_open_v2( path.toUtf8(), &database, flags, zVfs );
|
||||
reset( database );
|
||||
|
||||
#if defined(SPATIALITE_HAS_INIT_EX)
|
||||
if ( result == SQLITE_OK )
|
||||
spatialite_init_ex( database, conn, 0 );
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString spatialite_database_unique_ptr::errorMessage() const
|
||||
{
|
||||
return QString( sqlite3_errmsg( get() ) );
|
||||
}
|
||||
|
||||
sqlite3_statement_unique_ptr spatialite_database_unique_ptr::prepare( const QString &sql, int &resultCode )
|
||||
{
|
||||
sqlite3_stmt *preparedStatement = nullptr;
|
||||
const char *tail = nullptr;
|
||||
resultCode = sqlite3_prepare( get(), sql.toUtf8(), sql.toUtf8().length(), &preparedStatement, &tail );
|
||||
sqlite3_statement_unique_ptr s;
|
||||
s.reset( preparedStatement );
|
||||
return s;
|
||||
}
|
||||
|
||||
void QgsSpatialiteCloser::operator()( sqlite3 *database )
|
||||
{
|
||||
sqlite3_close( database );
|
||||
|
||||
#if defined(SPATIALITE_HAS_INIT_EX)
|
||||
spatialite_cleanup_ex( database );
|
||||
#endif
|
||||
|
||||
}
|
||||
73
src/core/qgsspatialiteutils.h
Normal file
73
src/core/qgsspatialiteutils.h
Normal file
@ -0,0 +1,73 @@
|
||||
/***************************************************************************
|
||||
qgsspatialiteutils.h
|
||||
-------------------
|
||||
begin : Nov, 2017
|
||||
copyright : (C) 2017 by Matthias Kuhn
|
||||
email : matthias@opengis.ch
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSSPATIALITEUTILS_H
|
||||
#define QGSSPATIALITEUTILS_H
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgssqliteutils.h"
|
||||
|
||||
/**
|
||||
* Closes a spatialite database.
|
||||
*/
|
||||
struct CORE_EXPORT QgsSpatialiteCloser
|
||||
{
|
||||
|
||||
/**
|
||||
* Closes an spatialite \a database.
|
||||
*/
|
||||
void operator()( sqlite3 *database );
|
||||
};
|
||||
|
||||
/**
|
||||
* Unique pointer for spatialite databases, which automatically closes
|
||||
* the database when the pointer goes out of scope or is reset.
|
||||
*/
|
||||
class CORE_EXPORT spatialite_database_unique_ptr : public std::unique_ptr< sqlite3, QgsSpatialiteCloser>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Opens the database at the specified file \a path.
|
||||
*
|
||||
* Returns the sqlite error code, or SQLITE_OK if open was successful.
|
||||
*/
|
||||
int open( const QString &path );
|
||||
|
||||
/**
|
||||
* Opens the database at the specified file \a path.
|
||||
*
|
||||
* Returns the sqlite error code, or SQLITE_OK if open was successful.
|
||||
*/
|
||||
int open_v2( const QString &path, int flags, const char *zVfs );
|
||||
|
||||
/**
|
||||
* Returns the most recent error message encountered by the database.
|
||||
*/
|
||||
QString errorMessage() const;
|
||||
|
||||
/**
|
||||
* Prepares a \a sql statement, returning the result. The \a resultCode
|
||||
* argument will be filled with the sqlite3 result code.
|
||||
*/
|
||||
sqlite3_statement_unique_ptr prepare( const QString &sql, int &resultCode );
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSSPATIALITEUTILS_H
|
||||
71
src/core/qgssqliteutils.cpp
Normal file
71
src/core/qgssqliteutils.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/***************************************************************************
|
||||
qgssqliteutils.cpp
|
||||
-------------------
|
||||
begin : Nov, 2017
|
||||
copyright : (C) 2017 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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 "qgssqliteutils.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
void QgsSqlite3Closer::operator()( sqlite3 *database )
|
||||
{
|
||||
sqlite3_close( database );
|
||||
}
|
||||
|
||||
void QgsSqlite3StatementFinalizer::operator()( sqlite3_stmt *statement )
|
||||
{
|
||||
sqlite3_finalize( statement );
|
||||
}
|
||||
|
||||
int sqlite3_statement_unique_ptr::step()
|
||||
{
|
||||
return sqlite3_step( get() );
|
||||
}
|
||||
|
||||
QString sqlite3_statement_unique_ptr::columnAsText( int column )
|
||||
{
|
||||
return QString::fromUtf8( ( char * ) sqlite3_column_text( get(), column ) );
|
||||
}
|
||||
|
||||
int sqlite3_database_unique_ptr::open( const QString &path )
|
||||
{
|
||||
sqlite3 *database = nullptr;
|
||||
int result = sqlite3_open( path.toUtf8(), &database );
|
||||
reset( database );
|
||||
return result;
|
||||
}
|
||||
|
||||
int sqlite3_database_unique_ptr::open_v2( const QString &path, int flags, const char *zVfs )
|
||||
{
|
||||
sqlite3 *database = nullptr;
|
||||
int result = sqlite3_open_v2( path.toUtf8(), &database, flags, zVfs );
|
||||
reset( database );
|
||||
return result;
|
||||
}
|
||||
|
||||
QString sqlite3_database_unique_ptr::errorMessage() const
|
||||
{
|
||||
return QString( sqlite3_errmsg( get() ) );
|
||||
}
|
||||
|
||||
sqlite3_statement_unique_ptr sqlite3_database_unique_ptr::prepare( const QString &sql, int &resultCode )
|
||||
{
|
||||
sqlite3_stmt *preparedStatement = nullptr;
|
||||
const char *tail = nullptr;
|
||||
resultCode = sqlite3_prepare( get(), sql.toUtf8(), sql.toUtf8().length(), &preparedStatement, &tail );
|
||||
sqlite3_statement_unique_ptr s;
|
||||
s.reset( preparedStatement );
|
||||
return s;
|
||||
}
|
||||
110
src/core/qgssqliteutils.h
Normal file
110
src/core/qgssqliteutils.h
Normal file
@ -0,0 +1,110 @@
|
||||
/***************************************************************************
|
||||
qgssqliteutils.h
|
||||
-------------------
|
||||
begin : Nov, 2017
|
||||
copyright : (C) 2017 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSSQLITEUTILS_H
|
||||
#define QGSSQLITEUTILS_H
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include <memory>
|
||||
#include <QString>
|
||||
|
||||
struct sqlite3;
|
||||
struct sqlite3_stmt;
|
||||
|
||||
/**
|
||||
* Closes a sqlite3 database.
|
||||
*/
|
||||
struct CORE_EXPORT QgsSqlite3Closer
|
||||
{
|
||||
|
||||
/**
|
||||
* Closes an sqlite \a database.
|
||||
*/
|
||||
void operator()( sqlite3 *database );
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalizes an sqlite3 statement.
|
||||
*/
|
||||
struct CORE_EXPORT QgsSqlite3StatementFinalizer
|
||||
{
|
||||
|
||||
/**
|
||||
* Finalizes an sqlite3 \a statement.
|
||||
*/
|
||||
void operator()( sqlite3_stmt *statement );
|
||||
};
|
||||
|
||||
/**
|
||||
* Unique pointer for sqlite3 prepared statements, which automatically finalizes
|
||||
* the statement when the pointer goes out of scope or is reset.
|
||||
*/
|
||||
class CORE_EXPORT sqlite3_statement_unique_ptr : public std::unique_ptr< sqlite3_stmt, QgsSqlite3StatementFinalizer>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Steps to the next record in the statement, returning the sqlite3 result code.
|
||||
*/
|
||||
int step();
|
||||
|
||||
/**
|
||||
* Returns the column value from the current statement row as a string.
|
||||
*/
|
||||
QString columnAsText( int column );
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unique pointer for sqlite3 databases, which automatically closes
|
||||
* the database when the pointer goes out of scope or is reset.
|
||||
*/
|
||||
class CORE_EXPORT sqlite3_database_unique_ptr : public std::unique_ptr< sqlite3, QgsSqlite3Closer>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Opens the database at the specified file \a path.
|
||||
*
|
||||
* Returns the sqlite error code, or SQLITE_OK if open was successful.
|
||||
*/
|
||||
int open( const QString &path );
|
||||
|
||||
/**
|
||||
* Opens the database at the specified file \a path.
|
||||
*
|
||||
* Returns the sqlite error code, or SQLITE_OK if open was successful.
|
||||
*/
|
||||
int open_v2( const QString &path, int flags, const char *zVfs );
|
||||
|
||||
/**
|
||||
* Returns the most recent error message encountered by the database.
|
||||
*/
|
||||
QString errorMessage() const;
|
||||
|
||||
/**
|
||||
* Prepares a \a sql statement, returning the result. The \a resultCode
|
||||
* argument will be filled with the sqlite3 result code.
|
||||
*/
|
||||
sqlite3_statement_unique_ptr prepare( const QString &sql, int &resultCode );
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSSQLITEUTILS_H
|
||||
@ -16,6 +16,7 @@
|
||||
#include "qgsslconnect.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsspatialiteutils.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <cstdlib> // atoi
|
||||
@ -65,11 +66,12 @@ QgsSpatiaLiteConnection::Error QgsSpatiaLiteConnection::fetchTables( bool loadGe
|
||||
if ( !fi.exists() )
|
||||
return NotExists;
|
||||
|
||||
sqlite3 *handle = openSpatiaLiteDb( fi.canonicalFilePath() );
|
||||
if ( !handle )
|
||||
spatialite_database_unique_ptr database;
|
||||
int ret = database.open( fi.canonicalFilePath() );
|
||||
if ( ret )
|
||||
return FailedToOpen;
|
||||
|
||||
int ret = checkHasMetadataTables( handle );
|
||||
ret = checkHasMetadataTables( handle );
|
||||
if ( !mErrorMsg.isNull() || ret == LayoutUnknown )
|
||||
{
|
||||
// unexpected error; invalid SpatiaLite DB
|
||||
@ -92,15 +94,14 @@ QgsSpatiaLiteConnection::Error QgsSpatiaLiteConnection::fetchTables( bool loadGe
|
||||
#ifdef SPATIALITE_VERSION_GE_4_0_0
|
||||
// only if libspatialite version is >= 4.0.0
|
||||
// using v.4.0 Abstract Interface
|
||||
if ( !getTableInfoAbstractInterface( handle, loadGeometrylessTables ) )
|
||||
if ( !getTableInfoAbstractInterface( database.get(), loadGeometrylessTables ) )
|
||||
#else
|
||||
// obsolete library: still using the traditional approach
|
||||
if ( !getTableInfo( handle, loadGeometrylessTables ) )
|
||||
if ( !getTableInfo( database.get(), loadGeometrylessTables ) )
|
||||
#endif
|
||||
{
|
||||
return FailedToGetTables;
|
||||
}
|
||||
closeSpatiaLiteDb( handle );
|
||||
|
||||
return NoError;
|
||||
}
|
||||
@ -112,13 +113,12 @@ bool QgsSpatiaLiteConnection::updateStatistics()
|
||||
if ( !fi.exists() )
|
||||
return false;
|
||||
|
||||
sqlite3 *handle = openSpatiaLiteDb( fi.canonicalFilePath() );
|
||||
if ( !handle )
|
||||
spatialite_database_unique_ptr database;
|
||||
int ret = database.open( fi.canonicalFilePath() );
|
||||
if ( ret )
|
||||
return false;
|
||||
|
||||
bool ret = update_layer_statistics( handle, nullptr, nullptr );
|
||||
|
||||
closeSpatiaLiteDb( handle );
|
||||
ret = update_layer_statistics( database.get(), nullptr, nullptr );
|
||||
|
||||
return ret;
|
||||
#else
|
||||
@ -126,27 +126,6 @@ bool QgsSpatiaLiteConnection::updateStatistics()
|
||||
#endif
|
||||
}
|
||||
|
||||
sqlite3 *QgsSpatiaLiteConnection::openSpatiaLiteDb( const QString &path )
|
||||
{
|
||||
sqlite3 *handle = nullptr;
|
||||
int ret;
|
||||
// trying to open the SQLite DB
|
||||
ret = QgsSLConnect::sqlite3_open_v2( path.toUtf8().constData(), &handle, SQLITE_OPEN_READWRITE, nullptr );
|
||||
if ( ret )
|
||||
{
|
||||
// failure
|
||||
mErrorMsg = sqlite3_errmsg( handle );
|
||||
return nullptr;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteConnection::closeSpatiaLiteDb( sqlite3 *handle )
|
||||
{
|
||||
if ( handle )
|
||||
QgsSLConnect::sqlite3_close( handle );
|
||||
}
|
||||
|
||||
int QgsSpatiaLiteConnection::checkHasMetadataTables( sqlite3 *handle )
|
||||
{
|
||||
bool gcSpatiaLite = false;
|
||||
|
||||
@ -30,6 +30,7 @@ email : a.furieri@lqt.it
|
||||
#include "qgsspatialiteconnpool.h"
|
||||
#include "qgsspatialitefeatureiterator.h"
|
||||
#include "qgsfeedback.h"
|
||||
#include "qgsspatialiteutils.h"
|
||||
|
||||
#include "qgsjsonutils.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
@ -5352,30 +5353,25 @@ QGISEXTERN bool createDb( const QString &dbPath, QString &errCause )
|
||||
QDir().mkpath( path.absolutePath() );
|
||||
|
||||
// creating/opening the new database
|
||||
sqlite3 *sqlite_handle = nullptr;
|
||||
int ret = QgsSLConnect::sqlite3_open_v2( dbPath.toUtf8().constData(), &sqlite_handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
|
||||
spatialite_database_unique_ptr database;
|
||||
int ret = database.open_v2( dbPath, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
|
||||
if ( ret )
|
||||
{
|
||||
// an error occurred
|
||||
errCause = QObject::tr( "Could not create a new database\n" );
|
||||
errCause += QString::fromUtf8( sqlite3_errmsg( sqlite_handle ) );
|
||||
QgsSLConnect::sqlite3_close( sqlite_handle );
|
||||
errCause += database.errorMessage();
|
||||
return false;
|
||||
}
|
||||
// activating Foreign Key constraints
|
||||
char *errMsg = nullptr;
|
||||
ret = sqlite3_exec( sqlite_handle, "PRAGMA foreign_keys = 1", nullptr, nullptr, &errMsg );
|
||||
ret = sqlite3_exec( database.get(), "PRAGMA foreign_keys = 1", nullptr, nullptr, &errMsg );
|
||||
if ( ret != SQLITE_OK )
|
||||
{
|
||||
errCause = QObject::tr( "Unable to activate FOREIGN_KEY constraints [%1]" ).arg( errMsg );
|
||||
sqlite3_free( errMsg );
|
||||
QgsSLConnect::sqlite3_close( sqlite_handle );
|
||||
return false;
|
||||
}
|
||||
bool init_res = ::initializeSpatialMetadata( sqlite_handle, errCause );
|
||||
|
||||
// all done: closing the DB connection
|
||||
QgsSLConnect::sqlite3_close( sqlite_handle );
|
||||
bool init_res = ::initializeSpatialMetadata( database.get(), errCause );
|
||||
|
||||
return init_res;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user