Skip to content

Commit

Permalink
Retrieve real primary keys columns
Browse files Browse the repository at this point in the history
  • Loading branch information
troopa81 authored and nyalldawson committed Jan 29, 2021
1 parent 2fc9048 commit d79ade0
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 25 deletions.
27 changes: 27 additions & 0 deletions src/providers/oracle/qgsoracleconn.cpp
Expand Up @@ -1058,6 +1058,33 @@ QString QgsOracleConn::createSpatialIndex( const QString &ownerName, const QStri
return QString( "QGIS_IDX_%1" ).arg( n, 10, 10, QChar( '0' ) );
}

QStringList QgsOracleConn::getPrimaryKeys( const QString &ownerName, const QString &tableName )
{
QSqlQuery qry( mDatabase );

QStringList result;

if ( !exec( qry, QString( "SELECT column_name"
" FROM all_cons_columns a"
" JOIN all_constraints b ON a.constraint_name=b.constraint_name AND a.owner=b.owner"
" WHERE b.constraint_type='P' AND b.owner=? AND b.table_name=?" ),
QVariantList() << ownerName << tableName ) )
{
QgsMessageLog::logMessage( tr( "Unable to execute the query.\nThe error message from the database was:\n%1.\nSQL: %2" )
.arg( qry.lastError().text() )
.arg( qry.lastQuery() ), tr( "Oracle" ) );
return result;
}

while ( qry.next() )
{
QString name = qry.value( 0 ).toString();
result << name;
}

return result;
}


QgsPoolOracleConn::QgsPoolOracleConn( const QString &connInfo )
: mConn( QgsOracleConnPool::instance()->acquireConnection( connInfo ) )
Expand Down
5 changes: 5 additions & 0 deletions src/providers/oracle/qgsoracleconn.h
Expand Up @@ -224,6 +224,11 @@ class QgsOracleConn : public QObject
*/
QString createSpatialIndex( const QString &ownerName, const QString &tableName, const QString &geometryColumn );

/**
* Returns list of defined primary keys for \a tableName table in \a ownerName schema/user
*/
QStringList getPrimaryKeys( const QString &ownerName, const QString &tableName );

static const int sGeomTypeSelectLimit;

static QgsWkbTypes::Type wkbTypeFromDatabase( int gtype );
Expand Down
16 changes: 2 additions & 14 deletions src/providers/oracle/qgsoracleprovider.cpp
Expand Up @@ -851,24 +851,12 @@ bool QgsOracleProvider::determinePrimaryKey()
QSqlQuery qry( *conn );
if ( !mIsQuery )
{
if ( !exec( qry, QString( "SELECT column_name"
" FROM all_cons_columns a"
" JOIN all_constraints b ON a.constraint_name=b.constraint_name AND a.owner=b.owner"
" WHERE b.constraint_type='P' AND b.owner=? AND b.table_name=?" ),
QVariantList() << mOwnerName << mTableName ) )
{
QgsMessageLog::logMessage( tr( "Unable to execute the query.\nThe error message from the database was:\n%1.\nSQL: %2" )
.arg( qry.lastError().text() )
.arg( qry.lastQuery() ), tr( "Oracle" ) );
return false;
}
const QStringList pkeys = conn->getPrimaryKeys( mOwnerName, mTableName );

bool isInt = true;

while ( qry.next() )
for ( QString name : pkeys )
{
QString name = qry.value( 0 ).toString();

int idx = mAttributeFields.indexFromName( name );
if ( idx < 0 )
{
Expand Down
5 changes: 1 addition & 4 deletions src/providers/oracle/qgsoracleproviderconnection.cpp
Expand Up @@ -356,12 +356,9 @@ QList<QgsAbstractDatabaseProviderConnection::TableProperty> QgsOracleProviderCon
property.setSchema( pr.ownerName );
property.setGeometryColumn( pr.geometryColName );
property.setGeometryColumnCount( prFlags & QgsAbstractDatabaseProviderConnection::TableFlag::Aspatial ? 0 : 1 );

// TODO These are candidates, not actual PKs
property.setPrimaryKeyColumns( pr.pkCols );
property.setPrimaryKeyColumns( pr.isView ? pr.pkCols : conn->getPrimaryKeys( pr.ownerName, pr.tableName ) );

tables.push_back( property );

}

return tables;
Expand Down
22 changes: 15 additions & 7 deletions tests/src/python/test_qgsproviderconnection_oracle.py
Expand Up @@ -65,13 +65,6 @@ def setUpClass(cls):
cls.conn.setPassword('qgis')
assert cls.conn.open()

# try:
# md = QgsProviderRegistry.instance().providerMetadata(cls.providerKey)
# conn = md.createConnection(cls.uri, {})
# conn.executeSql('drop schema [myNewSchema]')
# except:
# pass

def execSQLCommand(self, sql, ignore_errors=False):
self.assertTrue(self.conn)
query = QSqlQuery(self.conn)
Expand Down Expand Up @@ -158,6 +151,21 @@ def test_configuration(self):
self.assertEqual(ds_uri.param('dbworkspace'), 'workspace')
conn.remove('myconf')

def test_pkcols(self):
"""Test retrieval of primary columns"""

self.execSQLCommand("""CREATE OR REPLACE VIEW "QGIS"."SOME_DATA_VIEW" AS SELECT * FROM "QGIS"."SOME_DATA" """)

md = QgsProviderRegistry.instance().providerMetadata('oracle')
conn = md.createConnection(self.uri, {})
tables = conn.tables('QGIS')

tables_dict = dict([(table.tableName(), table.primaryKeyColumns()) for table in tables])

self.assertEqual(sorted(tables_dict['SOME_DATA_VIEW']), ['GEOM', 'cnt', 'date', 'dt', 'name', 'name2', 'num_char', 'pk', 'time'])
self.assertEqual(sorted(tables_dict['SOME_DATA']), ['pk'])
self.assertEqual(sorted(tables_dict['POINT_DATA_IDENTITY']), ['pk'])


if __name__ == '__main__':
unittest.main()

0 comments on commit d79ade0

Please sign in to comment.