Skip to content

Commit 2632ca6

Browse files
mrylovnyalldawson
authored andcommittedJan 28, 2021
Fix primary key issues in HANA
1 parent c4a69f6 commit 2632ca6

11 files changed

+178
-60
lines changed
 

‎src/providers/hana/qgshanaconnection.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ void QgsHanaConnection::readLayerInfo( QgsHanaLayerProperty &layerProperty )
553553
{
554554
layerProperty.srid = getColumnSrid( layerProperty.schemaName, layerProperty.tableName, layerProperty.geometryColName );
555555
layerProperty.type = getColumnGeometryType( layerProperty.schemaName, layerProperty.tableName, layerProperty.geometryColName );
556-
layerProperty.pkCols = getPrimaryeKeyCandidates( layerProperty );
556+
layerProperty.pkCols = getPrimaryKeyCandidates( layerProperty );
557557
}
558558

559559
QVector<QgsHanaSchemaProperty> QgsHanaConnection::getSchemas( const QString &ownerName )
@@ -585,7 +585,7 @@ QVector<QgsHanaSchemaProperty> QgsHanaConnection::getSchemas( const QString &own
585585
return list;
586586
}
587587

588-
QStringList QgsHanaConnection::getLayerPrimaryeKey( const QString &schemaName, const QString &tableName )
588+
QStringList QgsHanaConnection::getLayerPrimaryKey( const QString &schemaName, const QString &tableName )
589589
{
590590
try
591591
{
@@ -609,7 +609,7 @@ QStringList QgsHanaConnection::getLayerPrimaryeKey( const QString &schemaName, c
609609
}
610610
}
611611

612-
QStringList QgsHanaConnection::getPrimaryeKeyCandidates( const QgsHanaLayerProperty &layerProperty )
612+
QStringList QgsHanaConnection::getPrimaryKeyCandidates( const QgsHanaLayerProperty &layerProperty )
613613
{
614614
if ( !layerProperty.isView )
615615
return QStringList();
@@ -618,6 +618,11 @@ QStringList QgsHanaConnection::getPrimaryeKeyCandidates( const QgsHanaLayerPrope
618618
QgsHanaResultSetRef rsColumns = getColumns( layerProperty.schemaName, layerProperty.tableName, QStringLiteral( "%" ) );
619619
while ( rsColumns->next() )
620620
{
621+
int dataType = rsColumns->getValue( 5/*DATA_TYPE */ ).toInt();
622+
// We exclude GEOMETRY and LOB columns
623+
if ( dataType == 29812 /* GEOMETRY TYPE */ || dataType == SQLDataTypes::LongVarBinary ||
624+
dataType == SQLDataTypes::LongVarChar || dataType == SQLDataTypes::WLongVarChar )
625+
continue;
621626
ret << rsColumns->getValue( 4/*COLUMN_NAME */ ).toString();
622627
}
623628
rsColumns->close();

‎src/providers/hana/qgshanaconnection.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class QgsHanaConnection : public QObject
6666
bool userTablesOnly = true );
6767
void readLayerInfo( QgsHanaLayerProperty &layerProperty );
6868
QVector<QgsHanaSchemaProperty> getSchemas( const QString &ownerName );
69-
QStringList getLayerPrimaryeKey( const QString &schemaName, const QString &tableName );
69+
QStringList getLayerPrimaryKey( const QString &schemaName, const QString &tableName );
7070
QgsWkbTypes::Type getColumnGeometryType( const QString &schemaName, const QString &tableName, const QString &columnName );
7171
QString getColumnDataType( const QString &schemaName, const QString &tableName, const QString &columnName );
7272
int getColumnSrid( const QString &schemaName, const QString &tableName, const QString &columnName );
@@ -82,7 +82,7 @@ class QgsHanaConnection : public QObject
8282
private:
8383
QgsHanaConnection( odbc::ConnectionRef connection, const QgsDataSourceUri &uri );
8484

85-
QStringList getPrimaryeKeyCandidates( const QgsHanaLayerProperty &layerProperty );
85+
QStringList getPrimaryKeyCandidates( const QgsHanaLayerProperty &layerProperty );
8686

8787
odbc::PreparedStatementRef createPreparedStatement( const QString &sql, const QVariantList &args );
8888

‎src/providers/hana/qgshanadataitems.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ QString QgsHanaLayerItem::comments() const
242242

243243
QString QgsHanaLayerItem::createUri() const
244244
{
245-
QString pkColName = !mLayerProperty.pkCols.isEmpty() ? mLayerProperty.pkCols.at( 0 ) : QString();
246245
QgsHanaConnectionItem *connItem = qobject_cast<QgsHanaConnectionItem *>( parent() ?
247246
parent()->parent() : nullptr );
248247

@@ -253,9 +252,26 @@ QString QgsHanaLayerItem::createUri() const
253252
}
254253

255254
QgsHanaSettings settings( connItem->name(), true );
255+
256+
QStringList pkColumns;
257+
if ( !mLayerProperty.pkCols.isEmpty() )
258+
{
259+
const QStringList pkColumnsStored = settings.keyColumns( mLayerProperty.schemaName, mLayerProperty.tableName );
260+
if ( !pkColumnsStored.empty() )
261+
{
262+
// We check whether the primary key columns still exist.
263+
auto intersection = pkColumnsStored.toSet().intersect( mLayerProperty.pkCols.toSet() );
264+
if ( intersection.size() == pkColumnsStored.size() )
265+
{
266+
for ( const auto &column : pkColumnsStored )
267+
pkColumns << QgsHanaUtils::quotedIdentifier( column );
268+
}
269+
}
270+
}
271+
256272
QgsDataSourceUri uri = settings.toDataSourceUri();
257273
uri.setDataSource( mLayerProperty.schemaName, mLayerProperty.tableName,
258-
mLayerProperty.geometryColName, mLayerProperty.sql, pkColName );
274+
mLayerProperty.geometryColName, mLayerProperty.sql, pkColumns.join( ',' ) );
259275
uri.setWkbType( mLayerProperty.type );
260276
if ( uri.wkbType() != QgsWkbTypes::NoGeometry )
261277
uri.setSrid( QString::number( mLayerProperty.srid ) );

‎src/providers/hana/qgshanaprovider.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ void QgsHanaProvider::determinePrimaryKey()
14061406
QgsHanaConnectionRef conn( mUri );
14071407
if ( conn->isTable( mSchemaName, mTableName ) )
14081408
{
1409-
QStringList layerPrimaryKey = conn->getLayerPrimaryeKey( mSchemaName, mTableName );
1409+
QStringList layerPrimaryKey = conn->getLayerPrimaryKey( mSchemaName, mTableName );
14101410
primaryKey = QgsHanaPrimaryKeyUtils::determinePrimaryKeyFromColumns( layerPrimaryKey, mAttributeFields );
14111411
}
14121412
else

‎src/providers/hana/qgshanaproviderconnection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ QList<QgsHanaProviderConnection::TableProperty> QgsHanaProviderConnection::table
338338
}
339339
else // Fetch and set the real pks
340340
{
341-
QStringList pks = conn->getLayerPrimaryeKey( layerInfo.schemaName, layerInfo.tableName );
341+
QStringList pks = conn->getLayerPrimaryKey( layerInfo.schemaName, layerInfo.tableName );
342342
property.setPrimaryKeyColumns( pks );
343343
}
344344
tables.push_back( property );

