diff --git a/src/core/providers/ogr/qgsogrprovidermetadata.cpp b/src/core/providers/ogr/qgsogrprovidermetadata.cpp index 092da1893f03..b7be2d95f1ff 100644 --- a/src/core/providers/ogr/qgsogrprovidermetadata.cpp +++ b/src/core/providers/ogr/qgsogrprovidermetadata.cpp @@ -27,6 +27,7 @@ email : nyall dot dawson at gmail dot com #include "qgsprojectstorageregistry.h" #include "qgsgeopackageproviderconnection.h" #include "qgsogrdbconnection.h" +#include "qgsprovidersublayerdetails.h" #include #include @@ -1028,6 +1029,61 @@ bool QgsOgrProviderMetadata::uriIsBlocklisted( const QString &uri ) const return false; } +QList QgsOgrProviderMetadata::querySublayers( const QString &uri, Qgis::SublayerQueryFlags flags, QgsFeedback * ) const +{ + QStringList skippedLayerNames; + + QStringList options { QStringLiteral( "@LIST_ALL_TABLES=YES" ) }; + + QString errCause; + QgsOgrLayerUniquePtr firstLayer = QgsOgrProviderUtils::getLayer( uri, false, options, 0, errCause, true ); + if ( !firstLayer ) + return {}; + + const QString driverName = firstLayer->driverName(); + if ( driverName == QLatin1String( "SQLite" ) ) + { + skippedLayerNames = QgsSqliteUtils::systemTables(); + } + + const unsigned int layerCount = firstLayer->GetLayerCount(); + + if ( layerCount == 1 ) + { + return QgsOgrProviderUtils::querySubLayerList( 0, firstLayer.get(), driverName, flags, false, uri ); + } + else + { + QList res; + // In case there is no free opened dataset in the cache, keep the first + // layer alive while we iterate over the other layers, so that we can + // reuse the same dataset. Can help in a particular with a FileGDB with + // the FileGDB driver + for ( unsigned int i = 0; i < layerCount; i++ ) + { + QString errCause; + QgsOgrLayerUniquePtr layer; + + if ( i != 0 ) + { + layer = QgsOgrProviderUtils::getLayer( firstLayer->datasetName(), + false, + firstLayer->options(), + i, + errCause, + // do not check timestamp beyond the first + // layer + firstLayer == nullptr ); + if ( !layer ) + continue; + } + + res << QgsOgrProviderUtils::querySubLayerList( i, i == 0 ? firstLayer.get() : layer.get(), driverName, flags, false, uri ); + } + return res; + } +} + QMap QgsOgrProviderMetadata::connections( bool cached ) { return connectionsProtected( cached ); diff --git a/src/core/providers/ogr/qgsogrprovidermetadata.h b/src/core/providers/ogr/qgsogrprovidermetadata.h index 3fa51acc49a7..414ea9d880e7 100644 --- a/src/core/providers/ogr/qgsogrprovidermetadata.h +++ b/src/core/providers/ogr/qgsogrprovidermetadata.h @@ -41,6 +41,7 @@ class QgsOgrProviderMetadata final: public QgsProviderMetadata QString filters( FilterType type ) override; ProviderCapabilities providerCapabilities() const override; bool uriIsBlocklisted( const QString &uri ) const override; + QList< QgsProviderSublayerDetails > querySublayers( const QString &uri, Qgis::SublayerQueryFlags flags = Qgis::SublayerQueryFlags(), QgsFeedback *feedback = nullptr ) const override; Qgis::VectorExportResult createEmptyLayer( const QString &uri, const QgsFields &fields,