mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-15 00:04:37 -04:00
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.
This commit is contained in:
parent
2cf2ad25b4
commit
9c67560b0c
@ -28,6 +28,7 @@
|
|||||||
#include "qgsmessageoutput.h"
|
#include "qgsmessageoutput.h"
|
||||||
#include "qgsvectorlayerexporter.h"
|
#include "qgsvectorlayerexporter.h"
|
||||||
#include "qgsgeopackagerasterwritertask.h"
|
#include "qgsgeopackagerasterwritertask.h"
|
||||||
|
#include "qgstaskmanager.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
@ -191,6 +192,10 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
|
|||||||
QStringList importResults;
|
QStringList importResults;
|
||||||
bool hasError = false;
|
bool hasError = false;
|
||||||
|
|
||||||
|
// Main task
|
||||||
|
std::unique_ptr< QgsGeoPackageImportTask > mainTask( new QgsGeoPackageImportTask( tr( "GeoPackage import" ) ) );
|
||||||
|
QgsTaskList importTasks;
|
||||||
|
|
||||||
const auto lst = QgsMimeDataUtils::decodeUriList( data );
|
const auto lst = QgsMimeDataUtils::decodeUriList( data );
|
||||||
for ( const QgsMimeDataUtils::Uri &dropUri : lst )
|
for ( const QgsMimeDataUtils::Uri &dropUri : lst )
|
||||||
{
|
{
|
||||||
@ -252,10 +257,11 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
|
|||||||
options.insert( QStringLiteral( "update" ), true );
|
options.insert( QStringLiteral( "update" ), true );
|
||||||
options.insert( QStringLiteral( "overwrite" ), true );
|
options.insert( QStringLiteral( "overwrite" ), true );
|
||||||
options.insert( QStringLiteral( "layerName" ), dropUri.name );
|
options.insert( QStringLiteral( "layerName" ), dropUri.name );
|
||||||
|
QgsVectorLayerExporterTask *exportTask = new QgsVectorLayerExporterTask( vectorSrcLayer, uri, QStringLiteral( "ogr" ), vectorSrcLayer->crs(), options, owner ) ;
|
||||||
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( vectorSrcLayer, uri, QStringLiteral( "ogr" ), vectorSrcLayer->crs(), options, owner ) );
|
mainTask->addSubTask( exportTask, importTasks );
|
||||||
|
importTasks << exportTask;
|
||||||
// when export is successful:
|
// when export is successful:
|
||||||
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()
|
connect( exportTask, &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()
|
||||||
{
|
{
|
||||||
// this is gross - TODO - find a way to get access to messageBar from data items
|
// this is gross - TODO - find a way to get access to messageBar from data items
|
||||||
QMessageBox::information( nullptr, tr( "Import to GeoPackage database" ), tr( "Import was successful." ) );
|
QMessageBox::information( nullptr, tr( "Import to GeoPackage database" ), tr( "Import was successful." ) );
|
||||||
@ -263,7 +269,7 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
// when an error occurs:
|
// when an error occurs:
|
||||||
connect( exportTask.get(), &QgsVectorLayerExporterTask::errorOccurred, this, [ = ]( int error, const QString & errorMessage )
|
connect( exportTask, &QgsVectorLayerExporterTask::errorOccurred, this, [ = ]( int error, const QString & errorMessage )
|
||||||
{
|
{
|
||||||
if ( error != QgsVectorLayerExporter::ErrUserCanceled )
|
if ( error != QgsVectorLayerExporter::ErrUserCanceled )
|
||||||
{
|
{
|
||||||
@ -274,14 +280,14 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QgsApplication::taskManager()->addTask( exportTask.release() );
|
|
||||||
}
|
}
|
||||||
else // Import raster
|
else // Import raster
|
||||||
{
|
{
|
||||||
|
QgsGeoPackageRasterWriterTask *exportTask = new QgsGeoPackageRasterWriterTask( dropUri, mPath ) ;
|
||||||
std::unique_ptr< QgsGeoPackageRasterWriterTask > exportTask( new QgsGeoPackageRasterWriterTask( dropUri, mPath ) );
|
mainTask->addSubTask( exportTask, importTasks );
|
||||||
|
importTasks << exportTask;
|
||||||
// when export is successful:
|
// when export is successful:
|
||||||
connect( exportTask.get(), &QgsGeoPackageRasterWriterTask::writeComplete, this, [ = ]()
|
connect( exportTask, &QgsGeoPackageRasterWriterTask::writeComplete, this, [ = ]()
|
||||||
{
|
{
|
||||||
// this is gross - TODO - find a way to get access to messageBar from data items
|
// this is gross - TODO - find a way to get access to messageBar from data items
|
||||||
QMessageBox::information( nullptr, tr( "Import to GeoPackage database" ), tr( "Import was successful." ) );
|
QMessageBox::information( nullptr, tr( "Import to GeoPackage database" ), tr( "Import was successful." ) );
|
||||||
@ -289,7 +295,7 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
// when an error occurs:
|
// when an error occurs:
|
||||||
connect( exportTask.get(), &QgsGeoPackageRasterWriterTask::errorOccurred, this, [ = ]( QgsGeoPackageRasterWriter::WriterError error, const QString & errorMessage )
|
connect( exportTask, &QgsGeoPackageRasterWriterTask::errorOccurred, this, [ = ]( QgsGeoPackageRasterWriter::WriterError error, const QString & errorMessage )
|
||||||
{
|
{
|
||||||
if ( error != QgsGeoPackageRasterWriter::WriterError::ErrUserCanceled )
|
if ( error != QgsGeoPackageRasterWriter::WriterError::ErrUserCanceled )
|
||||||
{
|
{
|
||||||
@ -304,7 +310,6 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
|
|||||||
deleteGeoPackageRasterLayer( QStringLiteral( "GPKG:%1:%2" ).arg( mPath, dropUri.name ), deleteErr );
|
deleteGeoPackageRasterLayer( QStringLiteral( "GPKG:%1:%2" ).arg( mPath, dropUri.name ), deleteErr );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QgsApplication::taskManager()->addTask( exportTask.release() );
|
|
||||||
}
|
}
|
||||||
} // do not overwrite
|
} // do not overwrite
|
||||||
}
|
}
|
||||||
@ -323,6 +328,10 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
|
|||||||
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( QStringLiteral( "\n" ) ), QgsMessageOutput::MessageText );
|
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( QStringLiteral( "\n" ) ), QgsMessageOutput::MessageText );
|
||||||
output->showMessage();
|
output->showMessage();
|
||||||
}
|
}
|
||||||
|
else if ( ! importTasks.isEmpty() )
|
||||||
|
{
|
||||||
|
QgsApplication::taskManager()->addTask( mainTask.release() );
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "qgsdataitem.h"
|
#include "qgsdataitem.h"
|
||||||
#include "qgsdataitemprovider.h"
|
#include "qgsdataitemprovider.h"
|
||||||
#include "qgsdataprovider.h"
|
#include "qgsdataprovider.h"
|
||||||
|
#include "qgstaskmanager.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,5 +129,24 @@ class QgsGeoPackageDataItemProvider : public QgsDataItemProvider
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class QgsGeoPackageImportTask : public QgsTask
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
QgsGeoPackageImportTask( const QString &desc = QString() ) : QgsTask( desc ) {}
|
||||||
|
|
||||||
|
void emitProgressChanged( double progress ) { setProgress( progress ); }
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool run() override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
#endif // QGSGEOPACKAGEDATAITEMS_H
|
#endif // QGSGEOPACKAGEDATAITEMS_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user