Skip to content

Commit a1345f0

Browse files
committedApr 18, 2023
Add support for setting field comments to OGR provider connection
1 parent d798fd0 commit a1345f0

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed
 

‎src/core/providers/ogr/qgsogrproviderconnection.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,10 @@ void QgsOgrProviderConnection::setDefaultCapabilities()
453453
{
454454
mCapabilities2 |= Qgis::DatabaseProviderConnectionCapability2::SetFieldAlias;
455455
}
456+
if ( CSLFindString( papszTokens, "Comment" ) >= 0 )
457+
{
458+
mCapabilities2 |= Qgis::DatabaseProviderConnectionCapability2::SetFieldComment;
459+
}
456460
#endif
457461

458462
CSLDestroy( papszTokens );
@@ -1061,6 +1065,46 @@ void QgsOgrProviderConnection::setFieldAlias( const QString &fieldName, const QS
10611065
#endif
10621066
}
10631067

1068+
void QgsOgrProviderConnection::setFieldComment( const QString &fieldName, const QString &schema, const QString &tableName, const QString &comment ) const
1069+
{
1070+
#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,7,0)
1071+
if ( ! schema.isEmpty() )
1072+
{
1073+
QgsMessageLog::logMessage( QStringLiteral( "Schema is not supported by OGR, ignoring" ), QStringLiteral( "OGR" ), Qgis::MessageLevel::Info );
1074+
}
1075+
1076+
QString errCause;
1077+
QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( uri(),
1078+
true,
1079+
QStringList(),
1080+
tableName, errCause, true );
1081+
if ( !layer )
1082+
{
1083+
throw QgsProviderConnectionException( QObject::tr( "There was an error opening the dataset: %1" ).arg( errCause ) );
1084+
}
1085+
1086+
//type does not matter, it will not be used
1087+
gdal::ogr_field_def_unique_ptr fld( OGR_Fld_Create( fieldName.toUtf8().constData(), OFTReal ) );
1088+
OGR_Fld_SetComment( fld.get(), comment.toUtf8().constData() );
1089+
1090+
const int fieldIndex = layer->GetLayerDefn().GetFieldIndex( fieldName.toUtf8().constData() );
1091+
if ( fieldIndex < 0 )
1092+
{
1093+
throw QgsProviderConnectionException( QObject::tr( "Could not set comment for %1 - field does not exist" ).arg( fieldName ) );
1094+
}
1095+
if ( layer->AlterFieldDefn( fieldIndex, fld.get(), ALTER_COMMENT_FLAG ) != OGRERR_NONE )
1096+
{
1097+
throw QgsProviderConnectionException( QObject::tr( "Could not set comment: %1" ).arg( CPLGetLastErrorMsg() ) );
1098+
}
1099+
#else
1100+
( void )fieldName;
1101+
( void )schema;
1102+
( void )tableName;
1103+
( void )comment;
1104+
throw QgsProviderConnectionException( QObject::tr( "Setting field comments for datasets requires GDAL 3.7 or later" ) );
1105+
#endif
1106+
}
1107+
10641108
QgsAbstractDatabaseProviderConnection::SqlVectorLayerOptions QgsOgrProviderConnection::sqlOptions( const QString &layerSource )
10651109
{
10661110
SqlVectorLayerOptions options;

‎src/core/providers/ogr/qgsogrproviderconnection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class QgsOgrProviderConnection : public QgsAbstractDatabaseProviderConnection
9090
void addFieldDomain( const QgsFieldDomain &domain, const QString &schema ) const override;
9191
void renameField( const QString &schema, const QString &tableName, const QString &name, const QString &newName ) const override;
9292
void setFieldAlias( const QString &fieldName, const QString &schema, const QString &tableName, const QString &alias ) const override;
93+
void setFieldComment( const QString &fieldName, const QString &schema, const QString &tableName, const QString &comment ) const override;
9394
SqlVectorLayerOptions sqlOptions( const QString &layerSource ) override;
9495
QList< Qgis::RelationshipCardinality > supportedRelationshipCardinalities() const override;
9596
QList< Qgis::RelationshipStrength > supportedRelationshipStrengths() const override;

‎tests/src/python/test_provider_ogr.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3225,6 +3225,46 @@ def test_provider_connection_set_field_alias(self):
32253225
fields = layer.fields()
32263226
self.assertEqual(fields['my_field'].alias(), 'my alias')
32273227

3228+
@unittest.skipIf(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(3, 7, 0), "GDAL 3.7 required")
3229+
def test_provider_connection_set_field_comment(self):
3230+
"""
3231+
Test setting field comments via the connections api
3232+
"""
3233+
metadata = QgsProviderRegistry.instance().providerMetadata('ogr')
3234+
with tempfile.TemporaryDirectory() as temp_dir:
3235+
tmpfile = os.path.join(temp_dir, 'test_gpkg.gpkg')
3236+
3237+
ok, err = metadata.createDatabase(tmpfile)
3238+
self.assertTrue(ok)
3239+
self.assertFalse(err)
3240+
3241+
conn = metadata.createConnection(tmpfile, {})
3242+
self.assertTrue(conn)
3243+
3244+
fields = QgsFields()
3245+
field = QgsField('my_field', QVariant.String)
3246+
fields.append(field)
3247+
conn.createVectorTable('', 'test', fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem('EPSG:4326'), False, {})
3248+
layer = QgsVectorLayer(tmpfile + '|layername=test')
3249+
self.assertTrue(layer.isValid())
3250+
3251+
del layer
3252+
3253+
self.assertTrue(
3254+
conn.capabilities2() & Qgis.DatabaseProviderConnectionCapability2.SetFieldComment)
3255+
3256+
# field does not exist
3257+
with self.assertRaises(QgsProviderConnectionException):
3258+
conn.setFieldComment('not field', '', 'test', 'my comment')
3259+
3260+
conn.setFieldComment('my_field', '', 'test', 'my comment')
3261+
3262+
layer = QgsVectorLayer(tmpfile + '|layername=test')
3263+
self.assertTrue(layer.isValid())
3264+
3265+
fields = layer.fields()
3266+
self.assertEqual(fields['my_field'].comment(), 'my comment')
3267+
32283268
@unittest.skipIf(int(gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(3, 7, 0), "GDAL 3.7 required")
32293269
def test_provider_set_field_alias(self):
32303270
"""

0 commit comments

Comments
 (0)
Please sign in to comment.