Skip to content

Commit

Permalink
De-duplicate methods for determining relkind for postgres items
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Apr 6, 2023
1 parent a818682 commit afc48e0
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 134 deletions.
42 changes: 42 additions & 0 deletions src/providers/postgres/qgspostgresconn.cpp
Expand Up @@ -1379,6 +1379,48 @@ QString QgsPostgresConn::quotedJsonValue( const QVariant &value )
return quotedString( QString::fromStdString( j.dump() ) );
}

Qgis::PostgresRelKind QgsPostgresConn::relKindFromValue( const QString &value )
{
if ( value == 'r' )
{
return Qgis::PostgresRelKind::OrdinaryTable;
}
else if ( value == 'i' )
{
return Qgis::PostgresRelKind::Index;
}
else if ( value == 's' )
{
return Qgis::PostgresRelKind::Sequence;
}
else if ( value == 'v' )
{
return Qgis::PostgresRelKind::View;
}
else if ( value == 'm' )
{
return Qgis::PostgresRelKind::MaterializedView;
}
else if ( value == 'c' )
{
return Qgis::PostgresRelKind::CompositeType;
}
else if ( value == 't' )
{
return Qgis::PostgresRelKind::ToastTable;
}
else if ( value == 'f' )
{
return Qgis::PostgresRelKind::ForeignTable;
}
else if ( value == 'p' )
{
return Qgis::PostgresRelKind::PartitionedTable;
}

return Qgis::PostgresRelKind::Unknown;
}

