Skip to content

Commit 9c67560

Browse files
committed
Geopackage import multiple files master task
This fixes a problem when importing multiple files into a gpkg. Previous implementation spawned multiple independent task causing the import to fail because of DB being write-locked. This implementation uses a master task with subtask and dependencies.
1 parent 2cf2ad2 commit 9c67560

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

src/providers/ogr/qgsgeopackagedataitems.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "qgsmessageoutput.h"
2929
#include "qgsvectorlayerexporter.h"
3030
#include "qgsgeopackagerasterwritertask.h"
31+
#include "qgstaskmanager.h"
3132

3233
#include <QAction>
3334
#include <QMessageBox>
@@ -191,6 +192,10 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
191192
QStringList importResults;
192193
bool hasError = false;
193194

195+
// Main task
196+
std::unique_ptr< QgsGeoPackageImportTask > mainTask( new QgsGeoPackageImportTask( tr( "GeoPackage import" ) ) );
197+
QgsTaskList importTasks;
198+
194199
const auto lst = QgsMimeDataUtils::decodeUriList( data );
195200
for ( const QgsMimeDataUtils::Uri &dropUri : lst )
196201
{
@@ -252,18 +257,19 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
252257
options.insert( QStringLiteral( "update" ), true );
253258
options.insert( QStringLiteral( "overwrite" ), true );
254259
options.insert( QStringLiteral( "layerName" ), dropUri.name );
255-
256-
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( vectorSrcLayer, uri, QStringLiteral( "ogr" ), vectorSrcLayer->crs(), options, owner ) );
260+
QgsVectorLayerExporterTask *exportTask = new QgsVectorLayerExporterTask( vectorSrcLayer, uri, QStringLiteral( "ogr" ), vectorSrcLayer->crs(), options, owner ) ;
261+
mainTask->addSubTask( exportTask, importTasks );
262+
importTasks << exportTask;
257263
// when export is successful:
258-
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()
264+
connect( exportTask, &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()
259265
{
260266
// this is gross - TODO - find a way to get access to messageBar from data items
261267
QMessageBox::information( nullptr, tr( "Import to GeoPackage database" ), tr( "Import was successful." ) );
262268
refreshConnections();
263269
} );
264270

265271
// when an error occurs:
266-
connect( exportTask.get(), &QgsVectorLayerExporterTask::errorOccurred, this, [ = ]( int error, const QString & errorMessage )
272+
connect( exportTask, &QgsVectorLayerExporterTask::errorOccurred, this, [ = ]( int error, const QString & errorMessage )
267273
{
268274
if ( error != QgsVectorLayerExporter::ErrUserCanceled )
269275
{
@@ -274,22 +280,22 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
274280
}
275281
} );
276282

277-
QgsApplication::taskManager()->addTask( exportTask.release() );
278283
}
279284
else // Import raster
280285
{
281-
282-
std::unique_ptr< QgsGeoPackageRasterWriterTask > exportTask( new QgsGeoPackageRasterWriterTask( dropUri, mPath ) );
286+
QgsGeoPackageRasterWriterTask *exportTask = new QgsGeoPackageRasterWriterTask( dropUri, mPath ) ;
287+
mainTask->addSubTask( exportTask, importTasks );
288+
importTasks << exportTask;
283289
// when export is successful:
284-
connect( exportTask.get(), &QgsGeoPackageRasterWriterTask::writeComplete, this, [ = ]()
290+
connect( exportTask, &QgsGeoPackageRasterWriterTask::writeComplete, this, [ = ]()
285291
{
286292
// this is gross - TODO - find a way to get access to messageBar from data items
287293
QMessageBox::information( nullptr, tr( "Import to GeoPackage database" ), tr( "Import was successful." ) );
288294
refreshConnections();
289295
} );
290296

291297
// when an error occurs:
292-
connect( exportTask.get(), &QgsGeoPackageRasterWriterTask::errorOccurred, this, [ = ]( QgsGeoPackageRasterWriter::WriterError error, const QString & errorMessage )
298+
connect( exportTask, &QgsGeoPackageRasterWriterTask::errorOccurred, this, [ = ]( QgsGeoPackageRasterWriter::WriterError error, const QString & errorMessage )
293299
{
294300
if ( error != QgsGeoPackageRasterWriter::WriterError::ErrUserCanceled )
295301
{
@@ -304,7 +310,6 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
304310
deleteGeoPackageRasterLayer( QStringLiteral( "GPKG:%1:%2" ).arg( mPath, dropUri.name ), deleteErr );
305311
} );
306312

307-
QgsApplication::taskManager()->addTask( exportTask.release() );
308313
}
309314
} // do not overwrite
310315
}
@@ -323,6 +328,10 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
323328
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( QStringLiteral( "\n" ) ), QgsMessageOutput::MessageText );
324329
output->showMessage();
325330
}
331+
else if ( ! importTasks.isEmpty() )
332+
{
333+
QgsApplication::taskManager()->addTask( mainTask.release() );
334+
}
326335
return true;
327336
}
328337

src/providers/ogr/qgsgeopackagedataitems.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "qgsdataitem.h"
1919
#include "qgsdataitemprovider.h"
2020
#include "qgsdataprovider.h"
21+
#include "qgstaskmanager.h"
2122

2223

2324
/**
@@ -128,5 +129,24 @@ class QgsGeoPackageDataItemProvider : public QgsDataItemProvider
128129
};
129130

130131

132+
class QgsGeoPackageImportTask : public QgsTask
133+
{
134+
Q_OBJECT
135+
136+
public:
137+
138+
QgsGeoPackageImportTask( const QString &desc = QString() ) : QgsTask( desc ) {}
139+
140+
void emitProgressChanged( double progress ) { setProgress( progress ); }
141+
142+
143+
protected:
144+
145+
bool run() override
146+
{
147+
return true;
148+
}
149+
150+
};
131151

132152
#endif // QGSGEOPACKAGEDATAITEMS_H

0 commit comments

Comments
 (0)