Skip to content

Commit 1b1b238

Browse files
committed
Fix extraction of ogr LayerName from multi-layer dataset URIs
Adds supports for "layerid" when present. Drop special handling for "table=" portions found in URI, making the code more generic. Includes testcase. Fixes #15698 - import geodatabase to postgis via processing
1 parent 992995c commit 1b1b238

File tree

2 files changed

+78
-14
lines changed

2 files changed

+78
-14
lines changed

python/plugins/processing/tests/ToolsTest.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,67 @@
3131
from qgis.core import (QgsVectorLayer, QgsFeatureRequest)
3232
from processing.core.ProcessingConfig import ProcessingConfig
3333

34+
import os.path
35+
import errno
36+
import shutil
37+
38+
dataFolder = os.path.join(os.path.dirname(__file__), '../../../../tests/testdata/')
39+
tmpBaseFolder = os.path.join(os.sep, 'tmp', 'qgis_test', str(os.getpid()))
40+
41+
42+
def mkDirP(path):
43+
try:
44+
os.makedirs(path)
45+
except OSError as exc:
46+
if exc.errno == errno.EEXIST and os.path.isdir(path):
47+
pass
48+
else:
49+
raise
50+
3451
start_app()
3552

3653

3754
class VectorTest(unittest.TestCase):
3855

56+
@classmethod
57+
def setUpClass(cls):
58+
mkDirP(tmpBaseFolder)
59+
60+
@classmethod
61+
def tearDownClass(cls):
62+
shutil.rmtree(tmpBaseFolder)
63+
pass
64+
65+
# See http://hub.qgis.org/issues/15698
66+
def test_ogrLayerName(self):
67+
tmpdir = os.path.join(tmpBaseFolder, 'ogrLayerName')
68+
os.mkdir(tmpdir)
69+
70+
def linkTestfile(f, t):
71+
os.link(os.path.join(dataFolder, f), os.path.join(tmpdir, t))
72+
73+
linkTestfile('geom_data.csv', 'a.csv')
74+
name = vector.ogrLayerName(tmpdir)
75+
self.assertEqual(name, 'a')
76+
77+
linkTestfile('wkt_data.csv', 'b.csv')
78+
name = vector.ogrLayerName(tmpdir + '|layerid=0')
79+
self.assertEqual(name, 'a')
80+
name = vector.ogrLayerName(tmpdir + '|layerid=1')
81+
self.assertEqual(name, 'b')
82+
83+
name = vector.ogrLayerName(tmpdir + '|layerid=2')
84+
self.assertEqual(name, 'invalid-layerid')
85+
86+
name = vector.ogrLayerName(tmpdir + '|layername=f')
87+
self.assertEqual(name, 'f') # layername takes precedence
88+
89+
name = vector.ogrLayerName(tmpdir + '|layerid=0|layername=f2')
90+
self.assertEqual(name, 'f2') # layername takes precedence
91+
92+
name = vector.ogrLayerName(tmpdir + '|layername=f2|layerid=0')
93+
self.assertEqual(name, 'f2') # layername takes precedence
94+
3995
def testFeatures(self):
4096
ProcessingConfig.initialize()
4197

python/plugins/processing/tools/vector.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
import psycopg2
3636

37+
from osgeo import ogr
38+
3739
from qgis.PyQt.QtCore import QVariant, QSettings
3840
from qgis.core import (QGis, QgsFields, QgsField, QgsGeometry, QgsRectangle,
3941
QgsSpatialIndex, QgsMapLayerRegistry, QgsMapLayer, QgsVectorLayer,
@@ -509,20 +511,26 @@ def ogrConnectionString(uri):
509511

510512

511513
def ogrLayerName(uri):
512-
if 'host' in uri:
513-
regex = re.compile('(table=")(.+?)(\.)(.+?)"')
514-
r = regex.search(uri)
515-
return '"' + r.groups()[1] + '.' + r.groups()[3] + '"'
516-
elif 'dbname' in uri:
517-
regex = re.compile('(table=")(.+?)"')
518-
r = regex.search(uri)
519-
return r.groups()[1]
520-
elif 'layername' in uri:
521-
regex = re.compile('(layername=)(.*)')
522-
r = regex.search(uri)
523-
return r.groups()[1]
524-
else:
525-
return os.path.basename(os.path.splitext(uri)[0])
514+
fields = uri.split('|')
515+
ogruri = fields[0]
516+
fields = fields[1:]
517+
layerid = 0
518+
for f in fields:
519+
if f.startswith('layername='):
520+
# Name encoded in uri, nothing more needed
521+
return f.split('=')[1]
522+
if f.startswith('layerid='):
523+
layerid = int(f.split('=')[1])
524+
# Last layerid= takes precedence, to allow of layername to
525+
# take precedence
526+
ds = ogr.Open(ogruri)
527+
if not ds:
528+
return "invalid-uri"
529+
ly = ds.GetLayer(layerid)
530+
if not ly:
531+
return "invalid-layerid"
532+
name = ly.GetName()
533+
return name
526534

527535

528536
class VectorWriter:

0 commit comments

Comments
 (0)