Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Use relkind everywhere to determine if table is a view
  • Loading branch information
nyalldawson committed Apr 6, 2023
1 parent 8d71d28 commit 84dfaf2
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 34 deletions.
29 changes: 20 additions & 9 deletions src/providers/postgres/qgspgtablemodel.cpp
Expand Up @@ -187,16 +187,27 @@ void QgsPgTableModel::addTableEntry( const QgsPostgresLayerProperty &layerProper
// Legacy: default value is determined by project option to trust layer's metadata
// TODO: remove this default from QGIS 4 and leave default value to false?
// checkPkUnicity has only effect on views and materialized views, so we can safely disable it
if ( layerProperty.isView || layerProperty.relKind == Qgis::PostgresRelKind::MaterializedView )
switch ( layerProperty.relKind )
{
checkPkUnicityItem->setCheckState( ( QgsProject::instance( )->flags() & Qgis::ProjectFlag::TrustStoredLayerStatistics ) ? Qt::CheckState::Unchecked : Qt::CheckState::Checked );
checkPkUnicityItem->setToolTip( headerData( Columns::DbtmCheckPkUnicity, Qt::Orientation::Horizontal, Qt::ToolTipRole ).toString() );
}
else
{
checkPkUnicityItem->setCheckState( Qt::CheckState::Unchecked );
checkPkUnicityItem->setFlags( checkPkUnicityItem->flags() & ~ Qt::ItemIsEnabled );
checkPkUnicityItem->setToolTip( tr( "This option is only available for views and materialized views." ) );
case Qgis::PostgresRelKind::View:
case Qgis::PostgresRelKind::MaterializedView:
checkPkUnicityItem->setCheckState( ( QgsProject::instance( )->flags() & Qgis::ProjectFlag::TrustStoredLayerStatistics ) ? Qt::CheckState::Unchecked : Qt::CheckState::Checked );
checkPkUnicityItem->setToolTip( headerData( Columns::DbtmCheckPkUnicity, Qt::Orientation::Horizontal, Qt::ToolTipRole ).toString() );
break;

case Qgis::PostgresRelKind::NotSet:
case Qgis::PostgresRelKind::Unknown:
case Qgis::PostgresRelKind::OrdinaryTable:
case Qgis::PostgresRelKind::Index:
case Qgis::PostgresRelKind::Sequence:
case Qgis::PostgresRelKind::CompositeType:
case Qgis::PostgresRelKind::ToastTable:
case Qgis::PostgresRelKind::ForeignTable:
case Qgis::PostgresRelKind::PartitionedTable:
checkPkUnicityItem->setCheckState( Qt::CheckState::Unchecked );
checkPkUnicityItem->setFlags( checkPkUnicityItem->flags() & ~ Qt::ItemIsEnabled );
checkPkUnicityItem->setToolTip( tr( "This option is only available for views and materialized views." ) );
break;
}

QStandardItem *sqlItem = new QStandardItem( layerProperty.sql );
Expand Down
25 changes: 14 additions & 11 deletions src/providers/postgres/qgspostgresconn.cpp
Expand Up @@ -712,7 +712,6 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
QString ssrid = result.PQgetvalue( idx, 4 );
int dim = result.PQgetvalue( idx, 5 ).toInt();
QString relkind = result.PQgetvalue( idx, 6 );
bool isView = relkind == QLatin1String( "v" ) || relkind == QLatin1String( "m" );
bool isRaster = type == QLatin1String( "RASTER" );
QString comment = result.PQgetvalue( idx, 7 );
QString attributes = result.PQgetvalue( idx, 8 );
Expand Down Expand Up @@ -767,11 +766,12 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
layerProperty.srids = QList<int>() << srid;
layerProperty.sql.clear();
layerProperty.relKind = relKindFromValue( relkind );
layerProperty.isView = isView;
layerProperty.isRaster = isRaster;
layerProperty.tableComment = comment;
layerProperty.nSpCols = nSpCols;
if ( isView || ( layerProperty.relKind == Qgis::PostgresRelKind::ForeignTable ) )
if ( ( layerProperty.relKind == Qgis::PostgresRelKind::View )
|| ( layerProperty.relKind == Qgis::PostgresRelKind::MaterializedView )
|| ( layerProperty.relKind == Qgis::PostgresRelKind::ForeignTable ) )
{
// TODO: use std::transform
for ( const auto &a : QgsPostgresStringUtils::parseArray( attributes ) )
Expand All @@ -780,7 +780,8 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
}
}

