diff --git a/src/core/vector/qgsvectorlayerexporter.cpp b/src/core/vector/qgsvectorlayerexporter.cpp index d78143821f5..23f9ac57154 100644 --- a/src/core/vector/qgsvectorlayerexporter.cpp +++ b/src/core/vector/qgsvectorlayerexporter.cpp @@ -107,9 +107,9 @@ QgsVectorLayerExporter::QgsVectorLayerExporter( const QString &uri, // create an empty layer QString errMsg; QgsProviderRegistry *pReg = QgsProviderRegistry::instance(); - QString createdLayerName; + QString uriUpdated; mError = pReg->createEmptyLayer( providerKey, uri, fields, geometryType, crs, overwrite, mOldToNewAttrIdx, - errMsg, !modifiedOptions.isEmpty() ? &modifiedOptions : nullptr, createdLayerName ); + errMsg, !modifiedOptions.isEmpty() ? &modifiedOptions : nullptr, uriUpdated ); if ( errorCode() != Qgis::VectorExportResult::Success ) { @@ -128,20 +128,6 @@ QgsVectorLayerExporter::QgsVectorLayerExporter( const QString &uri, QgsDebugMsgLevel( QStringLiteral( "Created empty layer" ), 2 ); - QString uriUpdated( uri ); - // HACK sorry... - if ( providerKey == QLatin1String( "ogr" ) ) - { - QString layerName; - if ( options.contains( QStringLiteral( "layerName" ) ) ) - layerName = options.value( QStringLiteral( "layerName" ) ).toString(); - if ( !layerName.isEmpty() ) - { - uriUpdated += QLatin1String( "|layername=" ); - uriUpdated += layerName; - } - } - // Oracle specific HACK: we cannot guess the geometry type when there is no rows, so we need // to force it in the uri if ( providerKey == QLatin1String( "oracle" ) ) diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index 9fda298159c..d355fa1d08e 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -375,6 +375,7 @@ ADD_PYTHON_TEST(PyQgsVectorLayerCache test_qgsvectorlayercache.py) ADD_PYTHON_TEST(PyQgsVectorLayerEditBuffer test_qgsvectorlayereditbuffer.py) ADD_PYTHON_TEST(PyQgsVectorLayerEditBufferGroup test_qgsvectorlayereditbuffergroup.py) ADD_PYTHON_TEST(PyQgsVectorLayerEditUtils test_qgsvectorlayereditutils.py) +ADD_PYTHON_TEST(PyQgsVectorLayerExporter test_qgsvectorlayerexporter.py) ADD_PYTHON_TEST(PyQgsVectorLayerNamedStyle test_qgsvectorlayer_namedstyle.py) ADD_PYTHON_TEST(PyQgsVectorLayerProfileGenerator test_qgsvectorlayerprofilegenerator.py) ADD_PYTHON_TEST(PyQgsVectorLayerRenderer test_qgsvectorlayerrenderer.py) diff --git a/tests/src/python/test_qgsvectorlayerexporter.py b/tests/src/python/test_qgsvectorlayerexporter.py new file mode 100644 index 00000000000..681e3ee8417 --- /dev/null +++ b/tests/src/python/test_qgsvectorlayerexporter.py @@ -0,0 +1,88 @@ +"""QGIS Unit tests for QgsVectorLayerExporter. + +.. note:: 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. +""" + +import tempfile +import unittest +from pathlib import Path + +import osgeo.gdal # NOQA +from osgeo import gdal, ogr +from qgis.core import ( + Qgis, + QgsVectorLayerExporter, + QgsFeature, + QgsGeometry, + QgsPointXY, + QgsVectorLayer, +) +from qgis.testing import start_app, QgisTestCase + +from utilities import unitTestDataPath + +TEST_DATA_DIR = unitTestDataPath() +start_app() + + +def GDAL_COMPUTE_VERSION(maj, min, rev): + return (maj) * 1000000 + (min) * 10000 + (rev) * 100 + + +class TestQgsVectorLayerExporter(QgisTestCase): + + @unittest.skipIf( + int(gdal.VersionInfo("VERSION_NUM")) < GDAL_COMPUTE_VERSION(3, 8, 0), + "GDAL 3.8 required", + ) + def test_write_laundered_table_names(self): + """ + Test exporting layer name with spaces to File Geodatabase, the name + should be laundered but things should still work + """ + with tempfile.TemporaryDirectory() as temp_dir: + dest_file_name = Path(temp_dir) / "test_export.gdb" + ds = ogr.GetDriverByName("OpenFileGDB").CreateDataSource( + dest_file_name.as_posix() + ) + self.assertIsNotNone(ds) + del ds + + # create a layer to export + layer = QgsVectorLayer( + "Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory" + ) + self.assertTrue(layer.isValid()) + pr = layer.dataProvider() + f = QgsFeature() + f.setAttributes(["test", 123]) + f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) + f2 = QgsFeature() + f2.setAttributes(["test2", 457]) + f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) + self.assertTrue(pr.addFeatures([f, f2])) + + res, error = QgsVectorLayerExporter.exportLayer( + layer, + dest_file_name.as_posix(), + "ogr", + layer.crs(), + options={"layerName": "Must be Laundered", "update": True}, + ) + self.assertEqual(res, Qgis.VectorExportResult.Success) + + # true to read result + layer = QgsVectorLayer( + dest_file_name.as_posix() + "|layername=Must_be_Laundered", + "test", + "ogr", + ) + self.assertTrue(layer.isValid()) + self.assertEqual(layer.featureCount(), 2) + + +if __name__ == "__main__": + unittest.main()