Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add support for setting field comments to OGR provider connection
  • Loading branch information
nyalldawson committed Apr 18, 2023
1 parent d798fd0 commit a1345f0
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/core/providers/ogr/qgsogrproviderconnection.cpp
Expand Up @@ -453,6 +453,10 @@ void QgsOgrProviderConnection::setDefaultCapabilities()
{
mCapabilities2 |= Qgis::DatabaseProviderConnectionCapability2::SetFieldAlias;
}
if ( CSLFindString( papszTokens, "Comment" ) >= 0 )
{
mCapabilities2 |= Qgis::DatabaseProviderConnectionCapability2::SetFieldComment;
}
#endif

CSLDestroy( papszTokens );
Expand Down Expand Up @@ -1061,6 +1065,46 @@ void QgsOgrProviderConnection::setFieldAlias( const QString &fieldName, const QS
#endif
}

void QgsOgrProviderConnection::setFieldComment( const QString &fieldName, const QString &schema, const QString &tableName, const QString &comment ) const
{
#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,7,0)
if ( ! schema.isEmpty() )
{
QgsMessageLog::logMessage( QStringLiteral( "Schema is not supported by OGR, ignoring" ), QStringLiteral( "OGR" ), Qgis::MessageLevel::Info );
}

QString errCause;
QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( uri(),
true,
QStringList(),
tableName, errCause, true );
if ( !layer )
{
throw QgsProviderConnectionException( QObject::tr( "There was an error opening the dataset: %1" ).arg( errCause ) );
}

//type does not matter, it will not be used
gdal::ogr_field_def_unique_ptr fld( OGR_Fld_Create( fieldName.toUtf8().constData(), OFTReal ) );
OGR_Fld_SetComment( fld.get(), comment.toUtf8().constData() );

const int fieldIndex = layer->GetLayerDefn().GetFieldIndex( fieldName.toUtf8().constData() );
if ( fieldIndex < 0 )
{
throw QgsProviderConnectionException( QObject::tr( "Could not set comment for %1 - field does not exist" ).arg( fieldName ) );
}
if ( layer->AlterFieldDefn( fieldIndex, fld.get(), ALTER_COMMENT_FLAG ) != OGRERR_NONE )
{
throw QgsProviderConnectionException( QObject::tr( "Could not set comment: %1" ).arg( CPLGetLastErrorMsg() ) );
}
#else
( void )fieldName;
( void )schema;
( void )tableName;
( void )comment;
throw QgsProviderConnectionException( QObject::tr( "Setting field comments for datasets requires GDAL 3.7 or later" ) );
#endif
}

QgsAbstractDatabaseProviderConnection::SqlVectorLayerOptions QgsOgrProviderConnection::sqlOptions( const QString &layerSource )
{
SqlVectorLayerOptions options;
Expand Down
1 change: 1 addition & 0 deletions src/core/providers/ogr/qgsogrproviderconnection.h
Expand Up @@ -90,6 +90,7 @@ class QgsOgrProviderConnection : public QgsAbstractDatabaseProviderConnection
void addFieldDomain( const QgsFieldDomain &domain, const QString &schema ) const override;
void renameField( const QString &schema, const QString &tableName, const QString &name, const QString &newName ) const override;
void setFieldAlias( const QString &fieldName, const QString &schema, const QString &tableName, const QString &alias ) const override;
void setFieldComment( const QString &fieldName, const QString &schema, const QString &tableName, const QString &comment ) const override;
SqlVectorLayerOptions sqlOptions( const QString &layerSource ) override;
QList< Qgis::RelationshipCardinality > supportedRelationshipCardinalities() const override;
QList< Qgis::RelationshipStrength > supportedRelationshipStrengths() const override;
Expand Down
40 changes: 40 additions & 0 deletions tests/src/python/test_provider_ogr.py
Expand Up @@ -3225,6 +3225,46 @@ def test_provider_connection_set_field_alias(self):
fields = layer.fields()
self.assertEqual(fields['my_field'].alias(), 'my alias')

@unittest.skipIf(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(3, 7, 0), "GDAL 3.7 required")
def test_provider_connection_set_field_comment(self):
"""
Test setting field comments via the connections api
"""
metadata = QgsProviderRegistry.instance().providerMetadata('ogr')
with tempfile.TemporaryDirectory() as temp_dir:
tmpfile = os.path.join(temp_dir, 'test_gpkg.gpkg')

ok, err = metadata.createDatabase(tmpfile)
self.assertTrue(ok)
self.assertFalse(err)

conn = metadata.createConnection(tmpfile, {})
self.assertTrue(conn)

fields = QgsFields()
field = QgsField('my_field', QVariant.String)
fields.append(field)
conn.createVectorTable('', 'test', fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem('EPSG:4326'), False, {})
layer = QgsVectorLayer(tmpfile + '|layername=test')
self.assertTrue(layer.isValid())

del layer

self.assertTrue(
conn.capabilities2() & Qgis.DatabaseProviderConnectionCapability2.SetFieldComment)

# field does not exist
with self.assertRaises(QgsProviderConnectionException):
conn.setFieldComment('not field', '', 'test', 'my comment')

conn.setFieldComment('my_field', '', 'test', 'my comment')

layer = QgsVectorLayer(tmpfile + '|layername=test')
self.assertTrue(layer.isValid())

fields = layer.fields()
self.assertEqual(fields['my_field'].comment(), 'my comment')

@unittest.skipIf(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(3, 7, 0), "GDAL 3.7 required")
def test_provider_set_field_alias(self):
"""
Expand Down

0 comments on commit a1345f0

Please sign in to comment.