Restore default metadata from DB

Fix #55726
This commit is contained in:
Alessandro Pasotti 2024-01-22 16:00:00 +01:00
parent 25da5f8810
commit 6b18c7fb1d
20 changed files with 381 additions and 64 deletions

View File

@ -15,4 +15,5 @@ QgsProviderMetadata.ProviderMetadataCapabilities = lambda flags=0: QgsProviderMe
QgsProviderMetadata.FileBasedUris = QgsProviderMetadata.ProviderCapability.FileBasedUris
QgsProviderMetadata.SaveLayerMetadata = QgsProviderMetadata.ProviderCapability.SaveLayerMetadata
QgsProviderMetadata.ParallelCreateProvider = QgsProviderMetadata.ProviderCapability.ParallelCreateProvider
QgsProviderMetadata.LoadLayerMetadata = QgsProviderMetadata.ProviderCapability.LoadLayerMetadata
QgsProviderMetadata.ProviderCapabilities = lambda flags=0: QgsProviderMetadata.ProviderCapability(flags)

View File

@ -158,6 +158,7 @@ library object.
FileBasedUris,
SaveLayerMetadata,
ParallelCreateProvider,
LoadLayerMetadata,
};
typedef QFlags<QgsProviderMetadata::ProviderCapability> ProviderCapabilities;
@ -680,6 +681,21 @@ Saves ``metadata`` to the layer corresponding to the specified ``uri``.
.. versionadded:: 3.20
%End
virtual QgsLayerMetadata loadLayerMetadata( const QString &layerUri, bool &found /Out/ ) throw( QgsNotSupportedException );
%Docstring
Loads layer metadata for the specified ``layerUri``.
:param layerUri: uri of layer to load metadata for
:return: - layer metadata
- found: set to ``True`` if metadata was found, ``False`` otherwise
:raises QgsNotSupportedException: if the provider does not support loading layer metadata for the
specified ``layerUri``.
.. versionadded:: 3.36
%End
virtual bool createDb( const QString &dbPath, QString &errCause );

View File

@ -324,6 +324,25 @@ Saves ``metadata`` to the layer corresponding to the specified ``uri``.
.. versionadded:: 3.20
%End
QgsLayerMetadata loadLayerMetadata( const QString &providerKey, const QString &uri, bool &found /Out/ ) throw( QgsNotSupportedException );
%Docstring
Loads metadata for the layer corresponding to the specified ``uri``.
:param providerKey: identifier of the provider
:param uri: uri of layer to load metadata for
:return: - The layer metadata or empty metadata if not found.
- found: will be set to ``True`` if metadata was found, or ``False`` if no metadata was found
:raises QgsNotSupportedException: if the provider does not support loading layer metadata for the
specified ``uri``.
.. versionadded:: 3.36
%End
bool createDb( const QString &providerKey, const QString &dbPath, QString &errCause );
%Docstring
Creates database by the provider on the path

View File

@ -158,6 +158,7 @@ library object.
FileBasedUris,
SaveLayerMetadata,
ParallelCreateProvider,
LoadLayerMetadata,
};
typedef QFlags<QgsProviderMetadata::ProviderCapability> ProviderCapabilities;
@ -680,6 +681,21 @@ Saves ``metadata`` to the layer corresponding to the specified ``uri``.
.. versionadded:: 3.20
%End
virtual QgsLayerMetadata loadLayerMetadata( const QString &layerUri, bool &found /Out/ ) throw( QgsNotSupportedException );
%Docstring
Loads layer metadata for the specified ``layerUri``.
:param layerUri: uri of layer to load metadata for
:return: - layer metadata
- found: set to ``True`` if metadata was found, ``False`` otherwise
:raises QgsNotSupportedException: if the provider does not support loading layer metadata for the
specified ``layerUri``.
.. versionadded:: 3.36
%End
virtual bool createDb( const QString &dbPath, QString &errCause );

View File