PGresult *QgsPostgresConn::PQexec( const QString &query, bool logError, bool retry, const QString &originatorClass, const QString &queryOrigin ) const
{
QMutexLocker locker( &mLock );
Expand Down
6 changes: 6 additions & 0 deletions src/providers/postgres/qgspostgresconn.h
Expand Up @@ -373,6 +373,12 @@ class QgsPostgresConn : public QObject
*/
static QString quotedJsonValue( const QVariant &value );

/**
* Returns the RelKind associated with a value from the relkind column
* in pg_class.
*/
static Qgis::PostgresRelKind relKindFromValue( const QString &value );

/**
* Gets the list of supported layers
* \param layers list to store layers in
Expand Down
133 changes: 77 additions & 56 deletions src/providers/postgres/qgspostgresdataitems.cpp
Expand Up @@ -61,72 +61,93 @@ bool QgsPostgresUtils::deleteLayer( const QString &uri, QString &errCause )
QString sqlViewCheck = QStringLiteral( "SELECT relkind FROM pg_class WHERE oid=regclass(%1)::oid" )
.arg( QgsPostgresConn::quotedValue( schemaTableName ) );
QgsPostgresResult resViewCheck( conn->LoggedPQexec( "QgsPostgresUtils", sqlViewCheck ) );
QString type = resViewCheck.PQgetvalue( 0, 0 );
if ( type == QLatin1String( "v" ) || type == QLatin1String( "m" ) )
const QString type = resViewCheck.PQgetvalue( 0, 0 );
const Qgis::PostgresRelKind relKind = QgsPostgresConn::relKindFromValue( type );

switch ( relKind )
{
QString sql = QStringLiteral( "DROP %1VIEW %2" ).arg( type == QLatin1String( "m" ) ? QStringLiteral( "MATERIALIZED " ) : QString(), schemaTableName );
QgsPostgresResult result( conn->LoggedPQexec( "QgsPostgresUtils", sql ) );
if ( result.PQresultStatus() != PGRES_COMMAND_OK )
case Qgis::PostgresRelKind::View:
case Qgis::PostgresRelKind::MaterializedView:
{
errCause = QObject::tr( "Unable to delete view %1: \n%2" )
.arg( schemaTableName,
result.PQresultErrorMessage() );
QString sql = QStringLiteral( "DROP %1VIEW %2" ).arg( type == QLatin1String( "m" ) ? QStringLiteral( "MATERIALIZED " ) : QString(), schemaTableName );
QgsPostgresResult result( conn->LoggedPQexec( "QgsPostgresUtils", sql ) );
if ( result.PQresultStatus() != PGRES_COMMAND_OK )
{
errCause = QObject::tr( "Unable to delete view %1: \n%2" )
.arg( schemaTableName,
result.PQresultErrorMessage() );
conn->unref();
return false;
}
conn->unref();
return false;
return true;
}
conn->unref();
return true;
}

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:
{
// TODO -- this logic is being applied to a whole bunch
// of potentially non-table items, eg indexes and sequences.
// These should have special handling!

// check the geometry column count
QString sql = QString( "SELECT count(*) "
"FROM geometry_columns, pg_class, pg_namespace "
"WHERE f_table_name=relname AND f_table_schema=nspname "
"AND pg_class.relnamespace=pg_namespace.oid "
"AND f_table_schema=%1 AND f_table_name=%2" )
.arg( QgsPostgresConn::quotedValue( schemaName ),
QgsPostgresConn::quotedValue( tableName ) );
QgsPostgresResult result( conn->LoggedPQexec( "QgsPostgresUtils", sql ) );
if ( result.PQresultStatus() != PGRES_TUPLES_OK )
{
errCause = QObject::tr( "Unable to delete layer %1: \n%2" )
.arg( schemaTableName,
result.PQresultErrorMessage() );
conn->unref();
return false;
}

// check the geometry column count
QString sql = QString( "SELECT count(*) "
"FROM geometry_columns, pg_class, pg_namespace "
"WHERE f_table_name=relname AND f_table_schema=nspname "
"AND pg_class.relnamespace=pg_namespace.oid "
"AND f_table_schema=%1 AND f_table_name=%2" )
.arg( QgsPostgresConn::quotedValue( schemaName ),
QgsPostgresConn::quotedValue( tableName ) );
QgsPostgresResult result( conn->LoggedPQexec( "QgsPostgresUtils", sql ) );
if ( result.PQresultStatus() != PGRES_TUPLES_OK )
{
errCause = QObject::tr( "Unable to delete layer %1: \n%2" )
.arg( schemaTableName,
result.PQresultErrorMessage() );
conn->unref();
return false;
}
int count = result.PQgetvalue( 0, 0 ).toInt();

int count = result.PQgetvalue( 0, 0 ).toInt();
if ( !geometryCol.isEmpty() && count > 1 )
{
// the table has more geometry columns, drop just the geometry column
sql = QStringLiteral( "SELECT DropGeometryColumn(%1,%2,%3)" )
.arg( QgsPostgresConn::quotedValue( schemaName ),
QgsPostgresConn::quotedValue( tableName ),
QgsPostgresConn::quotedValue( geometryCol ) );
}
else
{
// drop the table
sql = QStringLiteral( "SELECT DropGeometryTable(%1,%2)" )
.arg( QgsPostgresConn::quotedValue( schemaName ),
QgsPostgresConn::quotedValue( tableName ) );
}

if ( !geometryCol.isEmpty() && count > 1 )
{
// the table has more geometry columns, drop just the geometry column
sql = QStringLiteral( "SELECT DropGeometryColumn(%1,%2,%3)" )
.arg( QgsPostgresConn::quotedValue( schemaName ),
QgsPostgresConn::quotedValue( tableName ),
QgsPostgresConn::quotedValue( geometryCol ) );
}
else
{
// drop the table
sql = QStringLiteral( "SELECT DropGeometryTable(%1,%2)" )
.arg( QgsPostgresConn::quotedValue( schemaName ),
QgsPostgresConn::quotedValue( tableName ) );
}
result = conn->LoggedPQexec( "QgsPostgresUtils", sql );
if ( result.PQresultStatus() != PGRES_TUPLES_OK )
{
errCause = QObject::tr( "Unable to delete layer %1: \n%2" )
.arg( schemaTableName,
result.PQresultErrorMessage() );
conn->unref();
return false;
}

result = conn->LoggedPQexec( "QgsPostgresUtils", sql );
if ( result.PQresultStatus() != PGRES_TUPLES_OK )
{
errCause = QObject::tr( "Unable to delete layer %1: \n%2" )
.arg( schemaTableName,
result.PQresultErrorMessage() );
conn->unref();
return false;
conn->unref();
return true;
}
}

conn->unref();
return true;
BUILTIN_UNREACHABLE
}

bool QgsPostgresUtils::deleteSchema( const QString &schema, const QgsDataSourceUri &uri, QString &errCause, bool cascade )
Expand Down
39 changes: 1 addition & 38 deletions src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -5252,44 +5252,7 @@ Qgis::PostgresRelKind QgsPostgresProvider::relkind() const
QgsPostgresResult res( connectionRO()->LoggedPQexec( "QgsPostgresProvider", sql ) );
QString type = res.PQgetvalue( 0, 0 );

mKind = Qgis::PostgresRelKind::Unknown;

if ( type == QLatin1String( "r" ) )
{
mKind = Qgis::PostgresRelKind::OrdinaryTable;
}
else if ( type == QLatin1String( "i" ) )
{
mKind = Qgis::PostgresRelKind::Index;
}
else if ( type == QLatin1String( "s" ) )
{
mKind = Qgis::PostgresRelKind::Sequence;
}
else if ( type == QLatin1String( "v" ) )
{
mKind = Qgis::PostgresRelKind::View;
}
else if ( type == QLatin1String( "m" ) )
{
mKind = Qgis::PostgresRelKind::MaterializedView;
}
else if ( type == QLatin1String( "c" ) )
{
mKind = Qgis::PostgresRelKind::CompositeType;
}
else if ( type == QLatin1String( "t" ) )
{
mKind = Qgis::PostgresRelKind::ToastTable;
}
else if ( type == QLatin1String( "f" ) )
{
mKind = Qgis::PostgresRelKind::ForeignTable;
}
else if ( type == QLatin1String( "p" ) )
{
mKind = Qgis::PostgresRelKind::PartitionedTable;
}
mKind = QgsPostgresConn::relKindFromValue( type );
}

return mKind;
Expand Down
41 changes: 1 addition & 40 deletions src/providers/postgres/raster/qgspostgresrasterprovider.cpp
Expand Up @@ -2016,46 +2016,7 @@ Qgis::PostgresRelKind QgsPostgresRasterProvider::relkind() const
QgsPostgresResult res( connectionRO()->PQexec( sql ) );
QString type = res.PQgetvalue( 0, 0 );

Qgis::PostgresRelKind kind = Qgis::PostgresRelKind::Unknown;

if ( type == 'r' )
{
kind = Qgis::PostgresRelKind::OrdinaryTable;
}
else if ( type == 'i' )
{
kind = Qgis::PostgresRelKind::Index;
}
else if ( type == 's' )
{
kind = Qgis::PostgresRelKind::Sequence;
}
else if ( type == 'v' )
{
kind = Qgis::PostgresRelKind::View;
}
else if ( type == 'm' )
{
kind = Qgis::PostgresRelKind::MaterializedView;
}
else if ( type == 'c' )
{
kind = Qgis::PostgresRelKind::CompositeType;
}
else if ( type == 't' )
{
kind = Qgis::PostgresRelKind::ToastTable;
}
else if ( type == 'f' )
{
kind = Qgis::PostgresRelKind::ForeignTable;
}
else if ( type == 'p' )
{
kind = Qgis::PostgresRelKind::PartitionedTable;
}

return kind;
return QgsPostgresConn::relKindFromValue( type );
}

bool QgsPostgresRasterProvider::determinePrimaryKey()
Expand Down

0 comments on commit afc48e0

Please sign in to comment.