‎src/providers/hana/qgshanasettings.cpp

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* (at your option) any later version.
1515
*
1616
***************************************************************************/
17+
#include "qgis.h"
1718
#include "qgshanasettings.h"
1819
#include "qgssettings.h"
1920

@@ -48,6 +49,19 @@ QString QgsHanaSettings::port() const
4849
return mIdentifier;
4950
}
5051

52+
QStringList QgsHanaSettings::keyColumns( const QString &schemaName, const QString &objectName ) const
53+
{
54+
return mKeyColumns.value( schemaName ).value( objectName );
55+
}
56+
57+
void QgsHanaSettings::setKeyColumns( const QString &schemaName, const QString &objectName, const QStringList &columnNames )
58+
{
59+
if ( columnNames.empty() )
60+
mKeyColumns[schemaName].remove( objectName );
61+
else
62+
mKeyColumns[schemaName][objectName] = columnNames;
63+
}
64+
5165
void QgsHanaSettings::setFromDataSourceUri( const QgsDataSourceUri &uri )
5266
{
5367
mDriver = uri.driver();
@@ -102,6 +116,7 @@ QgsDataSourceUri QgsHanaSettings::toDataSourceUri() const
102116
uri.setConnection( mHost, port(), mDatabase, mUserName, mPassword );
103117
uri.setDriver( mDriver );
104118
uri.setSchema( mSchema );
119+
105120
if ( mSslEnabled )
106121
{
107122
uri.setParam( QStringLiteral( "sslEnabled" ), QStringLiteral( "true" ) );
@@ -122,7 +137,7 @@ QgsDataSourceUri QgsHanaSettings::toDataSourceUri() const
122137
void QgsHanaSettings::load()
123138
{
124139
QgsSettings settings;
125-
QString key = path();
140+
const QString key = path();
126141
mDriver = settings.value( key + "/driver" ).toString();
127142
mHost = settings.value( key + "/host" ).toString();
128143
mIdentifierType = settings.value( key + "/identifierType" ).toUInt();
@@ -145,11 +160,33 @@ void QgsHanaSettings::load()
145160
mSslTrustStore = settings.value( key + "/sslTrustStore" ).toString();
146161
mSslValidateCertificate = settings.value( key + "/sslValidateCertificate", true ).toBool();
147162
mSslHostNameInCertificate = settings.value( key + "/sslHostNameInCertificate" ).toString();
163+
164+
const QString keysPath = key + "/keys";
165+
settings.beginGroup( keysPath );
166+
const QStringList schemaNames = settings.childGroups();
167+
if ( !schemaNames.empty() )
168+
{
169+
for ( const QString &schemaName : schemaNames )
170+
{
171+
const QString schemaKey = keysPath + "/" + schemaName;
172+
QgsSettings subSettings;
173+
subSettings.beginGroup( schemaKey );
174+
const QStringList objectNames = subSettings.childKeys();
175+
if ( objectNames.empty() )
176+
continue;
177+
for ( const QString &objectName : objectNames )
178+
{
179+
QVariant value = subSettings.value( objectName );
180+
if ( !value.isNull() )
181+
mKeyColumns[schemaName][objectName] = value.toStringList();
182+
}
183+
}
184+
}
148185
}
149186

150187
void QgsHanaSettings::save()
151188
{
152-
QString key( path() );
189+
const QString key( path() );
153190
QgsSettings settings;
154191
settings.setValue( key + "/driver", mDriver );
155192
settings.setValue( key + "/host", mHost );
@@ -171,12 +208,32 @@ void QgsHanaSettings::save()
171208
settings.setValue( key + "/sslTrustStore", mSslTrustStore );
172209
settings.setValue( key + "/sslValidateCertificate", mSslValidateCertificate );
173210
settings.setValue( key + "/sslHostNameInCertificate", mSslHostNameInCertificate );
211+
212+
if ( !mKeyColumns.empty() )
213+
{
214+
const QString keysPath = key + "/keys/";
215+
settings.beginGroup( keysPath );
216+
const QStringList schemaNames = mKeyColumns.keys();
217+
for ( const QString &schemaName : schemaNames )
218+
{
219+
const auto &schemaKeys = mKeyColumns[schemaName];
220+
if ( schemaKeys.empty() )
221+
continue;
222+
const QStringList objectNames = schemaKeys.keys();
223+
settings.beginGroup( schemaName );
224+
for ( const QString &objectName : objectNames )
225+
settings.setValue( objectName, schemaKeys[objectName] );
226+
settings.endGroup();
227+
}
228+
settings.endGroup();
229+
}
230+
174231
settings.sync();
175232
}
176233

177234
void QgsHanaSettings::removeConnection( const QString &name )
178235
{
179-
QString key( getBaseKey() + name );
236+
const QString key( getBaseKey() + name );
180237
QgsSettings settings;
181238
settings.remove( key + "/driver" );
182239
settings.remove( key + "/host" );
@@ -198,6 +255,7 @@ void QgsHanaSettings::removeConnection( const QString &name )
198255
settings.remove( key + "/sslTrustStore" );
199256
settings.remove( key + "/sslValidateCertificate" );
200257
settings.remove( key + "/sslHostNameInCertificate" );
258+
settings.remove( key + "/keys" );
201259
settings.remove( key );
202260
settings.sync();
203261
}

‎src/providers/hana/qgshanasettings.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@ class QgsHanaSettings
182182
*/
183183
QString port() const;
184184

185+
/**
186+
* Gets the key columns for the given database object.
187+
*/
188+
QStringList keyColumns( const QString &schemaName, const QString &objectName ) const;
189+
190+
/**
191+
* Sets the key columns for the given database object.
192+
*/
193+
void setKeyColumns( const QString &schemaName, const QString &objectName, const QStringList &columnNames );
194+
185195
/**
186196
* Sets values from a RDBMS data source URI.
187197
*/
@@ -234,6 +244,7 @@ class QgsHanaSettings
234244
QString mSslTrustStore;
235245
bool mSslValidateCertificate = false;
236246
QString mSslHostNameInCertificate;
247+
QMap<QString, QMap<QString, QStringList>> mKeyColumns;
237248
};
238249

239250
#endif // QGSHANAPSETTINGS_H

‎src/providers/hana/qgshanasourceselect.cpp

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ void QgsHanaSourceSelect::mSearchModeComboBox_currentIndexChanged( const QString
457457

458458
void QgsHanaSourceSelect::setLayerType( const QgsHanaLayerProperty &layerProperty )
459459
{
460-
mTableModel.addTableEntry( layerProperty );
460+
mTableModel.addTableEntry( mConnectionName, layerProperty );
461461
}
462462

463463
QgsHanaSourceSelect::~QgsHanaSourceSelect()
@@ -495,6 +495,16 @@ void QgsHanaSourceSelect::populateConnectionList()
495495
cmbConnections->setDisabled( cmbConnections->count() == 0 );
496496
}
497497

498+
QStringList QgsHanaSourceSelect::selectedTables()
499+
{
500+
return mSelectedTables;
501+
}
502+
503+
QString QgsHanaSourceSelect::connectionInfo()
504+
{
505+
return mConnectionInfo;
506+
}
507+
498508
// Slot for performing action when the Add button is clicked
499509
void QgsHanaSourceSelect::addButtonClicked()
500510
{
@@ -506,7 +516,7 @@ void QgsHanaSourceSelect::addButtonClicked()
506516
if ( idx.column() != QgsHanaTableModel::DbtmTable )
507517
continue;
508518

509-
QString uri = mTableModel.layerURI( mProxyModel.mapToSource( idx ), QgsHanaUtils::connectionInfo( mDataSrcUri ) );
519+
QString uri = mTableModel.layerURI( mProxyModel.mapToSource( idx ), mConnectionName, mConnectionInfo );
510520
if ( uri.isNull() )
511521
continue;
512522

@@ -536,10 +546,11 @@ void QgsHanaSourceSelect::btnConnect_clicked()
536546
return;
537547
}
538548

549+
const QString connName = cmbConnections->currentText();
550+
539551
QModelIndex rootItemIndex = mTableModel.indexFromItem( mTableModel.invisibleRootItem() );
540552
mTableModel.removeRows( 0, mTableModel.rowCount( rootItemIndex ), rootItemIndex );
541553

542-
const QString connName = cmbConnections->currentText();
543554
QgsHanaSettings settings( connName, true );
544555
settings.setAllowGeometrylessTables( cbxAllowGeometrylessTables->isChecked() );
545556

@@ -554,12 +565,13 @@ void QgsHanaSourceSelect::btnConnect_clicked()
554565
return;
555566
}
556567

