diff --git a/src/providers/mssql/qgsmssqlconnection.cpp b/src/providers/mssql/qgsmssqlconnection.cpp index a915e79f3df..e98f38950a5 100644 --- a/src/providers/mssql/qgsmssqlconnection.cpp +++ b/src/providers/mssql/qgsmssqlconnection.cpp @@ -429,6 +429,10 @@ QgsDataSourceUri QgsMssqlConnection::connUri( const QString &connName ) } } + QStringList excludedSchemas = QgsMssqlConnection::excludedSchemasList( connName ); + if ( !excludedSchemas.isEmpty() ) + uri.setParam( QStringLiteral( "excludedSchemas" ), excludedSchemas.join( ',' ) ); + return uri; } @@ -469,59 +473,80 @@ QList QgsMssqlConnection::nativeTypes() ; } -QString QgsMssqlConnection::buildQueryForSchemas( const QString &connName, bool allowTablesWithNoGeometry ) +QStringList QgsMssqlConnection::excludedSchemasList( const QString &connName ) { QgsSettings settings; - - QString selectedSchemas; - QString databaseName = settings.value( QStringLiteral( "/MSSQL/connections/" ) + connName + "/database" ).toString(); + return excludedSchemasList( connName, databaseName ); +} + +QStringList QgsMssqlConnection::excludedSchemasList( const QString &connName, const QString &database ) +{ + QgsSettings settings; bool schemaFilteringEnabled = settings.value( QStringLiteral( "/MSSQL/connections/" ) + connName + "/schemasFiltering" ).toBool(); if ( schemaFilteringEnabled ) { - QVariant schemaSettingsVariant = settings.value( QStringLiteral( "/MSSQL/connections/" ) + connName + "/schemasFiltered" ); + QVariant schemaSettingsVariant = settings.value( QStringLiteral( "/MSSQL/connections/" ) + connName + "/excludedSchemas" ); if ( schemaSettingsVariant.type() == QVariant::Map ) { - QVariantMap schemaSettings = schemaSettingsVariant.toMap(); - QVariantMap schemaSettingsForDatabase = schemaSettings.value( databaseName ).toMap(); - //schema filter - - - QStringList schemaNames; - for ( const QString &schemaName : schemaSettingsForDatabase.keys() ) - { - if ( schemaSettingsForDatabase.value( schemaName ).toBool() ) - { - schemaNames.append( QgsMssqlProvider::quotedValue( schemaName ) ); - } - } - if ( !schemaNames.empty() ) - selectedSchemas = schemaNames.join( ',' ); - - selectedSchemas.prepend( QStringLiteral( "( " ) ); - selectedSchemas.append( QStringLiteral( " )" ) ); - + const QVariantMap schemaSettings = schemaSettingsVariant.toMap(); + if ( schemaSettings.contains( database ) && schemaSettings.value( database ).type() == QVariant::StringList ) + return schemaSettings.value( database ).toStringList(); } } - // build sql statement + return QStringList(); +} + +void QgsMssqlConnection::setExcludedSchemasList( const QString &connName, const QStringList &excludedSchemas ) +{ + QgsSettings settings; + + QString currentDatabaseName = settings.value( QStringLiteral( "/MSSQL/connections/" ) + connName + "/database" ).toString(); + setExcludedSchemasList( connName, currentDatabaseName, excludedSchemas ); +} + +void QgsMssqlConnection::setExcludedSchemasList( const QString &connName, const QString &database, const QStringList &excludedSchemas ) +{ + QgsSettings settings; + settings.setValue( QStringLiteral( "/MSSQL/connections/" ) + connName + "/schemasFiltering", excludedSchemas.isEmpty() ? 0 : 1 ); + + QVariant schemaSettingsVariant = settings.value( QStringLiteral( "/MSSQL/connections/" ) + connName + "/excludedSchemas" ); + QVariantMap schemaSettings = schemaSettingsVariant.toMap(); + schemaSettings.insert( database, excludedSchemas ); + settings.setValue( QStringLiteral( "/MSSQL/connections/" ) + connName + "/excludedSchemas", schemaSettings ); +} + +QString QgsMssqlConnection::buildQueryForTables( bool allowTablesWithNoGeometry, bool geometryColumnOnly, const QStringList &excludedSchemaList ) +{ + QString notSelectedSchemas; + if ( !excludedSchemaList.isEmpty() ) + { + QStringList quotedSchemas; + for ( const QString &sch : excludedSchemaList ) + quotedSchemas.append( QgsMssqlProvider::quotedValue( sch ) ); + notSelectedSchemas = quotedSchemas.join( ',' ); + notSelectedSchemas.prepend( QStringLiteral( "( " ) ); + notSelectedSchemas.append( QStringLiteral( " )" ) ); + } + QString query( QStringLiteral( "SELECT " ) ); - if ( geometryColumnsOnly( connName ) ) + if ( geometryColumnOnly ) { query += QStringLiteral( "f_table_schema, f_table_name, f_geometry_column, srid, geometry_type, 0 FROM geometry_columns" ); - if ( !selectedSchemas.isEmpty() ) - query += QStringLiteral( " WHERE f_table_schema IN %1" ).arg( selectedSchemas ); + if ( !notSelectedSchemas.isEmpty() ) + query += QStringLiteral( " WHERE f_table_schema NOT IN %1" ).arg( notSelectedSchemas ); } else { query += QStringLiteral( "sys.schemas.name, sys.objects.name, sys.columns.name, null, 'GEOMETRY', CASE when sys.objects.type = 'V' THEN 1 ELSE 0 END \n" "FROM sys.columns JOIN sys.types ON sys.columns.system_type_id = sys.types.system_type_id AND sys.columns.user_type_id = sys.types.user_type_id JOIN sys.objects ON sys.objects.object_id = sys.columns.object_id JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id \n" "WHERE (sys.types.name = 'geometry' OR sys.types.name = 'geography') AND (sys.objects.type = 'U' OR sys.objects.type = 'V')" ); - if ( !selectedSchemas.isEmpty() ) - query += QStringLiteral( " AND (sys.schemas.name IN %1)" ).arg( selectedSchemas ); + if ( !notSelectedSchemas.isEmpty() ) + query += QStringLiteral( " AND (sys.schemas.name NOT IN %1)" ).arg( notSelectedSchemas ); } if ( allowTablesWithNoGeometry ) @@ -530,16 +555,21 @@ QString QgsMssqlConnection::buildQueryForSchemas( const QString &connName, bool "SELECT sys.schemas.name, sys.objects.name, null, null, 'NONE', case when sys.objects.type = 'V' THEN 1 ELSE 0 END \n" "FROM sys.objects JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id " "WHERE NOT EXISTS (SELECT * FROM sys.columns sc1 JOIN sys.types ON sc1.system_type_id = sys.types.system_type_id WHERE (sys.types.name = 'geometry' OR sys.types.name = 'geography') AND sys.objects.object_id = sc1.object_id) AND (sys.objects.type = 'U' or sys.objects.type = 'V')" ); - if ( !selectedSchemas.isEmpty() ) - query += QStringLiteral( " AND sys.schemas.name IN %1" ).arg( selectedSchemas ); + if ( !notSelectedSchemas.isEmpty() ) + query += QStringLiteral( " AND sys.schemas.name NOT IN %1" ).arg( notSelectedSchemas ); } return query; } -QString QgsMssqlConnection::buildQueryForSchemas( const QString &connName ) +QString QgsMssqlConnection::buildQueryForTables( const QString &connName, bool allowTablesWithNoGeometry ) { - return buildQueryForSchemas( connName, allowGeometrylessTables( connName ) ); + return buildQueryForTables( allowTablesWithNoGeometry, geometryColumnsOnly( connName ), excludedSchemasList( connName ) ); +} + +QString QgsMssqlConnection::buildQueryForTables( const QString &connName ) +{ + return buildQueryForTables( allowGeometrylessTables( connName ), geometryColumnsOnly( connName ), excludedSchemasList( connName ) ); } QString QgsMssqlConnection::dbConnectionName( const QString &name ) diff --git a/src/providers/mssql/qgsmssqlconnection.h b/src/providers/mssql/qgsmssqlconnection.h index 5db04b72841..3814cec9241 100644 --- a/src/providers/mssql/qgsmssqlconnection.h +++ b/src/providers/mssql/qgsmssqlconnection.h @@ -45,7 +45,6 @@ class QgsMssqlConnection */ static QSqlDatabase getDatabase( const QString &service, const QString &host, const QString &database, const QString &username, const QString &password ); - static bool openDatabase( QSqlDatabase &db ); /** @@ -151,6 +150,7 @@ class QgsMssqlConnection /** * Returns a list of all schemas on the \a dataBase. + * \since QGIS 3.18 */ static QStringList schemas( QSqlDatabase &dataBase, QString *errorMessage ); @@ -176,16 +176,47 @@ class QgsMssqlConnection static QList nativeTypes(); /** - * Builds and returns a sql query string to obtain schemas list depending on settings and \a allowTablesWithNoGeometry + * Returns a list of excluded schemas for connection \a connName depending on settings, returns empty list if nothing is set for this connection * \since QGIS 3.18 */ - static QString buildQueryForSchemas( const QString &connName, bool allowTablesWithNoGeometry ); + static QStringList excludedSchemasList( const QString &connName ); + + /** + * Returns a list of excluded schemas for connection \a connName for a specific \a database depending on settings, returns empty list if nothing is set for this connection + * \since QGIS 3.18 + */ + static QStringList excludedSchemasList( const QString &connName, const QString &database ); + + /** + * Sets a list of excluded schemas for connection \a connName depending on settings, returns empty list if nothing is set for this connection + * \since QGIS 3.18 + */ + static void setExcludedSchemasList( const QString &connName, const QStringList &excludedSchemas ); + + /** + * Sets a list of excluded schemas for connection \a connName for a specific \a database depending on settings, returns empty list if nothing is set for this connection + * \since QGIS 3.18 + */ + static void setExcludedSchemasList( const QString &connName, const QString &database, const QStringList &excludedSchemas ); + + /** + * Builds and returns a sql query string to obtain tables list depending on \a allowTablesWithNoGeometry, \a geometryColumnOnly and on \a notSelectedSchemasList + * \since QGIS 3.18 + */ + static QString buildQueryForTables( bool allowTablesWithNoGeometry, bool geometryColumnOnly, const QStringList &excludedSchemaList = QStringList() ); + + + /** + * Builds and returns a sql query string to obtain tables list depending on settings and \a allowTablesWithNoGeometry + * \since QGIS 3.18 + */ + static QString buildQueryForTables( const QString &connName, bool allowTablesWithNoGeometry ); /** * Builds and returns a sql query string to obtain schemas list depending only on settings * \since QGIS 3.18 */ - static QString buildQueryForSchemas( const QString &connName ); + static QString buildQueryForTables( const QString &connName ); private: diff --git a/src/providers/mssql/qgsmssqldataitems.cpp b/src/providers/mssql/qgsmssqldataitems.cpp index b786ddbd923..7b99ae56e00 100644 --- a/src/providers/mssql/qgsmssqldataitems.cpp +++ b/src/providers/mssql/qgsmssqldataitems.cpp @@ -74,9 +74,10 @@ void QgsMssqlConnectionItem::readConnectionSettings() mSchemaSettings.clear(); mSchemasFilteringEnabled = settings.value( key + "/schemasFiltering" ).toBool(); + if ( mSchemasFilteringEnabled ) { - QVariant schemasSettingsVariant = settings.value( key + "/schemasFiltered" ); + QVariant schemasSettingsVariant = settings.value( key + "/excludedSchemas" ); if ( schemasSettingsVariant.isValid() && schemasSettingsVariant.type() == QVariant::Map ) mSchemaSettings = schemasSettingsVariant.toMap(); } @@ -144,7 +145,7 @@ QVector QgsMssqlConnectionItem::createChildren() } // build sql statement - QString query = QgsMssqlConnection::buildQueryForSchemas( mName ); + QString query = QgsMssqlConnection::buildQueryForTables( mName ); const bool disableInvalidGeometryHandling = QgsMssqlConnection::isInvalidGeometryHandlingDisabled( mName ); @@ -252,14 +253,13 @@ QVector QgsMssqlConnectionItem::createChildren() } } - // add missing schemas (i.e., empty schemas) const QString uri = connInfo(); const QStringList allSchemas = QgsMssqlConnection::schemas( uri, nullptr ); - QVariantMap schemaSettings = mSchemaSettings.value( mDatabase ).toMap(); + QStringList excludedSchema = QgsMssqlConnection::excludedSchemasList( mName ); for ( const QString &schema : allSchemas ) { - if ( mSchemasFilteringEnabled && !schemaSettings.value( schema ).toBool() ) + if ( mSchemasFilteringEnabled && excludedSchema.contains( schema ) ) continue; // user does not want it to be shown if ( addedSchemas.contains( schema ) ) @@ -274,8 +274,6 @@ QVector QgsMssqlConnectionItem::createChildren() children.append( schemaItem ); } - - // spawn threads (new layers will be added later on) if ( mColumnTypeThread ) { diff --git a/src/providers/mssql/qgsmssqlnewconnection.cpp b/src/providers/mssql/qgsmssqlnewconnection.cpp index b6e45ff9285..5cac3e82fc3 100644 --- a/src/providers/mssql/qgsmssqlnewconnection.cpp +++ b/src/providers/mssql/qgsmssqlnewconnection.cpp @@ -61,7 +61,7 @@ QgsMssqlNewConnection::QgsMssqlNewConnection( QWidget *parent, const QString &co txtHost->setText( settings.value( key + "/host" ).toString() ); listDatabase->addItem( settings.value( key + "/database" ).toString() ); groupBoxSchemasFilter->setChecked( settings.value( key + "/schemasFiltering" ).toBool() ); - QVariant schemasVariant = settings.value( key + "/schemasFiltered" ); + QVariant schemasVariant = settings.value( key + "/excludedSchemas" ); if ( schemasVariant.isValid() && schemasVariant.type() == QVariant::Map ) mSchemaSettings = schemasVariant.toMap(); @@ -90,14 +90,8 @@ QgsMssqlNewConnection::QgsMssqlNewConnection( QWidget *parent, const QString &co cb_trustedConnection_clicked(); schemaView->setModel( &mSchemaModel ); - if ( listDatabase->currentItem() ) - { - QString dataBaseName = listDatabase->currentItem()->text(); - mSchemaModel.setDataBaseName( dataBaseName ); - mSchemaModel.setSchemasSetting( mSchemaSettings.value( dataBaseName ).toMap() ); - } - onCurrentDataBaseChange(); + groupBoxSchemasFilter->setCollapsed( !groupBoxSchemasFilter->isChecked() ); } @@ -147,8 +141,8 @@ void QgsMssqlNewConnection::accept() if ( groupBoxSchemasFilter->isChecked() ) { if ( !mSchemaModel.dataBaseName().isEmpty() ) - mSchemaSettings.insert( mSchemaModel.dataBaseName(), mSchemaModel.schemasSettings() ); - settings.setValue( baseKey + "/schemasFiltered", mSchemaSettings ); + mSchemaSettings.insert( mSchemaModel.dataBaseName(), mSchemaModel.uncheckedSchemas() ); + settings.setValue( baseKey + "/excludedSchemas", mSchemaSettings ); } settings.setValue( baseKey + "/schemasFiltering", groupBoxSchemasFilter->isChecked() ); @@ -303,9 +297,8 @@ void QgsMssqlNewConnection::updateOkButtonState() void QgsMssqlNewConnection::onCurrentDataBaseChange() { //First store the schema settings for the previous dataBase - QVariantMap vm = mSchemaModel.schemasSettings(); if ( !mSchemaModel.dataBaseName().isEmpty() ) - mSchemaSettings.insert( mSchemaModel.dataBaseName(), mSchemaModel.schemasSettings() ); + mSchemaSettings.insert( mSchemaModel.dataBaseName(), mSchemaModel.uncheckedSchemas() ); QString databaseName; if ( listDatabase->currentItem() ) @@ -318,23 +311,16 @@ void QgsMssqlNewConnection::onCurrentDataBaseChange() txtPassword->text().trimmed() ); QStringList schemasList = QgsMssqlConnection::schemas( db, nullptr ); - - QVariantMap newSchemaSettings = mSchemaSettings.value( databaseName ).toMap(); - - for ( const QString &sch : newSchemaSettings.keys() ) + int i = 0; + while ( i < schemasList.count() ) { - if ( !schemasList.contains( sch ) ) - newSchemaSettings.remove( sch ); + if ( QgsMssqlConnection::isSystemSchema( schemasList.at( i ) ) ) + schemasList.removeAt( i ); + else + ++i; } - for ( const QString &sch : schemasList ) - { - if ( !newSchemaSettings.contains( sch ) && !QgsMssqlConnection::isSystemSchema( sch ) ) - newSchemaSettings.insert( sch, true ); - } - - mSchemaModel.setDataBaseName( databaseName ); - mSchemaModel.setSchemasSetting( newSchemaSettings ); + mSchemaModel.setSettings( databaseName, schemasList, QgsMssqlConnection::excludedSchemasList( txtName->text(), databaseName ) ); } QgsMssqlNewConnection::SchemaModel::SchemaModel( QObject *parent ): QAbstractListModel( parent ) @@ -351,18 +337,17 @@ QVariant QgsMssqlNewConnection::SchemaModel::data( const QModelIndex &index, int if ( !index.isValid() || index.row() >= mSchemas.count() ) return QVariant(); - QList schemasName = mSchemas.keys(); switch ( role ) { case Qt::CheckStateRole: - if ( mSchemas.value( schemasName.at( index.row() ) ).toBool() ) - return Qt::CheckState::Checked; - else + if ( mExcludedSchemas.contains( mSchemas.at( index.row() ) ) ) return Qt::CheckState::Unchecked; + else + return Qt::CheckState::Checked; break; case Qt::DisplayRole: - return schemasName.at( index.row() ); + return mSchemas.at( index.row() ); break; default: return QVariant(); @@ -376,11 +361,13 @@ bool QgsMssqlNewConnection::SchemaModel::setData( const QModelIndex &index, cons if ( !index.isValid() || index.row() >= mSchemas.count() ) return false; - QList schemasName = mSchemas.keys(); switch ( role ) { case Qt::CheckStateRole: - mSchemas[schemasName.at( index.row() )] = value; + if ( value == Qt::Checked && mExcludedSchemas.contains( mSchemas.at( index.row() ) ) ) + mExcludedSchemas.removeOne( mSchemas.at( index.row() ) ); + else if ( value == Qt::Unchecked && !mExcludedSchemas.contains( mSchemas.at( index.row() ) ) ) + mExcludedSchemas.append( mSchemas.at( index.row() ) ); return true; break; default: @@ -395,17 +382,11 @@ Qt::ItemFlags QgsMssqlNewConnection::SchemaModel::flags( const QModelIndex &inde return QAbstractListModel::flags( index ) | Qt::ItemFlag::ItemIsUserCheckable; } -void QgsMssqlNewConnection::SchemaModel::setSchemasSetting( const QVariantMap &schemas ) +QStringList QgsMssqlNewConnection::SchemaModel::uncheckedSchemas() const { - beginResetModel(); - mSchemas = schemas; - endResetModel(); + return mExcludedSchemas; } -QVariantMap QgsMssqlNewConnection::SchemaModel::schemasSettings() const -{ - return mSchemas; -} QString QgsMssqlNewConnection::SchemaModel::dataBaseName() const { @@ -416,3 +397,12 @@ void QgsMssqlNewConnection::SchemaModel::setDataBaseName( const QString &dataBas { mDataBaseName = dataBaseName; } + +void QgsMssqlNewConnection::SchemaModel::setSettings( const QString &database, const QStringList &schemas, const QStringList &excludedSchemas ) +{ + beginResetModel(); + mDataBaseName = database; + mSchemas = schemas; + mExcludedSchemas = excludedSchemas; + endResetModel(); +} diff --git a/src/providers/mssql/qgsmssqlnewconnection.h b/src/providers/mssql/qgsmssqlnewconnection.h index cade6d202fb..7422d550566 100644 --- a/src/providers/mssql/qgsmssqlnewconnection.h +++ b/src/providers/mssql/qgsmssqlnewconnection.h @@ -62,11 +62,8 @@ class QgsMssqlNewConnection : public QDialog, private Ui::QgsMssqlNewConnectionB bool setData( const QModelIndex &index, const QVariant &value, int role ) override; Qt::ItemFlags flags( const QModelIndex &index ) const override; - //! Sets the schema settings (keyd : schema names, value : bool that represents whether the schema is checked) - void setSchemasSetting( const QVariantMap &schemas ); - - //! Returns the schema settings (keyd : schema names, value : bool that represents whether the schema is checked) - QVariantMap schemasSettings() const; + //! Returns the unchecked schemas + QStringList uncheckedSchemas() const; //! Returns the database nale represented by the model QString dataBaseName() const; @@ -74,9 +71,13 @@ class QgsMssqlNewConnection : public QDialog, private Ui::QgsMssqlNewConnectionB //! Sets the database nale represented by the model void setDataBaseName( const QString &dataBaseName ); + //! Sets the settings for \a database + void setSettings( const QString &database, const QStringList &schemas, const QStringList &excludedSchemas ); + private: - QVariantMap mSchemas; QString mDataBaseName; + QStringList mSchemas; + QStringList mExcludedSchemas; }; diff --git a/src/providers/mssql/qgsmssqlproviderconnection.cpp b/src/providers/mssql/qgsmssqlproviderconnection.cpp index f3aff53744f..23baee213a6 100644 --- a/src/providers/mssql/qgsmssqlproviderconnection.cpp +++ b/src/providers/mssql/qgsmssqlproviderconnection.cpp @@ -66,6 +66,9 @@ QgsMssqlProviderConnection::QgsMssqlProviderConnection( const QString &uri, cons } } + if ( inputUri.hasParam( QStringLiteral( "excludedSchemas" ) ) ) + currentUri.setParam( QStringLiteral( "excludedSchemas" ), inputUri.param( QStringLiteral( "excludedSchemas" ) ) ); + setUri( currentUri.uri() ); setDefaultCapabilities(); } @@ -456,9 +459,14 @@ QStringList QgsMssqlProviderConnection::schemas( ) const { checkCapability( Capability::Schemas ); QStringList schemas; + + QgsDataSourceUri connUri( uri() ); + const QgsDataSourceUri dsUri { uri() }; - const QString sql { QStringLiteral( - R"raw( + const QString sql + { + QStringLiteral( + R"raw( SELECT s.name AS schema_name, s.schema_id, u.name AS schema_owner @@ -467,12 +475,22 @@ QStringList QgsMssqlProviderConnection::schemas( ) const ON u.uid = s.principal_id WHERE u.issqluser = 1 AND u.name NOT IN ('sys', 'guest', 'INFORMATION_SCHEMA') - )raw" )}; + )raw" ) + }; + const QList result { executeSqlPrivate( sql, false ).rows() }; + + QStringList excludedSchemaList; + if ( connUri.hasParam( QStringLiteral( "excludedSchemas" ) ) ) + excludedSchemaList = QgsDataSourceUri( uri() ).param( QStringLiteral( "excludedSchemas" ) ).split( ',' ); for ( const auto &row : result ) { if ( row.size() > 0 ) - schemas.push_back( row.at( 0 ).toString() ); + { + QString schema = row.at( 0 ).toString(); + if ( !excludedSchemaList.contains( schema ) ) + schemas.push_back( schema ); + } } return schemas; } @@ -498,13 +516,14 @@ void QgsMssqlProviderConnection::store( const QString &name ) const settings.setValue( "password", dsUri.password() ); settings.setValue( "estimatedMetadata", dsUri.useEstimatedMetadata() ); + QgsMssqlConnection::setExcludedSchemasList( name, dsUri.database(), dsUri.param( QStringLiteral( "excludedSchemas" ) ).split( ',' ) ); + for ( const auto ¶m : EXTRA_CONNECTION_PARAMETERS ) { if ( dsUri.hasParam( param ) ) { settings.setValue( param, dsUri.param( param ) == QStringLiteral( "true" ) || dsUri.param( param ) == '1' ); - } } diff --git a/src/providers/mssql/qgsmssqlsourceselect.cpp b/src/providers/mssql/qgsmssqlsourceselect.cpp index 181e46e0e6f..52f330185e9 100644 --- a/src/providers/mssql/qgsmssqlsourceselect.cpp +++ b/src/providers/mssql/qgsmssqlsourceselect.cpp @@ -540,7 +540,7 @@ void QgsMssqlSourceSelect::btnConnect_clicked() // Read supported layers from database QApplication::setOverrideCursor( Qt::WaitCursor ); - QString query = QgsMssqlConnection::buildQueryForSchemas( cmbConnections->currentText(), allowGeometrylessTables ); + QString query = QgsMssqlConnection::buildQueryForTables( cmbConnections->currentText(), allowGeometrylessTables ); // issue the sql query q = QSqlQuery( db ); diff --git a/src/ui/qgsmssqlnewconnectionbase.ui b/src/ui/qgsmssqlnewconnectionbase.ui index 682afa530b9..3b70e05c5d7 100644 --- a/src/ui/qgsmssqlnewconnectionbase.ui +++ b/src/ui/qgsmssqlnewconnectionbase.ui @@ -7,7 +7,7 @@ 0 0 772 - 691 + 687 @@ -272,19 +272,6 @@ Untick save if you don't wish to be the case. - - - - 0 - 0 - - - - Qt::Horizontal - - - - Use Only a Subset of Schemas @@ -317,7 +304,7 @@ Untick save if you don't wish to be the case. - + Test Connection diff --git a/tests/src/python/test_qgsproviderconnection_mssql.py b/tests/src/python/test_qgsproviderconnection_mssql.py index 32d15d654e0..017392d1fcb 100644 --- a/tests/src/python/test_qgsproviderconnection_mssql.py +++ b/tests/src/python/test_qgsproviderconnection_mssql.py @@ -102,6 +102,30 @@ class TestPyQgsProviderConnectionMssql(unittest.TestCase, TestPyQgsProviderConne fields = conn.fields('qgis_test', 'someData') self.assertEqual(fields.names(), ['pk', 'cnt', 'name', 'name2', 'num_char', 'dt', 'date', 'time']) + def test_schemas_filtering(self): + """Test schemas filtering""" + + md = QgsProviderRegistry.instance().providerMetadata('mssql') + + conn = md.createConnection(self.uri, {}) + schemas = conn.schemas() + self.assertEqual(len(schemas), 2) + self.assertEqual(schemas, ['dbo', 'qgis_test']) + filterUri = QgsDataSourceUri(self.uri) + filterUri.setParam('excludedSchemas', 'dbo') + conn = md.createConnection(filterUri.uri(), {}) + schemas = conn.schemas() + self.assertEqual(len(schemas), 1) + self.assertEqual(schemas, ['qgis_test']) + + # Store the connection + conn.store('filteredConnection') + + otherConn = md.createConnection('filteredConnection') + schemas = otherConn.schemas() + self.assertEqual(len(schemas), 1) + self.assertEqual(schemas, ['qgis_test']) + if __name__ == '__main__': unittest.main()