Skip to content

Commit 8843de8

Browse files
committed
Fix ogrLayerName handling of PostgreSQL dataset URIs
Also document "uri" parameter semantic, and add more tests. See for background https://lists.osgeo.org/pipermail/qgis-developer/2016-October/045311.html REF #15698
1 parent 743a5cd commit 8843de8

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

python/plugins/processing/tests/ToolsTest.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,33 +70,41 @@ def test_ogrLayerName(self):
7070
def linkTestfile(f, t):
7171
os.link(os.path.join(dataFolder, f), os.path.join(tmpdir, t))
7272

73+
# URI from OGR provider
7374
linkTestfile('geom_data.csv', 'a.csv')
7475
name = vector.ogrLayerName(tmpdir)
7576
self.assertEqual(name, 'a')
7677

78+
# URI from OGR provider
7779
linkTestfile('wkt_data.csv', 'b.csv')
7880
name = vector.ogrLayerName(tmpdir + '|layerid=0')
7981
self.assertEqual(name, 'a')
8082
name = vector.ogrLayerName(tmpdir + '|layerid=1')
8183
self.assertEqual(name, 'b')
8284

85+
# URI from OGR provider
8386
name = vector.ogrLayerName(tmpdir + '|layerid=2')
8487
self.assertEqual(name, 'invalid-layerid')
8588

89+
# URI from OGR provider
8690
name = vector.ogrLayerName(tmpdir + '|layername=f')
8791
self.assertEqual(name, 'f') # layername takes precedence
8892

93+
# URI from OGR provider
8994
name = vector.ogrLayerName(tmpdir + '|layerid=0|layername=f2')
9095
self.assertEqual(name, 'f2') # layername takes precedence
9196

97+
# URI from OGR provider
9298
name = vector.ogrLayerName(tmpdir + '|layername=f2|layerid=0')
9399
self.assertEqual(name, 'f2') # layername takes precedence
94100

101+
# URI from Sqlite provider
95102
name = vector.ogrLayerName('dbname=\'/tmp/x.sqlite\' table="t" (geometry) sql=')
96103
self.assertEqual(name, 't')
97104

98-
name = vector.ogrLayerName('dbname=\'/tmp/x.sqlite\' table="s.t" (geometry) sql=')
99-
self.assertEqual(name, 's.t')
105+
# URI from PostgreSQL provider
106+
name = vector.ogrLayerName('port=5493 sslmode=disable key=\'edge_id\' srid=0 type=LineString table="city_data"."edge" (geom) sql=')
107+
self.assertEqual(name, 'city_data.edge')
100108

101109
def testFeatures(self):
102110
ProcessingConfig.initialize()

python/plugins/processing/tools/vector.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -532,16 +532,43 @@ def ogrConnectionString(uri):
532532
return '"' + ogrstr + '"'
533533

534534

535+
#
536+
# The uri parameter is an URI from any QGIS provider,
537+
# so could have different formats.
538+
# Example formats:
539+
#
540+
# -- PostgreSQL provider
541+
# port=5493 sslmode=disable key='edge_id' srid=0 type=LineString table="city_data"."edge" (geom) sql=
542+
#
543+
# -- Spatialite provider
544+
# dbname='/tmp/x.sqlite' table="t" (geometry) sql='
545+
#
546+
# -- OGR provider (single-layer directory)
547+
# /tmp/x.gdb
548+
#
549+
# -- OGR provider (multi-layer directory)
550+
# /tmp/x.gdb|layerid=1
551+
#
552+
# -- OGR provider (multi-layer directory)
553+
# /tmp/x.gdb|layername=thelayer
554+
#
535555
def ogrLayerName(uri):
536-
if 'host' in uri:
537-
regex = re.compile('table="(.+?)\.(.+?)"')
538-
r = regex.search(uri)
539-
return '"' + r.groups()[0] + '.' + r.groups()[1] + '"'
540-
elif 'dbname' in uri:
541-
regex = re.compile('table="(.+?)"')
542-
r = regex.search(uri)
543-
return r.groups()[0]
544-
elif 'layername' in uri:
556+
557+
# handle URIs of database providers
558+
if ' table=' in uri:
559+
# Matches table="schema"."table"
560+
re_table_schema = re.compile(' table="([^"]*)"\."([^"]*)"')
561+
r = re_table_schema.search(uri)
562+
if r:
563+
return r.groups()[0] + '.' + r.groups()[1]
564+
# Matches table="table"
565+
re_table = re.compile(' table="([^"]*)"')
566+
r = re_table.search(uri)
567+
if r:
568+
return r.groups()[0]
569+
570+
# handle URIs of OGR provider with explicit layername
571+
if 'layername' in uri:
545572
regex = re.compile('(layername=)([^|]*)')
546573
r = regex.search(uri)
547574
return r.groups()[1]

0 commit comments

Comments
 (0)