Skip to content

Commit

Permalink
Add api to retrieve illegal field names via connections api
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 30, 2022
1 parent 7a3a57a commit 026f3cd
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
Expand Up @@ -724,6 +724,14 @@ The default implementation returns an list of common reserved words under the
Subclasses should add provider- and/or connection- specific words.

.. versionadded:: 3.22
%End

virtual QSet< QString > illegalFieldNames() const;
%Docstring
Returns a list of field names which are considered illegal by the connection and
should not be used when creating or altering fields.

.. versionadded:: 3.30
%End

virtual QStringList fieldDomainNames() const throw( QgsProviderConnectionException );
Expand Down
46 changes: 46 additions & 0 deletions src/core/providers/ogr/qgsogrproviderconnection.cpp
Expand Up @@ -542,6 +542,52 @@ void QgsOgrProviderConnection::setDefaultCapabilities()
}
#endif

#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,7,0)
if ( const char *pszIllegalFieldNames = GDALGetMetadataItem( hDriver, GDAL_DMD_ILLEGAL_FIELD_NAMES, nullptr ) )
{
char **papszTokens = CSLTokenizeString2( pszIllegalFieldNames, " ", 0 );
const QStringList illegalFieldNames = QgsOgrUtils::cStringListToQStringList( papszTokens );
for ( const QString &name : illegalFieldNames )
mIllegalFieldNames.insert( name );
CSLDestroy( papszTokens );
}
#else
if ( mDriverName == QLatin1String( "OpenFileGDB" ) || mDriverName == QLatin1String( "FileGDB" ) )
{
mIllegalFieldNames =
{
QStringLiteral( "ADD" ),
QStringLiteral( "ALTER" ),
QStringLiteral( "AND" ),
QStringLiteral( "BETWEEN" ),
QStringLiteral( "BY" ),
QStringLiteral( "COLUMN" ),
QStringLiteral( "CREATE" ),
QStringLiteral( "DELETE" ),
QStringLiteral( "DROP" ),
QStringLiteral( "EXISTS" ),
QStringLiteral( "FOR" ),
QStringLiteral( "FROM" ),
QStringLiteral( "GROUP" ),
QStringLiteral( "IN" ),
QStringLiteral( "INSERT" ),
QStringLiteral( "INTO" ),
QStringLiteral( "IS" ),
QStringLiteral( "LIKE" ),
QStringLiteral( "NOT" ),
QStringLiteral( "NULL" ),
QStringLiteral( "OR" ),
QStringLiteral( "ORDER" ),
QStringLiteral( "SELECT" ),
QStringLiteral( "SET" ),
QStringLiteral( "TABLE" ),
QStringLiteral( "UPDATE" ),
QStringLiteral( "VALUES" ),
QStringLiteral( "WHERE" )
};
}
#endif

mSqlLayerDefinitionCapabilities =
{
Qgis::SqlLayerDefinitionCapability::SubsetStringFilter,
Expand Down
5 changes: 5 additions & 0 deletions src/core/providers/qgsabstractdatabaseproviderconnection.cpp
Expand Up @@ -1015,6 +1015,11 @@ QMultiMap<Qgis::SqlKeywordCategory, QStringList> QgsAbstractDatabaseProviderConn
};
}

QSet<QString> QgsAbstractDatabaseProviderConnection::illegalFieldNames() const
{
return mIllegalFieldNames;
}

QList<Qgis::FieldDomainType> QgsAbstractDatabaseProviderConnection::supportedFieldDomainTypes() const
{
return {};
Expand Down
9 changes: 9 additions & 0 deletions src/core/providers/qgsabstractdatabaseproviderconnection.h
Expand Up @@ -839,6 +839,14 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv
*/
virtual QMultiMap<Qgis::SqlKeywordCategory, QStringList> sqlDictionary();

/**
* Returns a list of field names which are considered illegal by the connection and
* should not be used when creating or altering fields.
*
* \since QGIS 3.30
*/
virtual QSet< QString > illegalFieldNames() const;

/**
* Returns a list of field domain names present on the provider.
*
Expand Down Expand Up @@ -1078,6 +1086,7 @@ class CORE_EXPORT QgsAbstractDatabaseProviderConnection : public QgsAbstractProv
GeometryColumnCapabilities mGeometryColumnCapabilities = GeometryColumnCapabilities() SIP_SKIP;
Qgis::SqlLayerDefinitionCapabilities mSqlLayerDefinitionCapabilities = Qgis::SqlLayerDefinitionCapabilities() SIP_SKIP;
QString mProviderKey;
QSet<QString> mIllegalFieldNames SIP_SKIP;

};

Expand Down
15 changes: 15 additions & 0 deletions tests/src/python/test_provider_ogr.py
Expand Up @@ -2814,6 +2814,21 @@ def test_provider_connection_tables(self):
'GDB_ItemRelationships', 'GDB_ItemTypes', 'GDB_Items',
'GDB_SpatialRefs', 'GDB_SystemCatalog'])

def test_provider_connection_illegal_fields(self):
"""
Test retrieving illegal field names via the connections API
"""
metadata = QgsProviderRegistry.instance().providerMetadata('ogr')
# start with a connection which only supports one layer
conn = metadata.createConnection(TEST_DATA_DIR + '/' + 'relationships.gdb', {})
self.assertTrue(conn)

self.assertEqual(conn.illegalFieldNames(),
{'ALTER', 'NULL', 'UPDATE', 'LIKE', 'FROM', 'WHERE', 'INSERT', 'CREATE',
'EXISTS', 'ORDER', 'DROP', 'TABLE', 'BETWEEN', 'SELECT', 'FOR', 'ADD',
'IS', 'GROUP', 'COLUMN', 'DELETE', 'VALUES', 'IN', 'NOT', 'BY', 'OR',
'INTO', 'AND', 'SET'})

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

0 comments on commit 026f3cd

Please sign in to comment.