557-
mDataSrcUri = uri;
568+
mConnectionName = connName;
569+
mConnectionInfo = QgsHanaUtils::connectionInfo( uri );
558570

559571
QApplication::setOverrideCursor( Qt::BusyCursor );
560572

561-
mColumnTypeThread = qgis::make_unique<QgsHanaColumnTypeThread>( settings.name(), uri, settings.allowGeometrylessTables(), settings.userTablesOnly() );
562-
mColumnTypeTask = qgis::make_unique<QgsProxyProgressTask>( tr( "Scanning tables for %1" ).arg( cmbConnections->currentText() ) );
573+
mColumnTypeThread = qgis::make_unique<QgsHanaColumnTypeThread>( mConnectionName, uri, settings.allowGeometrylessTables(), settings.userTablesOnly() );
574+
mColumnTypeTask = qgis::make_unique<QgsProxyProgressTask>( tr( "Scanning tables for %1" ).arg( mConnectionName ) );
563575
QgsApplication::taskManager()->addTask( mColumnTypeTask.get() );
564576

565577
connect( mColumnTypeThread.get(), &QgsHanaColumnTypeThread::setLayerType,
@@ -597,16 +609,6 @@ void QgsHanaSourceSelect::columnThreadFinished()
597609
finishList();
598610
}
599611

