Skip to content

Commit

Permalink
[processing] Fix saving outputs to non-file formats
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 23, 2017
1 parent cd0ba91 commit f7a317b
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/core/processing/qgsprocessingutils.cpp
Expand Up @@ -307,9 +307,9 @@ QString QgsProcessingUtils::stringToPythonLiteral( const QString &string )
return s;
}

void parseDestinationString( QString &destination, QString &providerKey, QString &uri, QString &format, QMap<QString, QVariant> &options )
void QgsProcessingUtils::parseDestinationString( QString &destination, QString &providerKey, QString &uri, QString &layerName, QString &format, QMap<QString, QVariant> &options, bool &useWriter )
{
QRegularExpression splitRx( QStringLiteral( "^(.{3,}):(.*)$" ) );
QRegularExpression splitRx( QStringLiteral( "^(.{3,}?):(.*)$" ) );
QRegularExpressionMatch match = splitRx.match( destination );
if ( match.hasMatch() )
{
Expand All @@ -319,9 +319,25 @@ void parseDestinationString( QString &destination, QString &providerKey, QString
providerKey = QStringLiteral( "postgres" );
}
uri = match.captured( 2 );
if ( providerKey == QLatin1String( "ogr" ) )
{
QgsDataSourceUri dsUri( uri );
if ( !dsUri.database().isEmpty() )
{
if ( !dsUri.table().isEmpty() )
{
layerName = dsUri.table();
options.insert( "layerName", layerName );
}
uri = dsUri.database();
}
options.insert( QStringLiteral( "update" ), true );
}
useWriter = false;
}
else
{
useWriter = true;
providerKey = QStringLiteral( "ogr" );
QRegularExpression splitRx( QStringLiteral( "^(.*)\\.(.*?)$" ) );
QRegularExpressionMatch match = splitRx.match( destination );
Expand Down Expand Up @@ -377,10 +393,12 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, Qgs
{
QString providerKey;
QString uri;
QString layerName;
QString format;
parseDestinationString( destination, providerKey, uri, format, options );
bool useWriter = false;
parseDestinationString( destination, providerKey, uri, layerName, format, options, useWriter );

if ( providerKey == QLatin1String( "ogr" ) )
if ( useWriter && providerKey == QLatin1String( "ogr" ) )
{
// use QgsVectorFileWriter for OGR destinations instead of QgsVectorLayerImport, as that allows
// us to use any OGR format which supports feature addition
Expand Down
2 changes: 2 additions & 0 deletions src/core/processing/qgsprocessingutils.h
Expand Up @@ -267,6 +267,8 @@ class CORE_EXPORT QgsProcessingUtils
*/
static QgsMapLayer *loadMapLayerFromString( const QString &string );

static void parseDestinationString( QString &destination, QString &providerKey, QString &uri, QString &layerName, QString &format, QMap<QString, QVariant> &options, bool &useWriter );

friend class TestQgsProcessing;

};
Expand Down
63 changes: 63 additions & 0 deletions tests/src/analysis/testqgsprocessing.cpp
Expand Up @@ -380,6 +380,7 @@ class TestQgsProcessing: public QObject
void features();
void uniqueValues();
void createIndex();
void parseDestinationString();
void createFeatureSink();
void parameters();
void algorithmParameters();
Expand Down Expand Up @@ -1207,6 +1208,68 @@ void TestQgsProcessing::createIndex()
QCOMPARE( ids, QList<QgsFeatureId>() << 2 );
}

void TestQgsProcessing::parseDestinationString()
{
QString providerKey;
QString uri;
QString layerName;
QString format;
QVariantMap options;
bool useWriter = false;

// simple shapefile output
QString destination = QStringLiteral( "d:/test.shp" );
QgsProcessingUtils::parseDestinationString( destination, providerKey, uri, layerName, format, options, useWriter );
QCOMPARE( destination, QStringLiteral( "d:/test.shp" ) );
QCOMPARE( providerKey, QStringLiteral( "ogr" ) );
QCOMPARE( uri, QStringLiteral( "d:/test.shp" ) );
QCOMPARE( format, QStringLiteral( "ESRI Shapefile" ) );
QVERIFY( useWriter );

// postgis output
destination = QStringLiteral( "postgis:dbname='db' host=DBHOST port=5432 table=\"calcs\".\"output\" (geom) sql=" );
QgsProcessingUtils::parseDestinationString( destination, providerKey, uri, layerName, format, options, useWriter );
QCOMPARE( providerKey, QStringLiteral( "postgres" ) );
QCOMPARE( uri, QStringLiteral( "dbname='db' host=DBHOST port=5432 table=\"calcs\".\"output\" (geom) sql=" ) );
QVERIFY( !useWriter );
// postgres key should also work
destination = QStringLiteral( "postgres:dbname='db' host=DBHOST port=5432 table=\"calcs\".\"output\" (geom) sql=" );
QgsProcessingUtils::parseDestinationString( destination, providerKey, uri, layerName, format, options, useWriter );
QCOMPARE( providerKey, QStringLiteral( "postgres" ) );
QCOMPARE( uri, QStringLiteral( "dbname='db' host=DBHOST port=5432 table=\"calcs\".\"output\" (geom) sql=" ) );
QVERIFY( !useWriter );

// full uri shp output
options.clear();
destination = QStringLiteral( "ogr:d:/test.shp" );
QgsProcessingUtils::parseDestinationString( destination, providerKey, uri, layerName, format, options, useWriter );
QCOMPARE( providerKey, QStringLiteral( "ogr" ) );
QCOMPARE( uri, QStringLiteral( "d:/test.shp" ) );
QCOMPARE( options.value( QStringLiteral( "update" ) ).toBool(), true );
QVERIFY( !options.contains( QStringLiteral( "layerName" ) ) );
QVERIFY( !useWriter );

// full uri geopackage output
options.clear();
destination = QStringLiteral( "ogr:d:/test.gpkg" );
QgsProcessingUtils::parseDestinationString( destination, providerKey, uri, layerName, format, options, useWriter );
QCOMPARE( providerKey, QStringLiteral( "ogr" ) );
QCOMPARE( uri, QStringLiteral( "d:/test.gpkg" ) );
QCOMPARE( options.value( QStringLiteral( "update" ) ).toBool(), true );
QVERIFY( !options.contains( QStringLiteral( "layerName" ) ) );
QVERIFY( !useWriter );

// full uri geopackage table output with layer name
options.clear();
destination = QStringLiteral( "ogr:dbname='d:/package.gpkg' table=\"mylayer\" (geom) sql=" );
QgsProcessingUtils::parseDestinationString( destination, providerKey, uri, layerName, format, options, useWriter );
QCOMPARE( providerKey, QStringLiteral( "ogr" ) );
QCOMPARE( uri, QStringLiteral( "d:/package.gpkg" ) );
QCOMPARE( options.value( QStringLiteral( "update" ) ).toBool(), true );
QCOMPARE( options.value( QStringLiteral( "layerName" ) ).toString(), QStringLiteral( "mylayer" ) );
QVERIFY( !useWriter );
}

void TestQgsProcessing::createFeatureSink()
{
QgsProcessingContext context;
Expand Down

0 comments on commit f7a317b

Please sign in to comment.