@ -324,6 +324,25 @@ Saves ``metadata`` to the layer corresponding to the specified ``uri``.
.. versionadded:: 3.20
%End
QgsLayerMetadata loadLayerMetadata( const QString &providerKey, const QString &uri, bool &found /Out/ ) throw( QgsNotSupportedException );
%Docstring
Loads metadata for the layer corresponding to the specified ``uri``.
:param providerKey: identifier of the provider
:param uri: uri of layer to load metadata for
:return: - The layer metadata or empty metadata if not found.
- found: will be set to ``True`` if metadata was found, or ``False`` if no metadata was found
:raises QgsNotSupportedException: if the provider does not support loading layer metadata for the
specified ``uri``.
.. versionadded:: 3.36
%End
bool createDb( const QString &providerKey, const QString &dbPath, QString &errCause );
%Docstring
Creates database by the provider on the path

View File

@ -32,6 +32,7 @@ email : nyall dot dawson at gmail dot com
#include "qgsgdalutils.h"
#include "qgsproviderregistry.h"
#include "qgsvectorfilewriter.h"
#include "qgsvectorlayer.h"
#include <gdal.h>
#include <QFileInfo>
@ -654,6 +655,117 @@ bool QgsOgrProviderMetadata::saveLayerMetadata( const QString &uri, const QgsLay
throw QgsNotSupportedException( QObject::tr( "Storing metadata for the specified uri is not supported" ) );
}
QgsLayerMetadata QgsOgrProviderMetadata::loadLayerMetadata( const QString &layerUri, bool &found )
{
QgsLayerMetadata metadata;
found = false;
const QVariantMap parts = decodeUri( layerUri );
const QString path = parts.value( QStringLiteral( "path" ) ).toString();
QString errorMessage;
if ( !path.isEmpty() && QFileInfo::exists( path ) )
{
const QFileInfo fi( path );
// if it is a gpkg, try reading metadata
if ( fi.suffix().compare( QLatin1String( "gpkg" ), Qt::CaseInsensitive ) == 0 )
{
const QString layerName = parts.value( QStringLiteral( "layerName" ) ).toString();
QgsOgrLayerUniquePtr userLayer;
userLayer = QgsOgrProviderUtils::getLayer( path, true, QStringList(), layerName, errorMessage, true );
if ( userLayer )
{
// try to read metadata from gpkg_metadata table
QString sql = QStringLiteral( "SELECT metadata FROM gpkg_metadata LEFT JOIN gpkg_metadata_reference ON "
"(gpkg_metadata_reference.table_name = %1 AND gpkg_metadata.id = gpkg_metadata_reference.md_file_id) "
"WHERE md_standard_uri = %2 and reference_scope = %3" ).arg(
QgsSqliteUtils::quotedString( layerName ),
QgsSqliteUtils::quotedString( QStringLiteral( "http://mrcc.com/qgis.dtd" ) ),
QgsSqliteUtils::quotedString( QStringLiteral( "table" ) ) );
if ( QgsOgrLayerUniquePtr l = userLayer->ExecuteSQL( sql.toUtf8().constData() ) )
{
// retrieve row id
gdal::ogr_feature_unique_ptr f( l->GetNextFeature() );
if ( f )
{
bool ok = false;
QVariant res = QgsOgrUtils::getOgrFeatureAttribute( f.get(), QgsField( QString(), QVariant::String ), 0, nullptr, &ok );
if ( ok )
{
QDomDocument document;
QString metadataXml = res.toString();
if ( document.setContent( metadataXml ) )
{
if ( !metadata.readMetadataXml( document.documentElement() ) )
{
found = false;
return metadata;
}
found = true;
return metadata;
}
}
}
}
}
// Read from gpkg_contents but do not override whatever was set in the previous step
// (this is to support old geopackages which do not have metadata in gpkg_metadata)
if ( metadata.title().isEmpty() || metadata.abstract().isEmpty() )
{
QRecursiveMutex *mutex = nullptr;
// Returns native OGRLayerH object with the mutex to lock when using it
OGRLayerH hLayer = userLayer->getHandleAndMutex( mutex );
QMutexLocker locker( mutex );
// These are special keys which get stored into the gpkg_contents table
if ( metadata.abstract().isEmpty() )
{
const char *description = GDALGetMetadataItem( hLayer, "DESCRIPTION", nullptr );
if ( description )
{
metadata.setAbstract( QString( description ) );
found = true;
}
}
if ( metadata.title().isEmpty() )
{
const char *identifier = GDALGetMetadataItem( hLayer, "IDENTIFIER", nullptr );
if ( identifier )
{
found = true;
metadata.setIdentifier( QString( identifier ) );
}
}
}
return metadata;
}
}
// try to read metadata from .qmd sidecar file
const QFileInfo fi( path );
const QString qmdFileName = fi.dir().filePath( fi.completeBaseName() + QStringLiteral( ".qmd" ) );
QFile qmdFile( qmdFileName );
if ( qmdFile.open( QFile::ReadOnly ) )
{
QDomDocument document;
if ( document.setContent( &qmdFile ) )
{
if ( !metadata.readMetadataXml( document.documentElement() ) )
{
found = false;
return metadata;
}
found = true;
return metadata;
}
}
throw QgsNotSupportedException( QObject::tr( "Loading metadata for the specified uri is not supported" ) );
}
QgsTransaction *QgsOgrProviderMetadata::createTransaction( const QString &connString )
{
@ -1201,7 +1313,7 @@ void QgsOgrProviderMetadata::saveConnection( const QgsAbstractProviderConnection
QgsProviderMetadata::ProviderCapabilities QgsOgrProviderMetadata::providerCapabilities() const
{
return FileBasedUris | SaveLayerMetadata;
return FileBasedUris | SaveLayerMetadata | LoadLayerMetadata;
}
///@endcond

View File

@ -73,6 +73,7 @@ class QgsOgrProviderMetadata final: public QgsProviderMetadata
QStringList &descriptions, QString &errCause ) override;
QString getStyleById( const QString &uri, const QString &styleId, QString &errCause ) override;
bool saveLayerMetadata( const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage ) final;
QgsLayerMetadata loadLayerMetadata( const QString &layerUri, bool &found ) override;
// -----
QgsTransaction *createTransaction( const QString &connString ) override;
@ -85,9 +86,9 @@ class QgsOgrProviderMetadata final: public QgsProviderMetadata
void saveConnection( const QgsAbstractProviderConnection *connection, const QString &name ) override;
protected:
QgsAbstractProviderConnection *createConnection( const QString &uri, const QVariantMap &configuration ) override;
public:
};

