Skip to content
Permalink
Browse files

Add field name in layers from postgis relation with multiple spatial …

…fields

NOTE: only works with browser, not with "Add PostGIS Layer" dialog
  • Loading branch information
Sandro Santilli
Sandro Santilli committed May 31, 2013
1 parent b72a79a commit a2774a05cc756ae682c67da09b8c6e99487abfd7
@@ -270,30 +270,39 @@ void QgsPostgresConn::disconnect()
deleteLater();
}

QStringList QgsPostgresConn::pkCandidates( QString schemaName, QString viewName )
/* private */
void QgsPostgresConn::addColumnInfo( QgsPostgresLayerProperty& layerProperty, const QString& schemaName, const QString& viewName, bool fetchPkCandidates )
{
QStringList cols;

QString sql = QString( "SELECT attname FROM pg_attribute JOIN pg_type ON atttypid=pg_type.oid WHERE attrelid=regclass('%1.%2')" )
.arg( quotedIdentifier( schemaName ) )
.arg( quotedIdentifier( viewName ) );
// TODO: optimize this query when pk candidates aren't needed
// could use array_agg() and count()
// array output would look like this: "{One,tWo}"
QString sql = QString( "SELECT attname, CASE WHEN typname = ANY(ARRAY['geometry','geography','topogeometry']) THEN 1 ELSE null END AS isSpatial FROM pg_attribute JOIN pg_type ON atttypid=pg_type.oid WHERE attrelid=regclass('%1.%2')" )
.arg( quotedIdentifier( schemaName ) )
.arg( quotedIdentifier( viewName ) );
QgsDebugMsg( sql );
QgsPostgresResult colRes = PQexec( sql );

layerProperty.nSpCols = 0;

if ( colRes.PQresultStatus() == PGRES_TUPLES_OK )
{
for ( int i = 0; i < colRes.PQntuples(); i++ )
{
QgsDebugMsg( colRes.PQgetvalue( i, 0 ) );
cols << colRes.PQgetvalue( i, 0 );
if ( fetchPkCandidates ) {
QgsDebugMsg( colRes.PQgetvalue( i, 0 ) );
layerProperty.pkCols << colRes.PQgetvalue( i, 0 );
}

if ( colRes.PQgetisnull( i, 1 ) == 0 ) {
++layerProperty.nSpCols;
}
}
}
else
{
QgsMessageLog::logMessage( tr( "SQL:%1\nresult:%2\nerror:%3\n" ).arg( sql ).arg( colRes.PQresultStatus() ).arg( colRes.PQresultErrorMessage() ), tr( "PostGIS" ) );
}

return cols;
}

bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables )
@@ -404,15 +413,12 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
layerProperty.types = QList<QGis::WkbType>() << ( QgsPostgresConn::wkbTypeFromPostgis( type ) );
layerProperty.srids = QList<int>() << srid;
layerProperty.sql = "";
addColumnInfo( layerProperty, schemaName, tableName, relkind == "v" );

if ( relkind == "v" )
if ( relkind == "v" && layerProperty.pkCols.empty() )
{
layerProperty.pkCols = pkCandidates( schemaName, tableName );
if ( layerProperty.pkCols.isEmpty() )
{
QgsDebugMsg( "no key columns found." );
continue;
}
QgsDebugMsg( "no key columns found." );
continue;
}

mLayersSupported << layerProperty;
@@ -522,14 +528,11 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
Q_ASSERT( !"Unknown geometry type" );
}

if ( relkind == "v" )
addColumnInfo( layerProperty, schemaName, tableName, relkind == "v" );
if ( relkind == "v" && layerProperty.pkCols.empty() )
{
layerProperty.pkCols = pkCandidates( schemaName, tableName );
if ( layerProperty.pkCols.isEmpty() )
{
QgsDebugMsg( "no key columns found." );
continue;
}
QgsDebugMsg( "no key columns found." );
continue;
}

layerProperty.sql = "";
@@ -583,7 +586,7 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
layerProperty.tableName = table;
layerProperty.geometryColName = QString::null;
layerProperty.geometryColType = sctNone;
layerProperty.pkCols = relkind == "v" ? pkCandidates( schema, table ) : QStringList();
addColumnInfo( layerProperty, schema, table, relkind == "v" );
layerProperty.sql = "";

mLayersSupported << layerProperty;
@@ -53,10 +53,19 @@ struct QgsPostgresLayerProperty
QgsPostgresGeometryColumnType geometryColType;
QStringList pkCols;
QList<int> srids;
unsigned int nSpCols;
QString sql;


// TODO: rename this !
int size() const { Q_ASSERT( types.size() == srids.size() ); return types.size(); }

QString defaultName() const {
QString n = tableName;
if ( nSpCols > 1 ) n += "." + geometryColName;
return n;
}

QgsPostgresLayerProperty at( int i ) const
{
QgsPostgresLayerProperty property;
@@ -70,6 +79,7 @@ struct QgsPostgresLayerProperty
property.geometryColName = geometryColName;
property.geometryColType = geometryColType;
property.pkCols = pkCols;
property.nSpCols = nSpCols;
property.sql = sql;

return property;
@@ -93,14 +103,15 @@ struct QgsPostgresLayerProperty
sridString += QString::number( srid );
}

return QString( "%1.%2.%3 type=%4 srid=%5 pkCols=%6 sql=%7" )
return QString( "%1.%2.%3 type=%4 srid=%5 pkCols=%6 sql=%7 nSpCols=%8" )
.arg( schemaName )
.arg( tableName )
.arg( geometryColName )
.arg( typeString )
.arg( sridString )
.arg( pkCols.join( "|" ) )
.arg( sql );
.arg( sql )
.arg( nSpCols );
}
#endif
};
@@ -215,9 +226,6 @@ class QgsPostgresConn : public QObject
/** Gets information about the spatial tables */
bool getTableInfo( bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables );

/** get primary key candidates (all int4 columns) */
QStringList pkCandidates( QString schemaName, QString viewName );

qint64 getBinaryInt( QgsPostgresResult &queryResult, int row, int col );

QString fieldExpression( const QgsField &fld );
@@ -292,6 +300,9 @@ class QgsPostgresConn : public QObject
static QMap<QString, QgsPostgresConn *> sConnectionsRW;
static QMap<QString, QgsPostgresConn *> sConnectionsRO;

/** count number of spatial columns in a given relation */
void addColumnInfo( QgsPostgresLayerProperty& layerProperty, const QString& schemaName, const QString& viewName, bool fetchPkCandidates );

//! List of the supported layers
QVector<QgsPostgresLayerProperty> mLayersSupported;

@@ -375,7 +375,7 @@ void QgsPGSchemaItem::addLayer( QgsPostgresLayerProperty layerProperty )
tip = tr( "as geometryless table" );
}

QgsPGLayerItem *layerItem = new QgsPGLayerItem( this, layerProperty.tableName, mPath + "/" + layerProperty.tableName, layerType, layerProperty );
QgsPGLayerItem *layerItem = new QgsPGLayerItem( this, layerProperty.defaultName(), mPath + "/" + layerProperty.tableName, layerType, layerProperty );
layerItem->setToolTip( tip );
addChild( layerItem );
}

0 comments on commit a2774a0

Please sign in to comment.
You can’t perform that action at this time.