if ( isView && layerProperty.pkCols.empty() )
if ( ( layerProperty.relKind == Qgis::PostgresRelKind::View
|| layerProperty.relKind == Qgis::PostgresRelKind::MaterializedView ) && layerProperty.pkCols.empty() )
{
//QgsDebugMsgLevel( QStringLiteral( "no key columns found." ), 2 );
continue;
Expand Down Expand Up @@ -874,7 +875,6 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
QString column = result.PQgetvalue( i, 2 ); // attname
QString relkind = result.PQgetvalue( i, 3 ); // relation kind
QString coltype = result.PQgetvalue( i, 4 ); // column type
bool isView = relkind == QLatin1String( "v" ) || relkind == QLatin1String( "m" );
QString comment = result.PQgetvalue( i, 5 ); // table comment

QgsPostgresLayerProperty layerProperty;
Expand All @@ -884,7 +884,6 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
layerProperty.tableName = tableName;
layerProperty.geometryColName = column;
layerProperty.relKind = relKindFromValue( relkind );
layerProperty.isView = isView;
layerProperty.isRaster = coltype == QLatin1String( "raster" );
layerProperty.tableComment = comment;
if ( coltype == QLatin1String( "geometry" ) )
Expand Down Expand Up @@ -915,9 +914,13 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP

// TODO: use knowledge from already executed query to count
// spatial fields and list attribute names...
addColumnInfo( layerProperty, schemaName, tableName, isView || ( layerProperty.relKind == Qgis::PostgresRelKind::ForeignTable ) );
addColumnInfo( layerProperty, schemaName, tableName,
layerProperty.relKind == Qgis::PostgresRelKind::View
|| layerProperty.relKind == Qgis::PostgresRelKind::MaterializedView
|| layerProperty.relKind == Qgis::PostgresRelKind::ForeignTable );

if ( isView && layerProperty.pkCols.empty() )
if ( ( layerProperty.relKind == Qgis::PostgresRelKind::View
|| layerProperty.relKind == Qgis::PostgresRelKind::MaterializedView ) && layerProperty.pkCols.empty() )
{
//QgsDebugMsgLevel( QStringLiteral( "no key columns found." ), 2 );
continue;
Expand Down Expand Up @@ -977,7 +980,6 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
QString relkind = result.PQgetvalue( i, 2 ); // relation kind
QString comment = result.PQgetvalue( i, 3 ); // table comment
QString attributes = result.PQgetvalue( i, 4 ); // attributes array
bool isView = relkind == QLatin1String( "v" ) || relkind == QLatin1String( "m" );

QgsPostgresLayerProperty layerProperty;
layerProperty.types = QList<Qgis::WkbType>() << Qgis::WkbType::NoGeometry;
Expand All @@ -988,7 +990,6 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
layerProperty.geometryColType = SctNone;
layerProperty.nSpCols = 0;
layerProperty.relKind = relKindFromValue( relkind );
layerProperty.isView = isView;
layerProperty.isRaster = false;
layerProperty.tableComment = comment;

Expand All @@ -1007,7 +1008,9 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
if ( alreadyFound )
continue;

if ( isView || ( layerProperty.relKind == Qgis::PostgresRelKind::ForeignTable ) )
if ( layerProperty.relKind == Qgis::PostgresRelKind::View
|| layerProperty.relKind == Qgis::PostgresRelKind::MaterializedView
|| layerProperty.relKind == Qgis::PostgresRelKind::ForeignTable )
{
// TODO: use std::transform
for ( const auto &a : QgsPostgresStringUtils::parseArray( attributes ) )
Expand Down
2 changes: 0 additions & 2 deletions src/providers/postgres/qgspostgresconn.h
Expand Up @@ -83,7 +83,6 @@ struct QgsPostgresLayerProperty
unsigned int nSpCols;
QString sql;
Qgis::PostgresRelKind relKind = Qgis::PostgresRelKind::Unknown;
bool isView = false;
bool isRaster = false;
QString tableComment;

Expand Down Expand Up @@ -113,7 +112,6 @@ struct QgsPostgresLayerProperty
property.nSpCols = nSpCols;
property.sql = sql;
property.relKind = relKind;
property.isView = isView;
property.isRaster = isRaster;
property.tableComment = tableComment;

Expand Down
37 changes: 31 additions & 6 deletions src/providers/postgres/qgspostgresdataitemguiprovider.cpp
Expand Up @@ -92,15 +92,15 @@ void QgsPostgresDataItemGuiProvider::populateContextMenu( QgsDataItem *item, QMe
if ( QgsPGLayerItem *layerItem = qobject_cast< QgsPGLayerItem * >( item ) )
{
const QgsPostgresLayerProperty &layerInfo = layerItem->layerInfo();
const QString typeName = layerInfo.isView ? tr( "View" ) : tr( "Table" );
const QString typeName = typeNameFromLayer( layerInfo );

QMenu *maintainMenu = new QMenu( tr( "%1 Operations" ).arg( typeName ), menu );

QAction *actionRenameLayer = new QAction( tr( "Rename %1…" ).arg( typeName ), menu );
connect( actionRenameLayer, &QAction::triggered, this, [layerItem, context] { renameLayer( layerItem, context ); } );
maintainMenu->addAction( actionRenameLayer );

if ( !layerInfo.isView )
if ( layerInfo.relKind != Qgis::PostgresRelKind::View && layerInfo.relKind != Qgis::PostgresRelKind::MaterializedView )
{
QAction *actionTruncateLayer = new QAction( tr( "Truncate %1…" ).arg( typeName ), menu );
connect( actionTruncateLayer, &QAction::triggered, this, [layerItem, context] { truncateTable( layerItem, context ); } );
Expand All @@ -123,7 +123,7 @@ bool QgsPostgresDataItemGuiProvider::deleteLayer( QgsLayerItem *item, QgsDataIte
if ( QgsPGLayerItem *layerItem = qobject_cast< QgsPGLayerItem * >( item ) )
{
const QgsPostgresLayerProperty &layerInfo = layerItem->layerInfo();
const QString typeName = layerInfo.isView ? tr( "View" ) : tr( "Table" );
const QString typeName = typeNameFromLayer( layerInfo );

if ( QMessageBox::question( nullptr, tr( "Delete %1" ).arg( typeName ),
QObject::tr( "Are you sure you want to delete %1 '%2.%3'?" ).arg( typeName.toLower(), layerInfo.schemaName, layerInfo.tableName ),
Expand Down Expand Up @@ -190,6 +190,30 @@ QWidget *QgsPostgresDataItemGuiProvider::createParamWidget( QgsDataItem *root, Q
}
}

QString QgsPostgresDataItemGuiProvider::typeNameFromLayer( const QgsPostgresLayerProperty &layer )
{
switch ( layer.relKind )
{
case Qgis::PostgresRelKind::View:
return tr( "View" );

case Qgis::PostgresRelKind::MaterializedView:
return tr( "Materialized View" );

case Qgis::PostgresRelKind::NotSet:
case Qgis::PostgresRelKind::Unknown:
case Qgis::PostgresRelKind::OrdinaryTable:
case Qgis::PostgresRelKind::Index:
case Qgis::PostgresRelKind::Sequence:
case Qgis::PostgresRelKind::CompositeType:
case Qgis::PostgresRelKind::ToastTable:
case Qgis::PostgresRelKind::ForeignTable:
case Qgis::PostgresRelKind::PartitionedTable:
return tr( "Table" );
}

BUILTIN_UNREACHABLE
}

void QgsPostgresDataItemGuiProvider::newConnection( QgsDataItem *item )
{
Expand Down Expand Up @@ -380,8 +404,9 @@ void QgsPostgresDataItemGuiProvider::renameSchema( QgsPGSchemaItem *schemaItem,
void QgsPostgresDataItemGuiProvider::renameLayer( QgsPGLayerItem *layerItem, QgsDataItemGuiContext context )
{
const QgsPostgresLayerProperty &layerInfo = layerItem->layerInfo();
const QString typeName = layerInfo.isView ? tr( "View" ) : tr( "Table" );
const QString lowerTypeName = layerInfo.isView ? tr( "view" ) : tr( "table" );
const QString typeName = typeNameFromLayer( layerInfo );
const QString lowerTypeName = ( layerInfo.relKind == Qgis::PostgresRelKind::View || layerInfo.relKind == Qgis::PostgresRelKind::MaterializedView )
? tr( "view" ) : tr( "table" );

QgsNewNameDialog dlg( tr( "%1 %2.%3" ).arg( lowerTypeName, layerInfo.schemaName, layerInfo.tableName ), layerInfo.tableName );
dlg.setWindowTitle( tr( "Rename %1" ).arg( typeName ) );
Expand All @@ -408,7 +433,7 @@ void QgsPostgresDataItemGuiProvider::renameLayer( QgsPGLayerItem *layerItem, Qgs

//rename the layer
QString sql;
if ( layerInfo.isView )
if ( layerInfo.relKind == Qgis::PostgresRelKind::View || layerInfo.relKind == Qgis::PostgresRelKind::MaterializedView )
{
sql = QStringLiteral( "ALTER %1 VIEW %2 RENAME TO %3" ).arg( layerInfo.relKind == Qgis::PostgresRelKind::MaterializedView ? QStringLiteral( "MATERIALIZED" ) : QString(),
oldName, newName );
Expand Down
3 changes: 3 additions & 0 deletions src/providers/postgres/qgspostgresdataitemguiprovider.h
Expand Up @@ -20,6 +20,7 @@

class QgsPGSchemaItem;
class QgsPGLayerItem;
class QgsPostgresLayerProperty;

class QgsPostgresDataItemGuiProvider : public QObject, public QgsDataItemGuiProvider
{
Expand All @@ -39,6 +40,8 @@ class QgsPostgresDataItemGuiProvider : public QObject, public QgsDataItemGuiProv
QWidget *createParamWidget( QgsDataItem *root, QgsDataItemGuiContext ) override;

private:

static QString typeNameFromLayer( const QgsPostgresLayerProperty &layer );
static void newConnection( QgsDataItem *item );
static void editConnection( QgsDataItem *item );
static void deleteConnection( QgsDataItem *item );
Expand Down
4 changes: 2 additions & 2 deletions src/providers/postgres/qgspostgresdataitems.cpp
Expand Up @@ -538,11 +538,11 @@ QgsPGLayerItem *QgsPGSchemaItem::createLayer( QgsPostgresLayerProperty layerProp
{
//QgsDebugMsg( "schemaName = " + layerProperty.schemaName + " tableName = " + layerProperty.tableName + " geometryColName = " + layerProperty.geometryColName );
QString tip;
if ( layerProperty.isView && layerProperty.relKind != Qgis::PostgresRelKind::MaterializedView )
if ( layerProperty.relKind == Qgis::PostgresRelKind::View )
{
tip = tr( "View" );
}
else if ( layerProperty.isView && layerProperty.relKind == Qgis::PostgresRelKind::MaterializedView )
else if ( layerProperty.relKind == Qgis::PostgresRelKind::MaterializedView )
{
tip = tr( "Materialized view" );
}
Expand Down
8 changes: 4 additions & 4 deletions src/providers/postgres/qgspostgresproviderconnection.cpp
Expand Up @@ -618,7 +618,7 @@ QList<QgsPostgresProviderConnection::TableProperty> QgsPostgresProviderConnectio
{
// Classify
TableFlags prFlags;
if ( pr.isView )
if ( pr.relKind == Qgis::PostgresRelKind::View || pr.relKind == Qgis::PostgresRelKind::MaterializedView )
{
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::View );
}
Expand Down Expand Up @@ -667,9 +667,9 @@ QList<QgsPostgresProviderConnection::TableProperty> QgsPostgresProviderConnectio
property.setComment( pr.tableComment );

// Get PKs
if ( pr.isView
|| ( pr.relKind == Qgis::PostgresRelKind::MaterializedView )
|| ( pr.relKind == Qgis::PostgresRelKind::ForeignTable ) )
if ( pr.relKind == Qgis::PostgresRelKind::View
|| pr.relKind == Qgis::PostgresRelKind::MaterializedView
|| pr.relKind == Qgis::PostgresRelKind::ForeignTable )
{
// Set the candidates
property.setPrimaryKeyColumns( pr.pkCols );
Expand Down

0 comments on commit 84dfaf2

Please sign in to comment.