View File

@ -297,6 +297,11 @@ bool QgsProviderMetadata::saveLayerMetadata( const QString &, const QgsLayerMeta
throw QgsNotSupportedException( QObject::tr( "Provider %1 does not support writing layer metadata" ).arg( key() ) );
}
QgsLayerMetadata QgsProviderMetadata::loadLayerMetadata( const QString &, bool & )
{
throw QgsNotSupportedException( QObject::tr( "Provider %1 does not support reading layer metadata" ).arg( key() ) );
}
bool QgsProviderMetadata::createDb( const QString &, QString &errCause )
{
errCause = QObject::tr( "Provider %1 has no %2 method" ).arg( key(), QStringLiteral( "createDb" ) );

View File

@ -203,6 +203,7 @@ class CORE_EXPORT QgsProviderMetadata : public QObject
FileBasedUris = 1 << 0, //!< Indicates that the provider can utilize URIs which are based on paths to files (as opposed to database or internet paths)
SaveLayerMetadata = 1 << 1, //!< Indicates that the provider supports saving native layer metadata (since QGIS 3.20)
ParallelCreateProvider = 1 << 2, //!< Indicates that the provider supports parallel creation, that is, can be created on another thread than the main thread (since QGIS 3.32)
LoadLayerMetadata = 1 << 3, //!< Indicates that the provider supports loading native layer metadata (since QGIS 3.36)
};
Q_DECLARE_FLAGS( ProviderCapabilities, ProviderCapability )
@ -703,6 +704,17 @@ class CORE_EXPORT QgsProviderMetadata : public QObject
*/
virtual bool saveLayerMetadata( const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage SIP_OUT ) SIP_THROW( QgsNotSupportedException );
/**
* Loads layer metadata for the specified \a layerUri.
* \param layerUri uri of layer to load metadata for
* \param found set to TRUE if metadata was found, FALSE otherwise
* \returns layer metadata
* \throws QgsNotSupportedException if the provider does not support loading layer metadata for the
* specified \a layerUri.
* \since QGIS 3.36
*/
virtual QgsLayerMetadata loadLayerMetadata( const QString &layerUri, bool &found SIP_OUT ) SIP_THROW( QgsNotSupportedException );
/**
* Creates database by the provider on the path
* \since QGIS 3.10

View File

@ -840,6 +840,16 @@ bool QgsProviderRegistry::saveLayerMetadata( const QString &providerKey, const Q
}
}
QgsLayerMetadata QgsProviderRegistry::loadLayerMetadata( const QString &providerKey, const QString &uri, bool &found )
{
if ( QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey ) )
return meta->loadLayerMetadata( uri, found );
else
{
throw QgsNotSupportedException( QObject::tr( "Unable to load %1 provider" ).arg( providerKey ) );
}
}
bool QgsProviderRegistry::createDb( const QString &providerKey, const QString &dbPath, QString &errCause )
{
QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );

View File

@ -335,6 +335,23 @@ class CORE_EXPORT QgsProviderRegistry
*/
bool saveLayerMetadata( const QString &providerKey, const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage SIP_OUT ) SIP_THROW( QgsNotSupportedException );
/**
* Loads metadata for the layer corresponding to the specified \a uri.
*
* \param providerKey identifier of the provider
* \param uri uri of layer to load metadata for
* \param found will be set to TRUE if metadata was found, or FALSE if no metadata was found
*
* \returns The layer metadata or empty metadata if not found.
*
* \throws QgsNotSupportedException if the provider does not support loading layer metadata for the
* specified \a uri.
*
* \since QGIS 3.36
*/
QgsLayerMetadata loadLayerMetadata( const QString &providerKey, const QString &uri, bool &found SIP_OUT ) SIP_THROW( QgsNotSupportedException );
/**
* Creates database by the provider on the path
* \since QGIS 3.10

View File

@ -1301,6 +1301,28 @@ QString QgsMapLayer::loadDefaultMetadata( bool &resultFlag )
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
if ( const QgsProviderMetadata *metadata = QgsProviderRegistry::instance()->providerMetadata( providerType() ) )
{
if ( metadata->providerCapabilities() & QgsProviderMetadata::ProviderCapability::LoadLayerMetadata )
{
try
{
const QgsLayerMetadata metadata { QgsProviderRegistry::instance()->loadLayerMetadata( providerType(), mDataSource, resultFlag ) };
if ( resultFlag )
{
mMetadata = metadata;
return tr( "Successfully loaded default layer metadata" );
}
}
catch ( QgsNotSupportedException &e )
{
resultFlag = false;
return e.what();
}
}
}
return loadNamedMetadata( metadataUri(), resultFlag );
}

View File

@ -139,7 +139,7 @@ void QgsLayerPropertiesDialog::loadDefaultMetadata()
return;
bool defaultLoadedFlag = false;
const QString message = mLayer->loadNamedMetadata( mLayer->metadataUri(), defaultLoadedFlag );
const QString message = mLayer->loadDefaultMetadata( defaultLoadedFlag );
//reset if the default metadata was loaded OK only
if ( defaultLoadedFlag )
{

View File

@ -215,36 +215,14 @@ QgsPostgresProvider::QgsPostgresProvider( QString const &uri, const ProviderOpti
mLayerExtent.setNull();
// Try to load metadata
const QString schemaQuery = QStringLiteral( "SELECT table_schema FROM information_schema.tables WHERE table_name = 'qgis_layer_metadata'" );
QgsPostgresResult res( mConnectionRO->LoggedPQexec( "QgsPostgresProvider", schemaQuery ) );
if ( res.PQntuples( ) > 0 )
{
const QString schemaName = res.PQgetvalue( 0, 0 );
// TODO: also filter CRS?
const QString selectQuery = QStringLiteral( R"SQL(
SELECT
qmd
FROM %4.qgis_layer_metadata
WHERE
f_table_schema=%1
AND f_table_name=%2
AND f_geometry_column %3
AND layer_type='vector'
)SQL" )
.arg( QgsPostgresConn::quotedValue( mUri.schema() ) )
.arg( QgsPostgresConn::quotedValue( mUri.table() ) )
.arg( mUri.geometryColumn().isEmpty() ? QStringLiteral( "IS NULL" ) : QStringLiteral( "=%1" ).arg( QgsPostgresConn::quotedValue( mUri.geometryColumn() ) ) )
.arg( QgsPostgresConn::quotedIdentifier( schemaName ) );
// Try to load metadata from DB
bool metadataLoadedFromDb = false;
QgsLayerMetadata metadataFromDb { QgsPostgresProviderMetadataUtils::loadLayerMetadata( Qgis::LayerType::Vector, uri, metadataLoadedFromDb ) };
QgsPostgresResult res( mConnectionRO->LoggedPQexec( "QgsPostgresProvider", selectQuery ) );
if ( res.PQntuples() > 0 )
{
QgsLayerMetadata metadata;
QDomDocument doc;
doc.setContent( res.PQgetvalue( 0, 0 ) );
mLayerMetadata.readMetadataXml( doc.documentElement() );
}
if ( metadataLoadedFromDb )
{
mLayerMetadata = metadataFromDb;
QgsMessageLog::logMessage( tr( "PostgreSQL layer metadata loaded from DB." ), tr( "PostGIS" ) );
}
// set the primary key
@ -6095,8 +6073,13 @@ bool QgsPostgresProviderMetadata::saveLayerMetadata( const QString &uri, const Q
return QgsPostgresProviderMetadataUtils::saveLayerMetadata( Qgis::LayerType::Vector, uri, metadata, errorMessage );
}
QgsLayerMetadata QgsPostgresProviderMetadata::loadLayerMetadata( const QString &layerUri, bool &found )
{
return QgsPostgresProviderMetadataUtils::loadLayerMetadata( Qgis::LayerType::Vector, layerUri, found );
}
QgsProviderMetadata::ProviderCapabilities QgsPostgresProviderMetadata::providerCapabilities() const
{
return QgsProviderMetadata::ProviderCapability::SaveLayerMetadata | QgsProviderMetadata::ProviderCapability::ParallelCreateProvider;
return QgsProviderMetadata::ProviderCapability::SaveLayerMetadata | QgsProviderMetadata::ProviderCapability::LoadLayerMetadata | QgsProviderMetadata::ProviderCapability::ParallelCreateProvider;
}

View File

@ -607,6 +607,7 @@ class QgsPostgresProviderMetadata final: public QgsProviderMetadata
QString encodeUri( const QVariantMap &parts ) const override;
QList< Qgis::LayerType > supportedLayerTypes() const override;
bool saveLayerMetadata( const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage ) override;
QgsLayerMetadata loadLayerMetadata( const QString &layerUri, bool &found ) override;
QgsProviderMetadata::ProviderCapabilities providerCapabilities() const override;
};

View File

@ -337,3 +337,79 @@ bool QgsPostgresProviderMetadataUtils::saveLayerMetadata( const Qgis::LayerType
return saved;
}
QgsLayerMetadata QgsPostgresProviderMetadataUtils::loadLayerMetadata( const Qgis::LayerType &layerType, const QString &layerUri, bool &found )
{
found = false;
QgsLayerMetadata metadata;
QgsDataSourceUri dsUri( layerUri );
QString layerTypeString;
if ( layerType == Qgis::LayerType::Vector )
{
layerTypeString = QStringLiteral( "vector" );
}
else if ( layerType == Qgis::LayerType::Raster )
{
layerTypeString = QStringLiteral( "raster" );
}
else
{
// Unsupported!
return metadata;
}
QgsPostgresConn *conn = QgsPostgresConn::connectDb( dsUri, false );
if ( !conn )
{
return metadata;
}
if ( dsUri.database().isEmpty() ) // typically when a service file is used
{
dsUri.setDatabase( conn->currentDatabase() );
}
// Try to load metadata
QString schemaName { dsUri.schema().isEmpty() ? QStringLiteral( "public" ) : dsUri.schema() };
const QString schemaQuery = QStringLiteral( "SELECT table_schema FROM information_schema.tables WHERE table_name = 'qgis_layer_metadata'" );
QgsPostgresResult res( conn->LoggedPQexec( "QgsPostgresProviderMetadataUtils", schemaQuery ) );
const bool metadataTableFound { res.PQntuples( ) > 0 };
if ( metadataTableFound )
{
schemaName = res.PQgetvalue( 0, 0 ) ;
const QString schemaName = res.PQgetvalue( 0, 0 );
// TODO: also filter CRS?
const QString selectQuery = QStringLiteral( R"SQL(
SELECT
qmd
FROM %4.qgis_layer_metadata
WHERE
f_table_schema=%1
AND f_table_name=%2
AND f_geometry_column %3
AND layer_type='%5'
)SQL" )
.arg( QgsPostgresConn::quotedValue( dsUri.schema() ) )
.arg( QgsPostgresConn::quotedValue( dsUri.table() ) )
.arg( dsUri.geometryColumn().isEmpty() ? QStringLiteral( "IS NULL" ) : QStringLiteral( "=%1" ).arg( QgsPostgresConn::quotedValue( dsUri.geometryColumn() ) ) )
.arg( QgsPostgresConn::quotedIdentifier( schemaName ) )
.arg( layerType == Qgis::LayerType::Raster ? QStringLiteral( "raster" ) : QStringLiteral( "vector" ) );
QgsPostgresResult res( conn->LoggedPQexec( "QgsPostgresProvider", selectQuery ) );
if ( res.PQntuples() > 0 )
{
QDomDocument doc;
doc.setContent( res.PQgetvalue( 0, 0 ) );
metadata.readMetadataXml( doc.documentElement() );
}
found = true;
}
return metadata;
}

View File

@ -32,6 +32,11 @@ class QgsPostgresProviderMetadataUtils
static QList<QgsLayerMetadataProviderResult> searchLayerMetadata( const QgsMetadataSearchContext &searchContext, const QString &uri, const QString &searchString, const QgsRectangle &geographicExtent, QgsFeedback *feedback );
static bool saveLayerMetadata( const Qgis::LayerType &layerType, const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage );
// Load metadata for a layer
static QgsLayerMetadata loadLayerMetadata( const Qgis::LayerType &layerType, const QString &layerUri, bool &found );
};
#endif // QGSPOSTGRESPROVIDERMETADATAUTILS_H

View File

@ -117,39 +117,26 @@ QgsPostgresRasterProvider::QgsPostgresRasterProvider( const QString &uri, const
QStringLiteral( "PostGIS" ), Qgis::MessageLevel::Warning );
}
// Try to load metadata
const QString schemaQuery = QStringLiteral( "SELECT table_schema FROM information_schema.tables WHERE table_name = 'qgis_layer_metadata'" );
QgsPostgresResult res( mConnectionRO->LoggedPQexec( "QgsPostgresRasterProvider", schemaQuery ) );
if ( res.PQntuples( ) > 0 )
{
const QString schemaName = res.PQgetvalue( 0, 0 );
// TODO: also filter CRS?
const QString selectQuery = QStringLiteral( R"SQL(
SELECT
qmd
FROM %4.qgis_layer_metadata
WHERE
f_table_schema=%1
AND f_table_name=%2
AND f_geometry_column %3
AND layer_type='raster'
)SQL" )
.arg( QgsPostgresConn::quotedValue( mUri.schema() ) )
.arg( QgsPostgresConn::quotedValue( mUri.table() ) )
.arg( mUri.geometryColumn().isEmpty() ? QStringLiteral( "IS NULL" ) : QStringLiteral( "=%1" ).arg( QgsPostgresConn::quotedValue( mUri.geometryColumn() ) ) )
.arg( QgsPostgresConn::quotedIdentifier( schemaName ) );
// Try to load metadata from DB
bool metadataLoadedFromDb = false;
QgsLayerMetadata metadataFromDb { QgsPostgresProviderMetadataUtils::loadLayerMetadata( Qgis::LayerType::Raster, uri, metadataLoadedFromDb ) };
QgsPostgresResult res( mConnectionRO->LoggedPQexec( "QgsPostgresRasterProvider", selectQuery ) );
if ( res.PQntuples() > 0 )
{
QgsLayerMetadata metadata;
QDomDocument doc;
doc.setContent( res.PQgetvalue( 0, 0 ) );
mLayerMetadata.readMetadataXml( doc.documentElement() );
QgsMessageLog::logMessage( tr( "PostgreSQL raster layer metadata loaded from the database." ), tr( "PostGIS" ) );
}
if ( metadataLoadedFromDb )
{
mLayerMetadata = metadataFromDb;
QgsMessageLog::logMessage( tr( "PostgreSQL layer metadata loaded from DB." ), tr( "PostGIS" ) );
}
// set the primary key
if ( !determinePrimaryKey() )
{
QgsMessageLog::logMessage( tr( "PostgreSQL layer has no primary key." ), tr( "PostGIS" ) );
mValid = false;
disconnectDb();
return;
}
mLayerMetadata.setType( QStringLiteral( "dataset" ) );
mLayerMetadata.setCrs( crs() );
@ -734,9 +721,14 @@ bool QgsPostgresRasterProviderMetadata::saveLayerMetadata( const QString &uri, c
return QgsPostgresProviderMetadataUtils::saveLayerMetadata( Qgis::LayerType::Raster, uri, metadata, errorMessage );
}
QgsLayerMetadata QgsPostgresRasterProviderMetadata::loadLayerMetadata( const QString &layerUri, bool &found )
{
return QgsPostgresProviderMetadataUtils::loadLayerMetadata( Qgis::LayerType::Raster, layerUri, found );
}
QgsProviderMetadata::ProviderCapabilities QgsPostgresRasterProviderMetadata::providerCapabilities() const
{
return QgsProviderMetadata::ProviderCapability::SaveLayerMetadata;
return QgsProviderMetadata::ProviderCapability::SaveLayerMetadata | QgsProviderMetadata::ProviderCapability::LoadLayerMetadata;
}
QgsPostgresRasterProvider *QgsPostgresRasterProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )

View File

@ -267,6 +267,7 @@ class QgsPostgresRasterProviderMetadata: public QgsProviderMetadata
QString encodeUri( const QVariantMap &parts ) const override;
QList< Qgis::LayerType > supportedLayerTypes() const override;
bool saveLayerMetadata( const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage ) override;
QgsLayerMetadata loadLayerMetadata( const QString &layerUri, bool &found ) override;
QgsProviderMetadata::ProviderCapabilities providerCapabilities() const override;
};

View File

@ -135,3 +135,12 @@ class LayerMetadataProviderTestBase():
self.assertEqual(len(results.metadata()), 1)
results = md_provider.search(QgsMetadataSearchContext(), 'cat2')
self.assertEqual(len(results.metadata()), 1)
# Test load from DB (used by restore from default)
self.test_layer = self.getLayer()
self.assertTrue(self.test_layer.isValid())
self.assertTrue(bool(md.providerCapabilities() & QgsProviderMetadata.ProviderCapability.LoadLayerMetadata))
m2, found = md.loadLayerMetadata(layer_uri)
self.assertTrue(found)
self.assertEqual(m2, m)