mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	Fix QgsVectorLayerExporter fails when provider launders layer name
Eg dropping a layer with spaces in its name onto a ESRI FileGeodatabase in the browser
This commit is contained in:
		
							parent
							
								
									9e8be2679a
								
							
						
					
					
						commit
						03174af446
					
				@ -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" ) )
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										88
									
								
								tests/src/python/test_qgsvectorlayerexporter.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								tests/src/python/test_qgsvectorlayerexporter.py
									
									
									
									
									
										Normal file
									
								
							@ -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()
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user