600-
QStringList QgsHanaSourceSelect::selectedTables()
601-
{
602-
return mSelectedTables;
603-
}
604-
605-
QString QgsHanaSourceSelect::connectionInfo()
606-
{
607-
return QgsHanaUtils::connectionInfo( mDataSrcUri );
608-
}
609-
610612
void QgsHanaSourceSelect::refresh()
611613
{
612614
populateConnectionList();
@@ -621,7 +623,7 @@ void QgsHanaSourceSelect::setSql( const QModelIndex &index )
621623
}
622624

623625
QModelIndex idx = mProxyModel.mapToSource( index );
624-
QString uri = mTableModel.layerURI( idx, QgsHanaUtils::connectionInfo( mDataSrcUri ) );
626+
QString uri = mTableModel.layerURI( idx, mConnectionName, mConnectionInfo );
625627
if ( uri.isNull() )
626628
{
627629
QgsDebugMsg( "no uri" );

‎src/providers/hana/qgshanasourceselect.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ class QgsHanaSourceSelect : public QgsAbstractDataSourceWidget, private Ui::QgsD
144144
void finishList();
145145
void showHelp();
146146

147-
QgsDataSourceUri mDataSrcUri;
147+
QString mConnectionName;
148+
QString mConnectionInfo;
148149
// A thread for detecting geometry types
149150
std::unique_ptr<QgsHanaColumnTypeThread> mColumnTypeThread;
150151
std::unique_ptr<QgsProxyProgressTask> mColumnTypeTask;

‎src/providers/hana/qgshanatablemodel.cpp

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "qgsdataitem.h"
1919
#include "qgsdatasourceuri.h"
2020
#include "qgshanatablemodel.h"
21+
#include "qgshanasettings.h"
22+
#include "qgshanautils.h"
2123
#include "qgslogger.h"
2224

2325
QgsHanaTableModel::QgsHanaTableModel()
@@ -35,21 +37,25 @@ QgsHanaTableModel::QgsHanaTableModel()
3537
setHorizontalHeaderLabels( headerLabels );
3638
}
3739

