mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-06 00:03:16 -05:00
PG: faster information retrieval for table info
Information about single tables does not need to scan for all tables anymore. Fix #56069
This commit is contained in:
parent
0aed505843
commit
1ed4113ef1
@ -593,7 +593,7 @@ void QgsPostgresConn::addColumnInfo( QgsPostgresLayerProperty &layerProperty, co
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables, const QString &schema )
|
bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables, const QString &schema, const QString &name )
|
||||||
{
|
{
|
||||||
QMutexLocker locker( &mLock );
|
QMutexLocker locker( &mLock );
|
||||||
int nColumns = 0;
|
int nColumns = 0;
|
||||||
@ -601,8 +601,6 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
|
|||||||
QgsPostgresResult result;
|
QgsPostgresResult result;
|
||||||
QString query;
|
QString query;
|
||||||
|
|
||||||
mLayersSupported.clear();
|
|
||||||
|
|
||||||
for ( int i = SctGeometry; i <= SctRaster; ++i )
|
for ( int i = SctGeometry; i <= SctRaster; ++i )
|
||||||
{
|
{
|
||||||
QString sql, tableName, schemaName, columnName, typeName, sridName, gtableName, dimName;
|
QString sql, tableName, schemaName, columnName, typeName, sridName, gtableName, dimName;
|
||||||
@ -710,6 +708,9 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
|
|||||||
if ( !schema.isEmpty() )
|
if ( !schema.isEmpty() )
|
||||||
sql += QStringLiteral( " AND %1='%2'" ).arg( schemaName, schema );
|
sql += QStringLiteral( " AND %1='%2'" ).arg( schemaName, schema );
|
||||||
|
|
||||||
|
if ( !name.isEmpty() )
|
||||||
|
sql += QStringLiteral( " AND %1='%2'" ).arg( tableName, name );
|
||||||
|
|
||||||
sql += QString( " GROUP BY 1,2,3,4,5,6,7,c.oid,11" );
|
sql += QString( " GROUP BY 1,2,3,4,5,6,7,c.oid,11" );
|
||||||
|
|
||||||
foundInTables |= 1 << i;
|
foundInTables |= 1 << i;
|
||||||
@ -848,7 +849,10 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
|
|||||||
sql += QLatin1String( " AND n.nspname='public'" );
|
sql += QLatin1String( " AND n.nspname='public'" );
|
||||||
|
|
||||||
if ( !schema.isEmpty() )
|
if ( !schema.isEmpty() )
|
||||||
sql += QStringLiteral( " AND n.nspname='%2'" ).arg( schema );
|
sql += QStringLiteral( " AND n.nspname='%1'" ).arg( schema );
|
||||||
|
|
||||||
|
if ( !name.isEmpty() )
|
||||||
|
sql += QStringLiteral( " AND c.relname ='%1'" ).arg( name );
|
||||||
|
|
||||||
// skip columns of which we already derived information from the metadata tables
|
// skip columns of which we already derived information from the metadata tables
|
||||||
if ( nColumns > 0 )
|
if ( nColumns > 0 )
|
||||||
@ -987,7 +991,10 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
|
|||||||
sql += QLatin1String( " AND pg_namespace.nspname='public'" );
|
sql += QLatin1String( " AND pg_namespace.nspname='public'" );
|
||||||
|
|
||||||
if ( !schema.isEmpty() )
|
if ( !schema.isEmpty() )
|
||||||
sql += QStringLiteral( " AND pg_namespace.nspname='%2'" ).arg( schema );
|
sql += QStringLiteral( " AND pg_namespace.nspname='%1'" ).arg( schema );
|
||||||
|
|
||||||
|
if ( !name.isEmpty() )
|
||||||
|
sql += QStringLiteral( " AND pg_class.relname='%1'" ).arg( name );
|
||||||
|
|
||||||
sql += QLatin1String( " GROUP BY 1,2,3,4" );
|
sql += QLatin1String( " GROUP BY 1,2,3,4" );
|
||||||
|
|
||||||
@ -1062,12 +1069,14 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QgsPostgresConn::supportedLayers( QVector<QgsPostgresLayerProperty> &layers, bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables, const QString &schema )
|
bool QgsPostgresConn::supportedLayers( QVector<QgsPostgresLayerProperty> &layers, bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables, const QString &schema, const QString &table )
|
||||||
{
|
{
|
||||||
QMutexLocker locker( &mLock );
|
QMutexLocker locker( &mLock );
|
||||||
|
|
||||||
|
mLayersSupported.clear();
|
||||||
|
|
||||||
// Get the list of supported tables
|
// Get the list of supported tables
|
||||||
if ( !getTableInfo( searchGeometryColumnsOnly, searchPublicOnly, allowGeometrylessTables, schema ) )
|
if ( !getTableInfo( searchGeometryColumnsOnly, searchPublicOnly, allowGeometrylessTables, schema, table ) )
|
||||||
{
|
{
|
||||||
QgsMessageLog::logMessage( tr( "Unable to get list of spatially enabled tables from the database" ), tr( "PostGIS" ) );
|
QgsMessageLog::logMessage( tr( "Unable to get list of spatially enabled tables from the database" ), tr( "PostGIS" ) );
|
||||||
return false;
|
return false;
|
||||||
@ -2172,7 +2181,7 @@ void QgsPostgresConn::retrieveLayerTypes( QVector<QgsPostgresLayerProperty *> &l
|
|||||||
sql = QStringLiteral( "SELECT %1, "
|
sql = QStringLiteral( "SELECT %1, "
|
||||||
"array_agg(DISTINCT st_srid(%2) || ':RASTER:-1') "
|
"array_agg(DISTINCT st_srid(%2) || ':RASTER:-1') "
|
||||||
"FROM %3 "
|
"FROM %3 "
|
||||||
"%2 IS NOT NULL "
|
"WHERE %2 IS NOT NULL "
|
||||||
"%4" // SQL clause
|
"%4" // SQL clause
|
||||||
"%5" )
|
"%5" )
|
||||||
.arg( i - 1 )
|
.arg( i - 1 )
|
||||||
|
|||||||
@ -385,13 +385,15 @@ class QgsPostgresConn : public QObject
|
|||||||
* \param searchPublicOnly
|
* \param searchPublicOnly
|
||||||
* \param allowGeometrylessTables
|
* \param allowGeometrylessTables
|
||||||
* \param schema restrict layers to layers within specified schema
|
* \param schema restrict layers to layers within specified schema
|
||||||
|
* \param table restrict tables to those with specified table
|
||||||
* \returns true if layers were fetched successfully
|
* \returns true if layers were fetched successfully
|
||||||
*/
|
*/
|
||||||
bool supportedLayers( QVector<QgsPostgresLayerProperty> &layers,
|
bool supportedLayers( QVector<QgsPostgresLayerProperty> &layers,
|
||||||
bool searchGeometryColumnsOnly = true,
|
bool searchGeometryColumnsOnly = true,
|
||||||
bool searchPublicOnly = true,
|
bool searchPublicOnly = true,
|
||||||
bool allowGeometrylessTables = false,
|
bool allowGeometrylessTables = false,
|
||||||
const QString &schema = QString() );
|
const QString &schema = QString(),
|
||||||
|
const QString &table = QString() );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of database schemas
|
* Gets the list of database schemas
|
||||||
@ -418,10 +420,11 @@ class QgsPostgresConn : public QObject
|
|||||||
* \param searchPublicOnly
|
* \param searchPublicOnly
|
||||||
* \param allowGeometrylessTables
|
* \param allowGeometrylessTables
|
||||||
* \param schema restrict tables to those within specified schema
|
* \param schema restrict tables to those within specified schema
|
||||||
|
* \param name restrict tables to those with specified name
|
||||||
* \returns true if tables were successfully queried
|
* \returns true if tables were successfully queried
|
||||||
*/
|
*/
|
||||||
bool getTableInfo( bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables,
|
bool getTableInfo( bool searchGeometryColumnsOnly, bool searchPublicOnly, bool allowGeometrylessTables,
|
||||||
const QString &schema = QString() );
|
const QString &schema = QString(), const QString &name = QString() );
|
||||||
|
|
||||||
qint64 getBinaryInt( QgsPostgresResult &queryResult, int row, int col );
|
qint64 getBinaryInt( QgsPostgresResult &queryResult, int row, int col );
|
||||||
|
|
||||||
|
|||||||
@ -222,6 +222,142 @@ void QgsPostgresProviderConnection::renameTablePrivate( const QString &schema, c
|
|||||||
QgsPostgresConn::quotedIdentifier( newName ) ) );
|
QgsPostgresConn::quotedIdentifier( newName ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QgsAbstractDatabaseProviderConnection::TableProperty> QgsPostgresProviderConnection::tablesPrivate( const QString &schema, const QString &table, const TableFlags &flags, QgsFeedback *feedback ) const
|
||||||
|
{
|
||||||
|
checkCapability( Capability::Tables );
|
||||||
|
QList<QgsPostgresProviderConnection::TableProperty> tables;
|
||||||
|
QString errCause;
|
||||||
|
// TODO: set flags from the connection if flags argument is 0
|
||||||
|
const QgsDataSourceUri dsUri { uri() };
|
||||||
|
QgsPostgresConn *conn = QgsPostgresConnPool::instance()->acquireConnection( dsUri.connectionInfo( false ), -1, false, feedback );
|
||||||
|
if ( feedback && feedback->isCanceled() )
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if ( !conn )
|
||||||
|
{
|
||||||
|
errCause = QObject::tr( "Connection failed: %1" ).arg( uri() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QVector<QgsPostgresLayerProperty> properties;
|
||||||
|
const bool aspatial { ! flags || flags.testFlag( TableFlag::Aspatial ) };
|
||||||
|
bool ok = conn->supportedLayers( properties, false, schema == QStringLiteral( "public" ), aspatial, schema, table );
|
||||||
|
if ( ! ok )
|
||||||
|
{
|
||||||
|
if ( ! table.isEmpty() )
|
||||||
|
{
|
||||||
|
errCause = QObject::tr( "Could not retrieve table '%2' from %1" ).arg( uri(), table );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errCause = QObject::tr( "Could not retrieve tables: %1" ).arg( uri() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
bool dontResolveType = configuration().value( QStringLiteral( "dontResolveType" ), false ).toBool();
|
||||||
|
bool useEstimatedMetadata = configuration().value( QStringLiteral( "estimatedMetadata" ), false ).toBool();
|
||||||
|
|
||||||
|
// Cannot be const:
|
||||||
|
for ( auto &pr : properties )
|
||||||
|
{
|
||||||
|
// Classify
|
||||||
|
TableFlags prFlags;
|
||||||
|
if ( pr.relKind == Qgis::PostgresRelKind::View || pr.relKind == Qgis::PostgresRelKind::MaterializedView )
|
||||||
|
{
|
||||||
|
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::View );
|
||||||
|
}
|
||||||
|
if ( pr.relKind == Qgis::PostgresRelKind::MaterializedView )
|
||||||
|
{
|
||||||
|
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::MaterializedView );
|
||||||
|
}
|
||||||
|
if ( pr.relKind == Qgis::PostgresRelKind::ForeignTable )
|
||||||
|
{
|
||||||
|
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::Foreign );
|
||||||
|
}
|
||||||
|
if ( pr.isRaster )
|
||||||
|
{
|
||||||
|
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::Raster );
|
||||||
|
}
|
||||||
|
else if ( pr.nSpCols != 0 )
|
||||||
|
{
|
||||||
|
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::Vector );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::Aspatial );
|
||||||
|
}
|
||||||
|
// Filter
|
||||||
|
if ( ! flags || ( prFlags & flags ) )
|
||||||
|
{
|
||||||
|
// retrieve layer types if needed
|
||||||
|
if ( ! dontResolveType && ( !pr.geometryColName.isNull() &&
|
||||||
|
( pr.types.value( 0, Qgis::WkbType::Unknown ) == Qgis::WkbType::Unknown ||
|
||||||
|
pr.srids.value( 0, std::numeric_limits<int>::min() ) == std::numeric_limits<int>::min() ) ) )
|
||||||
|
{
|
||||||
|
conn->retrieveLayerTypes( pr, useEstimatedMetadata, feedback );
|
||||||
|
}
|
||||||
|
QgsPostgresProviderConnection::TableProperty property;
|
||||||
|
property.setFlags( prFlags );
|
||||||
|
for ( int i = 0; i < std::min( pr.types.size(), pr.srids.size() ) ; i++ )
|
||||||
|
{
|
||||||
|
property.addGeometryColumnType( pr.types.at( i ), QgsCoordinateReferenceSystem::fromEpsgId( pr.srids.at( i ) ) );
|
||||||
|
}
|
||||||
|
property.setTableName( pr.tableName );
|
||||||
|
property.setSchema( pr.schemaName );
|
||||||
|
property.setGeometryColumn( pr.geometryColName );
|
||||||
|
// These are candidates, not actual PKs
|
||||||
|
// property.setPrimaryKeyColumns( pr.pkCols );
|
||||||
|
property.setGeometryColumnCount( static_cast<int>( pr.nSpCols ) );
|
||||||
|
property.setComment( pr.tableComment );
|
||||||
|
|
||||||
|
// Get PKs
|
||||||
|
if ( pr.relKind == Qgis::PostgresRelKind::View
|
||||||
|
|| pr.relKind == Qgis::PostgresRelKind::MaterializedView
|
||||||
|
|| pr.relKind == Qgis::PostgresRelKind::ForeignTable )
|
||||||
|
{
|
||||||
|
// Set the candidates
|
||||||
|
property.setPrimaryKeyColumns( pr.pkCols );
|
||||||
|
}
|
||||||
|
else // Fetch and set the real pks
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const QList<QVariantList> pks = executeSqlPrivate( QStringLiteral( R"(
|
||||||
|
WITH pkrelid AS (
|
||||||
|
SELECT indexrelid AS idxri FROM pg_index WHERE indrelid='%1.%2'::regclass AND (indisprimary OR indisunique)
|
||||||
|
ORDER BY CASE WHEN indisprimary THEN 1 ELSE 2 END LIMIT 1)
|
||||||
|
SELECT attname FROM pg_index,pg_attribute, pkrelid
|
||||||
|
WHERE indexrelid=pkrelid.idxri AND indrelid=attrelid AND pg_attribute.attnum=any(pg_index.indkey);
|
||||||
|
)" ).arg( QgsPostgresConn::quotedIdentifier( pr.schemaName ),
|
||||||
|
QgsPostgresConn::quotedIdentifier( pr.tableName ) ), false );
|
||||||
|
QStringList pkNames;
|
||||||
|
for ( const QVariantList &pk : std::as_const( pks ) )
|
||||||
|
{
|
||||||
|
pkNames.push_back( pk.first().toString() );
|
||||||
|
}
|
||||||
|
property.setPrimaryKeyColumns( pkNames );
|
||||||
|
}
|
||||||
|
catch ( const QgsProviderConnectionException &ex )
|
||||||
|
{
|
||||||
|
QgsDebugError( QStringLiteral( "Error retrieving primary keys: %1" ).arg( ex.what() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tables.push_back( property );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QgsPostgresConnPool::instance()->releaseConnection( conn );
|
||||||
|
}
|
||||||
|
if ( ! errCause.isEmpty() )
|
||||||
|
{
|
||||||
|
throw QgsProviderConnectionException( errCause );
|
||||||
|
}
|
||||||
|
return tables;
|
||||||
|
}
|
||||||
|
|
||||||
void QgsPostgresProviderConnection::renameVectorTable( const QString &schema, const QString &name, const QString &newName ) const
|
void QgsPostgresProviderConnection::renameVectorTable( const QString &schema, const QString &name, const QString &newName ) const
|
||||||
{
|
{
|
||||||
checkCapability( Capability::RenameVectorTable );
|
checkCapability( Capability::RenameVectorTable );
|
||||||
@ -601,131 +737,21 @@ void QgsPostgresProviderConnection::setFieldComment( const QString &fieldName, c
|
|||||||
|
|
||||||
QList<QgsPostgresProviderConnection::TableProperty> QgsPostgresProviderConnection::tables( const QString &schema, const TableFlags &flags, QgsFeedback *feedback ) const
|
QList<QgsPostgresProviderConnection::TableProperty> QgsPostgresProviderConnection::tables( const QString &schema, const TableFlags &flags, QgsFeedback *feedback ) const
|
||||||
{
|
{
|
||||||
checkCapability( Capability::Tables );
|
return tablesPrivate( schema, QString(), flags, feedback );
|
||||||
QList<QgsPostgresProviderConnection::TableProperty> tables;
|
}
|
||||||
QString errCause;
|
|
||||||
// TODO: set flags from the connection if flags argument is 0
|
|
||||||
const QgsDataSourceUri dsUri { uri() };
|
|
||||||
QgsPostgresConn *conn = QgsPostgresConnPool::instance()->acquireConnection( dsUri.connectionInfo( false ), -1, false, feedback );
|
|
||||||
if ( feedback && feedback->isCanceled() )
|
|
||||||
return {};
|
|
||||||
|
|
||||||
if ( !conn )
|
QgsAbstractDatabaseProviderConnection::TableProperty QgsPostgresProviderConnection::table( const QString &schema, const QString &table, QgsFeedback *feedback ) const
|
||||||
|
{
|
||||||
|
const QList<QgsPostgresProviderConnection::TableProperty> properties { tablesPrivate( schema, table, TableFlags(), feedback ) };
|
||||||
|
if ( ! properties.empty() )
|
||||||
{
|
{
|
||||||
errCause = QObject::tr( "Connection failed: %1" ).arg( uri() );
|
return properties.first();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QVector<QgsPostgresLayerProperty> properties;
|
throw QgsProviderConnectionException( QObject::tr( "Table '%1' was not found in schema '%2'" )
|
||||||
const bool aspatial { ! flags || flags.testFlag( TableFlag::Aspatial ) };
|
.arg( table, schema ) );
|
||||||
bool ok = conn->supportedLayers( properties, false, schema == QStringLiteral( "public" ), aspatial, schema );
|
|
||||||
if ( ! ok )
|
|
||||||
{
|
|
||||||
errCause = QObject::tr( "Could not retrieve tables: %1" ).arg( uri() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
bool dontResolveType = configuration().value( QStringLiteral( "dontResolveType" ), false ).toBool();
|
|
||||||
bool useEstimatedMetadata = configuration().value( QStringLiteral( "estimatedMetadata" ), false ).toBool();
|
|
||||||
|
|
||||||
// Cannot be const:
|
|
||||||
for ( auto &pr : properties )
|
|
||||||
{
|
|
||||||
// Classify
|
|
||||||
TableFlags prFlags;
|
|
||||||
if ( pr.relKind == Qgis::PostgresRelKind::View || pr.relKind == Qgis::PostgresRelKind::MaterializedView )
|
|
||||||
{
|
|
||||||
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::View );
|
|
||||||
}
|
|
||||||
if ( pr.relKind == Qgis::PostgresRelKind::MaterializedView )
|
|
||||||
{
|
|
||||||
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::MaterializedView );
|
|
||||||
}
|
|
||||||
if ( pr.relKind == Qgis::PostgresRelKind::ForeignTable )
|
|
||||||
{
|
|
||||||
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::Foreign );
|
|
||||||
}
|
|
||||||
if ( pr.isRaster )
|
|
||||||
{
|
|
||||||
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::Raster );
|
|
||||||
}
|
|
||||||
else if ( pr.nSpCols != 0 )
|
|
||||||
{
|
|
||||||
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::Vector );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prFlags.setFlag( QgsPostgresProviderConnection::TableFlag::Aspatial );
|
|
||||||
}
|
|
||||||
// Filter
|
|
||||||
if ( ! flags || ( prFlags & flags ) )
|
|
||||||
{
|
|
||||||
// retrieve layer types if needed
|
|
||||||
if ( ! dontResolveType && ( !pr.geometryColName.isNull() &&
|
|
||||||
( pr.types.value( 0, Qgis::WkbType::Unknown ) == Qgis::WkbType::Unknown ||
|
|
||||||
pr.srids.value( 0, std::numeric_limits<int>::min() ) == std::numeric_limits<int>::min() ) ) )
|
|
||||||
{
|
|
||||||
conn->retrieveLayerTypes( pr, useEstimatedMetadata, feedback );
|
|
||||||
}
|
|
||||||
QgsPostgresProviderConnection::TableProperty property;
|
|
||||||
property.setFlags( prFlags );
|
|
||||||
for ( int i = 0; i < std::min( pr.types.size(), pr.srids.size() ) ; i++ )
|
|
||||||
{
|
|
||||||
property.addGeometryColumnType( pr.types.at( i ), QgsCoordinateReferenceSystem::fromEpsgId( pr.srids.at( i ) ) );
|
|
||||||
}
|
|
||||||
property.setTableName( pr.tableName );
|
|
||||||
property.setSchema( pr.schemaName );
|
|
||||||
property.setGeometryColumn( pr.geometryColName );
|
|
||||||
// These are candidates, not actual PKs
|
|
||||||
// property.setPrimaryKeyColumns( pr.pkCols );
|
|
||||||
property.setGeometryColumnCount( static_cast<int>( pr.nSpCols ) );
|
|
||||||
property.setComment( pr.tableComment );
|
|
||||||
|
|
||||||
// Get PKs
|
|
||||||
if ( pr.relKind == Qgis::PostgresRelKind::View
|
|
||||||
|| pr.relKind == Qgis::PostgresRelKind::MaterializedView
|
|
||||||
|| pr.relKind == Qgis::PostgresRelKind::ForeignTable )
|
|
||||||
{
|
|
||||||
// Set the candidates
|
|
||||||
property.setPrimaryKeyColumns( pr.pkCols );
|
|
||||||
}
|
|
||||||
else // Fetch and set the real pks
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const QList<QVariantList> pks = executeSqlPrivate( QStringLiteral( R"(
|
|
||||||
WITH pkrelid AS (
|
|
||||||
SELECT indexrelid AS idxri FROM pg_index WHERE indrelid='%1.%2'::regclass AND (indisprimary OR indisunique)
|
|
||||||
ORDER BY CASE WHEN indisprimary THEN 1 ELSE 2 END LIMIT 1)
|
|
||||||
SELECT attname FROM pg_index,pg_attribute, pkrelid
|
|
||||||
WHERE indexrelid=pkrelid.idxri AND indrelid=attrelid AND pg_attribute.attnum=any(pg_index.indkey);
|
|
||||||
)" ).arg( QgsPostgresConn::quotedIdentifier( pr.schemaName ),
|
|
||||||
QgsPostgresConn::quotedIdentifier( pr.tableName ) ), false );
|
|
||||||
QStringList pkNames;
|
|
||||||
for ( const QVariantList &pk : std::as_const( pks ) )
|
|
||||||
{
|
|
||||||
pkNames.push_back( pk.first().toString() );
|
|
||||||
}
|
|
||||||
property.setPrimaryKeyColumns( pkNames );
|
|
||||||
}
|
|
||||||
catch ( const QgsProviderConnectionException &ex )
|
|
||||||
{
|
|
||||||
QgsDebugError( QStringLiteral( "Error retrieving primary keys: %1" ).arg( ex.what() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tables.push_back( property );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QgsPostgresConnPool::instance()->releaseConnection( conn );
|
|
||||||
}
|
}
|
||||||
if ( ! errCause.isEmpty() )
|
|
||||||
{
|
|
||||||
throw QgsProviderConnectionException( errCause );
|
|
||||||
}
|
|
||||||
return tables;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList QgsPostgresProviderConnection::schemas( ) const
|
QStringList QgsPostgresProviderConnection::schemas( ) const
|
||||||
@ -776,6 +802,7 @@ void QgsPostgresProviderConnection::store( const QString &name ) const
|
|||||||
|
|
||||||
// From URI
|
// From URI
|
||||||
const QgsDataSourceUri dsUri { uri() };
|
const QgsDataSourceUri dsUri { uri() };
|
||||||
|
qDebug() << settings.fileName();
|
||||||
settings.setValue( "service", dsUri.service() );
|
settings.setValue( "service", dsUri.service() );
|
||||||
settings.setValue( "host", dsUri.host() );
|
settings.setValue( "host", dsUri.host() );
|
||||||
settings.setValue( "port", dsUri.port() );
|
settings.setValue( "port", dsUri.port() );
|
||||||
|
|||||||
@ -72,6 +72,7 @@ class QgsPostgresProviderConnection : public QgsAbstractDatabaseProviderConnecti
|
|||||||
void setFieldComment( const QString &fieldName, const QString &schema, const QString &tableName, const QString &comment ) const override;
|
void setFieldComment( const QString &fieldName, const QString &schema, const QString &tableName, const QString &comment ) const override;
|
||||||
QList<QgsAbstractDatabaseProviderConnection::TableProperty> tables( const QString &schema,
|
QList<QgsAbstractDatabaseProviderConnection::TableProperty> tables( const QString &schema,
|
||||||
const TableFlags &flags = TableFlags(), QgsFeedback *feedback = nullptr ) const override;
|
const TableFlags &flags = TableFlags(), QgsFeedback *feedback = nullptr ) const override;
|
||||||
|
QgsAbstractDatabaseProviderConnection::TableProperty table( const QString &schema, const QString &table, QgsFeedback *feedback = nullptr ) const override;
|
||||||
QStringList schemas( ) const override;
|
QStringList schemas( ) const override;
|
||||||
void store( const QString &name ) const override;
|
void store( const QString &name ) const override;
|
||||||
void remove( const QString &name ) const override;
|
void remove( const QString &name ) const override;
|
||||||
@ -92,7 +93,8 @@ class QgsPostgresProviderConnection : public QgsAbstractDatabaseProviderConnecti
|
|||||||
void setDefaultCapabilities();
|
void setDefaultCapabilities();
|
||||||
void dropTablePrivate( const QString &schema, const QString &name ) const;
|
void dropTablePrivate( const QString &schema, const QString &name ) const;
|
||||||
void renameTablePrivate( const QString &schema, const QString &name, const QString &newName ) const;
|
void renameTablePrivate( const QString &schema, const QString &name, const QString &newName ) const;
|
||||||
|
QList<QgsAbstractDatabaseProviderConnection::TableProperty> tablesPrivate( const QString &schema, const QString &table,
|
||||||
|
const TableFlags &flags = TableFlags(), QgsFeedback *feedback = nullptr ) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user