Skip to content

Commit

Permalink
Retrieve fields' comments in HANA
Browse files Browse the repository at this point in the history
  • Loading branch information
mrylov authored and nyalldawson committed May 4, 2021
1 parent 7e060a8 commit 3ea7443
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 22 deletions.
76 changes: 57 additions & 19 deletions src/providers/hana/qgshanaconnection.cpp
Expand Up @@ -101,7 +101,7 @@ QgsField AttributeField::toQgsField() const
break;
}

QgsField field = QgsField( name, fieldType, typeName, size, precision, QString(), QVariant::Invalid );
QgsField field = QgsField( name, fieldType, typeName, size, precision, comment, QVariant::Invalid );
if ( !isNullable || isAutoIncrement )
{
QgsFieldConstraints constraints;
Expand Down Expand Up @@ -633,24 +633,62 @@ void QgsHanaConnection::readLayerInfo( QgsHanaLayerProperty &layerProperty )
layerProperty.pkCols = getPrimaryKeyCandidates( layerProperty );
}

void QgsHanaConnection::readQueryFields( const QString &sql, const std::function<void( const AttributeField &field )> &callback )
{
PreparedStatementRef stmt = prepareStatement( sql );
ResultSetMetaDataUnicodeRef rsmd = stmt->getMetaDataUnicode();
for ( unsigned short i = 1; i <= rsmd->getColumnCount(); ++i )
{
AttributeField field;
field.schemaName = QString::fromStdU16String( rsmd->getSchemaName( i ) );
field.tableName = QString::fromStdU16String( rsmd->getTableName( i ) );
field.name = QString::fromStdU16String( rsmd->getColumnName( i ) );
field.typeName = QString::fromStdU16String( rsmd->getColumnTypeName( i ) );
field.type = rsmd->getColumnType( i );
field.isSigned = rsmd->isSigned( i );
field.isNullable = rsmd->isNullable( i );
field.isAutoIncrement = rsmd->isAutoIncrement( i );
field.size = static_cast<int>( rsmd->getColumnLength( i ) );
field.precision = -1;
callback( field );
void QgsHanaConnection::readQueryFields( const QString &sql, const QString &schemaName,
const std::function<void( const AttributeField &field )> &callback )
{
QMap<QString, QMap<QString, QString>> clmComments;
auto getColumnComments = [&clmComments, &conn = mConnection]( const QString & schemaName, const QString & tableName, const QString & columnName )
{
if ( schemaName.isEmpty() || tableName.isEmpty() )
return QString();

const QString key = QStringLiteral( "%1.%2" ).arg( schemaName, tableName );
if ( clmComments.contains( key ) )
return clmComments[key].value( columnName );

const char *sql = "SELECT COLUMN_NAME, COMMENTS FROM SYS.TABLE_COLUMNS WHERE SCHEMA_NAME = ? AND TABLE_NAME = ?";
PreparedStatementRef stmt = conn->prepareStatement( sql );
stmt->setNString( 1, NString( schemaName.toStdU16String() ) );
stmt->setNString( 2, NString( tableName.toStdU16String() ) );

ResultSetRef rsColumns = stmt->executeQuery();
while ( rsColumns->next() )
{
QString name = QgsHanaUtils::toQString( rsColumns->getString( 1 ) );
QString comments = QgsHanaUtils::toQString( rsColumns->getString( 2 ) );
clmComments[key].insert( name, comments );
}
rsColumns->close();

return clmComments[key].value( columnName );
};

try
{
PreparedStatementRef stmt = prepareStatement( sql );
ResultSetMetaDataUnicodeRef rsmd = stmt->getMetaDataUnicode();
for ( unsigned short i = 1; i <= rsmd->getColumnCount(); ++i )
{
AttributeField field;
field.schemaName = QString::fromStdU16String( rsmd->getSchemaName( i ) );
field.tableName = QString::fromStdU16String( rsmd->getTableName( i ) );
field.name = QString::fromStdU16String( rsmd->getColumnName( i ) );
field.typeName = QString::fromStdU16String( rsmd->getColumnTypeName( i ) );
field.type = rsmd->getColumnType( i );
field.isSigned = rsmd->isSigned( i );
field.isNullable = rsmd->isNullable( i );
field.isAutoIncrement = rsmd->isAutoIncrement( i );
field.size = static_cast<int>( rsmd->getColumnLength( i ) );
field.precision = -1;
// As field comments cannot be retrieved via ODBC, we get it from SYS.TABLE_COLUMNS.
field.comment = getColumnComments( !field.schemaName.isEmpty() ? field.schemaName : schemaName, field.tableName, field.name );

callback( field );
}
}
catch ( const Exception &ex )
{
throw QgsHanaException( ex.what() );
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/providers/hana/qgshanaconnection.h
Expand Up @@ -40,6 +40,7 @@ struct AttributeField
bool isAutoIncrement;
bool isNullable;
bool isSigned;
QString comment;

QgsField toQgsField() const;
};
Expand Down Expand Up @@ -83,7 +84,7 @@ class QgsHanaConnection : public QObject
bool userTablesOnly = true,
const std::function<bool( const QgsHanaLayerProperty &layer )> &layerFilter = nullptr );
void readLayerInfo( QgsHanaLayerProperty &layerProperty );
void readQueryFields( const QString &sql, const std::function<void( const AttributeField &field )> &callback );
void readQueryFields( const QString &sql, const QString &schemaName, const std::function<void( const AttributeField &field )> &callback );
QVector<QgsHanaSchemaProperty> getSchemas( const QString &ownerName );
QStringList getLayerPrimaryKey( const QString &schemaName, const QString &tableName );
QgsWkbTypes::Type getColumnGeometryType( const QString &schemaName, const QString &tableName, const QString &columnName );
Expand Down
2 changes: 1 addition & 1 deletion src/providers/hana/qgshanaprovider.cpp
Expand Up @@ -1350,7 +1350,7 @@ void QgsHanaProvider::readAttributeFields( QgsHanaConnection &conn )
rsColumns->close();
};

conn.readQueryFields( buildQuery( QStringLiteral( "*" ) ), processField );
conn.readQueryFields( buildQuery( QStringLiteral( "*" ) ), mSchemaName, processField );

determinePrimaryKey( conn );
}
Expand Down
2 changes: 1 addition & 1 deletion src/providers/hana/qgshanaproviderconnection.cpp
Expand Up @@ -424,7 +424,7 @@ QgsFields QgsHanaProviderConnection::fields( const QString &schema, const QStrin
if ( field.name != geometryColumn )
fields.append( field.toQgsField() );
};
conn->readQueryFields( sql, processField );
conn->readQueryFields( sql, schema, processField );
return fields;
}
catch ( const QgsHanaException &ex )
Expand Down

0 comments on commit 3ea7443

Please sign in to comment.