38-
void QgsHanaTableModel::addTableEntry( const QgsHanaLayerProperty &layerProperty )
40+
void QgsHanaTableModel::addTableEntry( const QString &connName, const QgsHanaLayerProperty &layerProperty )
3941
{
4042
QgsWkbTypes::Type wkbType = layerProperty.type;
4143
int srid = layerProperty.srid;
4244

4345
if ( wkbType == QgsWkbTypes::Unknown && layerProperty.geometryColName.isEmpty() )
4446
wkbType = QgsWkbTypes::NoGeometry;
4547

48+
bool withTipButSelectable = false;
4649
QString tip;
4750
if ( wkbType == QgsWkbTypes::Unknown )
4851
tip = tr( "Specify a geometry type in the '%1' column" ).arg( tr( "Data Type" ) );
4952
else if ( wkbType != QgsWkbTypes::NoGeometry && srid == std::numeric_limits<int>::min() )
5053
tip = tr( "Enter a SRID into the '%1' column" ).arg( tr( "SRID" ) );
51-
else if ( layerProperty.pkCols.size() > 1 )
54+
else if ( !layerProperty.pkCols.empty() )
55+
{
5256
tip = tr( "Select columns in the '%1' column that uniquely identify features of this layer" ).arg( tr( "Feature id" ) );
57+
withTipButSelectable = true;
58+
}
5359

5460
QStandardItem *schemaNameItem = new QStandardItem( layerProperty.schemaName );
5561
QStandardItem *typeItem = new QStandardItem( iconForWkbType( wkbType ),
@@ -70,26 +76,34 @@ void QgsHanaTableModel::addTableEntry( const QgsHanaLayerProperty &layerProperty
7076
sridItem->setFlags( sridItem->flags() | Qt::ItemIsEditable );
7177
}
7278

73-
QString pkText;
74-
QString pkCol;
75-
switch ( layerProperty.pkCols.size() )
79+
QStandardItem *pkItem = new QStandardItem( QString() );
80+
if ( !layerProperty.pkCols.isEmpty() )
7681
{
77-
case 0:
78-
break;
79-
case 1:
80-
pkText = layerProperty.pkCols[0];
81-
pkCol = pkText;
82-
break;
83-
default:
84-
pkText = tr( "Select…" );
85-
break;
82+
pkItem->setText( tr( "Select…" ) );
83+
pkItem->setFlags( pkItem->flags() | Qt::ItemIsEditable );
8684
}
85+
else
86+
pkItem->setFlags( pkItem->flags() & ~Qt::ItemIsEditable );
8787

88-
QStandardItem *pkItem = new QStandardItem( pkText );
89-
if ( layerProperty.pkCols.size() > 1 )
90-
pkItem->setFlags( pkItem->flags() | Qt::ItemIsEditable );
9188
pkItem->setData( layerProperty.pkCols, Qt::UserRole + 1 );
92-
pkItem->setData( pkCol, Qt::UserRole + 2 );
89+
90+
QgsHanaSettings settings( connName, true );
91+
QStringList pkColumns;
92+
if ( !layerProperty.pkCols.isEmpty() )
93+
{
94+
QStringList pkColumnsStored = settings.keyColumns( layerProperty.schemaName, layerProperty.tableName );
95+
if ( !pkColumnsStored.empty() )
96+
{
97+
// We check whether the primary key columns still exist.
98+
auto intersection = pkColumnsStored.toSet().intersect( layerProperty.pkCols.toSet() );
99+
if ( intersection.size() == pkColumnsStored.size() )
100+
pkColumns = pkColumnsStored;
101+
}
102+
}
103+
104+
pkItem->setData( pkColumns, Qt::UserRole + 2 );
105+
if ( !pkColumns.isEmpty() )
106+
pkItem->setText( pkColumns.join( ',' ) );
93107

94108
QStandardItem *selItem = new QStandardItem( QString( ) );
95109
selItem->setFlags( selItem->flags() | Qt::ItemIsUserCheckable );
@@ -113,15 +127,17 @@ void QgsHanaTableModel::addTableEntry( const QgsHanaLayerProperty &layerProperty
113127

114128
for ( QStandardItem *item : qgis::as_const( childItemList ) )
115129
{
130+
if ( tip.isEmpty() || withTipButSelectable )
131+
item->setFlags( item->flags() | Qt::ItemIsSelectable );
132+
else
133+
item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
134+
116135
if ( tip.isEmpty() )
117136
{
118-
item->setFlags( item->flags() | Qt::ItemIsSelectable );
119137
item->setToolTip( QString( ) );
120138
}
121139
else
122140
{
123-
item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
124-
125141
if ( item == schemaNameItem )
126142
item->setData( QgsApplication::getThemeIcon( QStringLiteral( "/mIconWarning.svg" ) ), Qt::DecorationRole );
127143

@@ -283,7 +299,7 @@ bool QgsHanaTableModel::setData( const QModelIndex &idx, const QVariant &value,
283299
return true;
284300
}
285301

286-
QString QgsHanaTableModel::layerURI( const QModelIndex &index, const QString &connInfo )
302+
QString QgsHanaTableModel::layerURI( const QModelIndex &index, const QString &connName, const QString &connInfo )
287303
{
288304
if ( !index.isValid() )
289305
return QString();
@@ -294,16 +310,25 @@ QString QgsHanaTableModel::layerURI( const QModelIndex &index, const QString &co
294310
return QString();
295311

296312
QStandardItem *pkItem = itemFromIndex( index.sibling( index.row(), DbtmPkCol ) );
297-
QString pkColumnName = pkItem->data( Qt::UserRole + 2 ).toString();
298-
299-
if ( !pkItem->data( Qt::UserRole + 1 ).toStringList().isEmpty() &&
300-
!pkItem->data( Qt::UserRole + 1 ).toStringList().contains( pkColumnName ) )
301-
// no valid primary candidate selected
313+
const QSet<QString> pkColumnsAll( qgis::listToSet( pkItem->data( Qt::UserRole + 1 ).toStringList() ) );
314+
const QSet<QString> pkColumnsSelected( qgis::listToSet( pkItem->data( Qt::UserRole + 2 ).toStringList() ) );
315+
if ( !pkColumnsAll.isEmpty() && !pkColumnsAll.intersects( pkColumnsSelected ) )
316+
{
317+
QgsDebugMsg( QStringLiteral( "no pk candidate selected" ) );
302318
return QString();
319+
}
303320

304321
QString schemaName = index.sibling( index.row(), DbtmSchema ).data( Qt::DisplayRole ).toString();
305322
QString tableName = index.sibling( index.row(), DbtmTable ).data( Qt::DisplayRole ).toString();
306323

324+
QgsHanaSettings settings( connName, true );
325+
settings.setKeyColumns( schemaName, tableName, pkColumnsSelected.toList() );
326+
settings.save();
327+
328+
QStringList pkColumns;
329+
for ( const QString &column : pkColumnsSelected )
330+
pkColumns << QgsHanaUtils::quotedIdentifier( column );
331+
307332
QString geomColumnName;
308333
QString srid;
309334
if ( wkbType != QgsWkbTypes::NoGeometry )
@@ -321,7 +346,7 @@ QString QgsHanaTableModel::layerURI( const QModelIndex &index, const QString &co
321346
QString sql = index.sibling( index.row(), DbtmSql ).data( Qt::DisplayRole ).toString();
322347

323348
QgsDataSourceUri uri( connInfo );
324-
uri.setDataSource( schemaName, tableName, geomColumnName, sql, pkColumnName );
349+
uri.setDataSource( schemaName, tableName, geomColumnName, sql, pkColumns.join( ',' ) );
325350
uri.setWkbType( wkbType );
326351
uri.setSrid( srid );
327352
uri.disableSelectAtId( !selectAtId );

‎src/providers/hana/qgshanatablemodel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class QgsHanaTableModel : public QStandardItemModel
6666
QgsHanaTableModel();
6767

6868
//! Adds entry for one database table to the model
69-
void addTableEntry( const QgsHanaLayerProperty &property );
69+
void addTableEntry( const QString &connName, const QgsHanaLayerProperty &property );
7070

7171
//! Sets an sql statement that belongs to a cell specified by a model index
7272
void setSql( const QModelIndex &index, const QString &sql );
@@ -90,7 +90,7 @@ class QgsHanaTableModel : public QStandardItemModel
9090

9191
bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) override;
9292

93-
QString layerURI( const QModelIndex &index, const QString &connInfo );
93+
QString layerURI( const QModelIndex &index, const QString &connName, const QString &connInfo );
9494

9595
static QIcon iconForWkbType( QgsWkbTypes::Type type );
9696

0 commit comments

Comments
 (0)
Please sign in to comment.