Skip to content

Commit bfa124f

Browse files
author
Sandro Santilli
committed
Fetch topological layer info at construction time
Simplify addFeatures and changeGeometryValues accordingly
1 parent 5e64c64 commit bfa124f

File tree

2 files changed

+60
-44
lines changed

2 files changed

+60
-44
lines changed

src/providers/postgres/qgspostgresprovider.cpp

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,16 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )
125125
return;
126126
}
127127

128+
if ( mSpatialColType == sctTopoGeometry )
129+
{
130+
if ( !getTopoLayerInfo() ) // gets topology name and layer id
131+
{
132+
QgsMessageLog::logMessage( tr( "invalid PostgreSQL topology layer" ), tr( "PostGIS" ) );
133+
disconnectDb();
134+
return;
135+
}
136+
}
137+
128138
mLayerExtent.setMinimal();
129139
mFeaturesCounted = -1;
130140

@@ -1817,38 +1827,38 @@ QString QgsPostgresProvider::paramValue( QString fieldValue, const QString &defa
18171827
return fieldValue;
18181828
}
18191829

1820-
QString QgsPostgresProvider::geomParam( int offset ) const
1821-
{
1822-
// TODO: retrieve these at construction time
1823-
QString toponame;
1824-
long layer_id;
18251830

1826-
if ( mSpatialColType == sctTopoGeometry )
1831+
/* private */
1832+
bool QgsPostgresProvider::getTopoLayerInfo( )
1833+
{
1834+
QString sql = QString( "SELECT t.name, l.layer_id "
1835+
"FROM topology.layer l, topology.topology t "
1836+
"WHERE l.topology_id = t.id AND l.schema_name=%1 "
1837+
"AND l.table_name=%2 AND l.feature_column=%3" )
1838+
.arg( quotedValue( mSchemaName ) )
1839+
.arg( quotedValue( mTableName ) )
1840+
.arg( quotedValue( mGeometryColumn ) );
1841+
QgsPostgresResult result = mConnectionRO->PQexec( sql );
1842+
if ( result.PQresultStatus() != PGRES_TUPLES_OK )
18271843
{
1828-
QString sql = QString( "SELECT t.name, l.layer_id FROM topology.layer l, topology.topology t "
1829-
"WHERE l.topology_id = t.id AND l.schema_name=%1 "
1830-
"AND l.table_name=%2 AND l.feature_column=%3" )
1831-
.arg( quotedValue( mSchemaName ) )
1832-
.arg( quotedValue( mTableName ) )
1833-
.arg( quotedValue( mGeometryColumn ) );
1834-
QgsPostgresResult result = mConnectionRO->PQexec( sql );
1835-
if ( result.PQresultStatus() != PGRES_TUPLES_OK )
1836-
{
1837-
throw PGException( result ); // we should probably not do this
1838-
}
1839-
if ( result.PQntuples() < 1 )
1840-
{
1841-
QgsMessageLog::logMessage( tr( "Could not find topology of layer %1.%2.%3" )
1842-
.arg( quotedValue( mSchemaName ) )
1843-
.arg( quotedValue( mTableName ) )
1844-
.arg( quotedValue( mGeometryColumn ) ),
1845-
tr( "PostGIS" ) );
1846-
}
1847-
toponame = result.PQgetvalue( 0, 0 );
1848-
layer_id = result.PQgetvalue( 0, 1 ).toLong();
1849-
1844+
throw PGException( result ); // we should probably not do this
1845+
}
1846+
if ( result.PQntuples() < 1 )
1847+
{
1848+
QgsMessageLog::logMessage( tr( "Could not find topology of layer %1.%2.%3" )
1849+
.arg( quotedValue( mSchemaName ) )
1850+
.arg( quotedValue( mTableName ) )
1851+
.arg( quotedValue( mGeometryColumn ) ),
1852+
tr( "PostGIS" ) );
1853+
return false;
18501854
}
1855+
mTopoLayerInfo.topologyName = result.PQgetvalue( 0, 0 );
1856+
mTopoLayerInfo.layerId = result.PQgetvalue( 0, 1 ).toLong();
1857+
return true;
1858+
}
18511859

1860+
QString QgsPostgresProvider::geomParam( int offset ) const
1861+
{
18521862
QString geometry;
18531863

18541864
bool forceMulti = false;
@@ -1903,8 +1913,8 @@ QString QgsPostgresProvider::geomParam( int offset ) const
19031913
if ( mSpatialColType == sctTopoGeometry )
19041914
{
19051915
geometry += QString( ",%1,%2)" )
1906-
.arg( quotedValue( toponame ) )
1907-
.arg( layer_id );
1916+
.arg( quotedValue( mTopoLayerInfo.topologyName ) )
1917+
.arg( mTopoLayerInfo.layerId );
19081918
}
19091919

19101920
return geometry;
@@ -2457,14 +2467,10 @@ bool QgsPostgresProvider::changeGeometryValues( QgsGeometryMap & geometry_map )
24572467
// Later, we'll replace the old TopoGeometry with the new one,
24582468
// to avoid orphans and retain higher level in an eventual
24592469
// hierarchical definition
2460-
update = QString( "WITH tg AS ( SELECT t.name, "
2461-
" toTopoGeom(%3, t.name, layer_id(o.%2)) as tg"
2462-
" FROM %1 o, topology.topology t WHERE t.id = topology_id(o.%2)"
2463-
" AND %4 ) SELECT layer_id(tg.tg), id(tg.tg), tg.name FROM tg" )
2464-
.arg( mQuery )
2465-
.arg( quotedIdentifier( mGeometryColumn ) )
2470+
update = QString( "SELECT id(%1) FROM %2 o WHERE %3" )
24662471
.arg( geomParam( 1 ) )
2467-
.arg( pkParamWhereClause( 2, "o" ) );
2472+
.arg( mQuery )
2473+
.arg( pkParamWhereClause( 2 ) );
24682474

24692475
QString getid = QString( "SELECT id(%1) FROM %2 WHERE %3" )
24702476
.arg( quotedIdentifier( mGeometryColumn ) )
@@ -2563,17 +2569,17 @@ bool QgsPostgresProvider::changeGeometryValues( QgsGeometryMap & geometry_map )
25632569

25642570
if ( mSpatialColType == sctTopoGeometry )
25652571
{
2566-
long layer_id = result.PQgetvalue( 0, 0 ).toLong(); // new layer_id == old layer_id
2567-
long new_tg_id = result.PQgetvalue( 0, 1 ).toLong(); // new topogeo_id
2568-
QString toponame = result.PQgetvalue( 0, 2 ); // new topology name == old topology name
2572+
long new_tg_id = result.PQgetvalue( 0, 0 ).toLong(); // new topogeo_id
25692573

25702574
// Replace old TopoGeom with new TopoGeom, so that
25712575
// any hierarchically defined TopoGeom will still have its
25722576
// definition and we'll leave no orphans
2577+
// TODO: move this logic into a method using mTopoLayerInfo and
2578+
// taking a topogeo_id (to be reused for deleteFeatures)
25732579
QString replace = QString( "DELETE FROM %1.relation WHERE "
25742580
"layer_id = %2 AND topogeo_id = %3" )
2575-
.arg( quotedIdentifier( toponame ) )
2576-
.arg( layer_id )
2581+
.arg( quotedIdentifier( mTopoLayerInfo.topologyName ) )
2582+
.arg( mTopoLayerInfo.layerId )
25772583
.arg( old_tg_id );
25782584
result = mConnectionRW->PQexec( replace );
25792585
if ( result.PQresultStatus() != PGRES_COMMAND_OK )
@@ -2585,9 +2591,9 @@ bool QgsPostgresProvider::changeGeometryValues( QgsGeometryMap & geometry_map )
25852591
// TODO: use prepared query here
25862592
replace = QString( "UPDATE %1.relation SET topogeo_id = %2 "
25872593
"WHERE layer_id = %3 AND topogeo_id = %4" )
2588-
.arg( quotedIdentifier( toponame ) )
2594+
.arg( quotedIdentifier( mTopoLayerInfo.topologyName ) )
25892595
.arg( old_tg_id )
2590-
.arg( layer_id )
2596+
.arg( mTopoLayerInfo.layerId )
25912597
.arg( new_tg_id );
25922598
QgsDebugMsg( "relation swap: " + replace );
25932599
result = mConnectionRW->PQexec( replace );

src/providers/postgres/qgspostgresprovider.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,16 @@ class QgsPostgresProvider : public QgsVectorDataProvider
437437

438438
bool getGeometryDetails();
439439

440+
struct TopoLayerInfo
441+
{
442+
QString topologyName;
443+
long layerId;
444+
};
445+
446+
TopoLayerInfo mTopoLayerInfo; //! only used with TopoGeometry layers
447+
448+
bool getTopoLayerInfo();
449+
440450
/* Use estimated metadata. Uses fast table counts, geometry type and extent determination */
441451
bool mUseEstimatedMetadata;
442452

0 commit comments

Comments
 (0)