Showing with 40 additions and 4 deletions.
  1. +4 −1 src/providers/postgres/qgspostgresconn.h
  2. +29 −2 src/providers/postgres/qgspostgresprovider.cpp
  3. +7 −1 src/providers/postgres/qgspostgresprovider.h
5 changes: 4 additions & 1 deletion src/providers/postgres/qgspostgresconn.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,12 @@ class QgsPostgresConn : public QObject
//! encode wkb in hex
bool useWkbHex() { return mUseWkbHex; }

//! major PostgreSQL version
//! major PostGIS version
int majorVersion() { return mPostgisVersionMajor; }

//! minor PostGIS version
int minorVersion() { return mPostgisVersionMinor; }

//! PostgreSQL version
int pgVersion() { return mPostgresqlVersion; }

Expand Down
31 changes: 29 additions & 2 deletions src/providers/postgres/qgspostgresprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,23 @@ bool QgsPostgresProvider::getTopoLayerInfo( )
return true;
}

/* private */
void QgsPostgresProvider::dropOrphanedTopoGeoms( )
{
QString sql = QString( "DELETE FROM %1.relation WHERE layer_id = %2 AND "
"topogeo_id NOT IN ( SELECT id(%3) FROM %4.%5 )" )
.arg( quotedIdentifier(mTopoLayerInfo.topologyName) )
.arg( mTopoLayerInfo.layerId )
.arg( quotedIdentifier(mGeometryColumn) )
.arg( quotedIdentifier(mSchemaName) )
.arg( quotedIdentifier(mTableName) )
;

QgsDebugMsg( "TopoGeom orphans cleanup query: " + sql );

mConnectionRW->PQexecNR( sql );
}

QString QgsPostgresProvider::geomParam( int offset ) const
{
QString geometry;
Expand Down Expand Up @@ -2192,6 +2209,18 @@ bool QgsPostgresProvider::deleteFeatures( const QgsFeatureIds & id )

mConnectionRW->PQexecNR( "COMMIT" );

if ( mSpatialColType == sctTopoGeometry )
{
// NOTE: in presence of multiple TopoGeometry objects
// for the same table or when deleting a Geometry
// layer _also_ having a TopoGeometry component,
// orphans would still be left.
// TODO: decouple layer from table and signal table when
// records are added or removed
dropOrphanedTopoGeoms();
}


mFeaturesCounted -= id.size();
}
catch ( PGException &e )
Expand Down Expand Up @@ -2574,8 +2603,6 @@ bool QgsPostgresProvider::changeGeometryValues( QgsGeometryMap & geometry_map )
// Replace old TopoGeom with new TopoGeom, so that
// any hierarchically defined TopoGeom will still have its
// definition and we'll leave no orphans
// TODO: move this logic into a method using mTopoLayerInfo and
// taking a topogeo_id (to be reused for deleteFeatures)
QString replace = QString( "DELETE FROM %1.relation WHERE "
"layer_id = %2 AND topogeo_id = %3" )
.arg( quotedIdentifier( mTopoLayerInfo.topologyName ) )
Expand Down
8 changes: 7 additions & 1 deletion src/providers/postgres/qgspostgresprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -437,16 +437,22 @@ class QgsPostgresProvider : public QgsVectorDataProvider

bool getGeometryDetails();

//! @{ Only used with TopoGeometry layers

struct TopoLayerInfo
{
QString topologyName;
long layerId;
};

TopoLayerInfo mTopoLayerInfo; //! only used with TopoGeometry layers
TopoLayerInfo mTopoLayerInfo;

bool getTopoLayerInfo();

void dropOrphanedTopoGeoms();

//! @}

/* Use estimated metadata. Uses fast table counts, geometry type and extent determination */
bool mUseEstimatedMetadata;

Expand Down