[mssql] Always use connection method with full QgsDataSourceUri

Remove the older method which took explicit host/database/service/...
arguments, and ensure we always use the method which takes a full
QgsDataSourceUri argument. This ensures that the db connection
always has access to ALL the properties of the original data source
uri, including any additional parameters set on it.
This commit is contained in:
Nyall Dawson 2025-08-06 11:31:34 +10:00
parent a6e34c1a3c
commit da4260766f
12 changed files with 69 additions and 79 deletions

View File

@ -107,7 +107,7 @@ bool QgsMssqlConnection::dropView( const QString &uri, QString *errorMessage )
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
const QString schema = dsUri.schema(); const QString schema = dsUri.schema();
const QString table = dsUri.table(); const QString table = dsUri.table();
@ -134,7 +134,7 @@ bool QgsMssqlConnection::dropTable( const QString &uri, QString *errorMessage )
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
const QString schema = dsUri.schema(); const QString schema = dsUri.schema();
const QString table = dsUri.table(); const QString table = dsUri.table();
@ -165,7 +165,7 @@ bool QgsMssqlConnection::truncateTable( const QString &uri, QString *errorMessag
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
const QString schema = dsUri.schema(); const QString schema = dsUri.schema();
const QString table = dsUri.table(); const QString table = dsUri.table();
@ -194,7 +194,7 @@ bool QgsMssqlConnection::createSchema( const QString &uri, const QString &schema
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {
@ -221,7 +221,7 @@ QStringList QgsMssqlConnection::schemas( const QString &uri, QString *errorMessa
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
return schemas( std::move( db ), errorMessage ); return schemas( std::move( db ), errorMessage );
} }

View File

@ -69,17 +69,6 @@ std::shared_ptr<QgsMssqlDatabase> QgsMssqlDatabase::connectDb( const QString &ur
return connectDb( dsUri, transaction ); return connectDb( dsUri, transaction );
} }
std::shared_ptr<QgsMssqlDatabase> QgsMssqlDatabase::connectDb( const QString &service, const QString &host, const QString &database, const QString &username, const QString &password, bool transaction )
{
QgsDataSourceUri uri;
uri.setService( service );
uri.setHost( host );
uri.setDatabase( database );
uri.setUsername( username );
uri.setPassword( password );
return connectDb( uri, transaction );
}
std::shared_ptr<QgsMssqlDatabase> QgsMssqlDatabase::connectDb( const QgsDataSourceUri &uri, bool transaction ) std::shared_ptr<QgsMssqlDatabase> QgsMssqlDatabase::connectDb( const QgsDataSourceUri &uri, bool transaction )
{ {
// try to use existing conn or create a new one // try to use existing conn or create a new one

View File

@ -63,7 +63,6 @@ class QgsMssqlDatabase
* \note The function is thread-safe * \note The function is thread-safe
*/ */
static std::shared_ptr<QgsMssqlDatabase> connectDb( const QString &uri, bool transaction = false ); static std::shared_ptr<QgsMssqlDatabase> connectDb( const QString &uri, bool transaction = false );
static std::shared_ptr<QgsMssqlDatabase> connectDb( const QString &service, const QString &host, const QString &database, const QString &username, const QString &password, bool transaction = false );
static std::shared_ptr<QgsMssqlDatabase> connectDb( const QgsDataSourceUri &uri, bool transaction = false ); static std::shared_ptr<QgsMssqlDatabase> connectDb( const QgsDataSourceUri &uri, bool transaction = false );
///// /////

View File

@ -133,7 +133,13 @@ QVector<QgsDataItem *> QgsMssqlConnectionItem::createChildren()
readConnectionSettings(); readConnectionSettings();
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( mService, mHost, mDatabase, mUsername, mPassword ); QgsDataSourceUri uri;
uri.setService( mService );
uri.setHost( mHost );
uri.setDatabase( mDatabase );
uri.setUsername( mUsername );
uri.setPassword( mPassword );
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( uri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {

View File

@ -454,7 +454,7 @@ bool QgsMssqlFeatureIterator::fetchFeature( QgsFeature &feature )
{ {
// No existing connection, so set it up now. It's safe to do here as we're now in // No existing connection, so set it up now. It's safe to do here as we're now in
// the thread were iteration is actually occurring. // the thread were iteration is actually occurring.
mDatabase = QgsMssqlDatabase::connectDb( mSource->mService, mSource->mHost, mSource->mDatabaseName, mSource->mUserName, mSource->mPassword ); mDatabase = QgsMssqlDatabase::connectDb( mSource->mUri );
} }
if ( !mDatabase->isValid() ) if ( !mDatabase->isValid() )
@ -710,11 +710,7 @@ QgsMssqlFeatureSource::QgsMssqlFeatureSource( const QgsMssqlProvider *p )
, mSchemaName( p->mSchemaName ) , mSchemaName( p->mSchemaName )
, mTableName( p->mTableName ) , mTableName( p->mTableName )
, mQuery( p->mQuery ) , mQuery( p->mQuery )
, mUserName( p->mUserName ) , mUri( p->mUri )
, mPassword( p->mPassword )
, mService( p->mService )
, mDatabaseName( p->mDatabaseName )
, mHost( p->mHost )
, mSqlWhereClause( p->mSqlWhereClause ) , mSqlWhereClause( p->mSqlWhereClause )
, mDisableInvalidGeometryHandling( p->mDisableInvalidGeometryHandling ) , mDisableInvalidGeometryHandling( p->mDisableInvalidGeometryHandling )
, mCrs( p->crs() ) , mCrs( p->crs() )

View File

@ -59,13 +59,7 @@ class QgsMssqlFeatureSource final : public QgsAbstractFeatureSource
QString mQuery; QString mQuery;
// login // login
QString mUserName; QgsDataSourceUri mUri;
QString mPassword;
// server access
QString mService;
QString mDatabaseName;
QString mHost;
// SQL statement used to limit the features retrieved // SQL statement used to limit the features retrieved
QString mSqlWhereClause; QString mSqlWhereClause;

View File

@ -48,7 +48,14 @@ void QgsMssqlGeomColumnTypeThread::run()
{ {
mStopped = false; mStopped = false;
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( mService, mHost, mDatabase, mUsername, mPassword ); QgsDataSourceUri uri;
uri.setService( mService );
uri.setHost( mHost );
uri.setDatabase( mDatabase );
uri.setUsername( mUsername );
uri.setPassword( mPassword );
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( uri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {
QgsDebugError( db->errorText() ); QgsDebugError( db->errorText() );

View File

@ -293,7 +293,13 @@ std::shared_ptr<QgsMssqlDatabase> QgsMssqlNewConnection::getDatabase( const QStr
database = item->text(); database = item->text();
} }
return QgsMssqlDatabase::connectDb( txtService->text().trimmed(), txtHost->text().trimmed(), database, txtUsername->text().trimmed(), txtPassword->text().trimmed() ); QgsDataSourceUri uri;
uri.setService( txtService->text().trimmed() );
uri.setHost( txtHost->text().trimmed() );
uri.setDatabase( database );
uri.setUsername( txtUsername->text().trimmed() );
uri.setPassword( txtPassword->text().trimmed() );
return QgsMssqlDatabase::connectDb( uri );
} }

View File

@ -71,42 +71,35 @@ int QgsMssqlProvider::sConnectionId = 0;
QgsMssqlProvider::QgsMssqlProvider( const QString &uri, const ProviderOptions &options, Qgis::DataProviderReadFlags flags ) QgsMssqlProvider::QgsMssqlProvider( const QString &uri, const ProviderOptions &options, Qgis::DataProviderReadFlags flags )
: QgsVectorDataProvider( uri, options, flags ) : QgsVectorDataProvider( uri, options, flags )
, mUri( uri )
, mShared( new QgsMssqlSharedData ) , mShared( new QgsMssqlSharedData )
{ {
const QgsDataSourceUri anUri = QgsDataSourceUri( uri ); if ( !mUri.srid().isEmpty() )
mSRId = mUri.srid().toInt();
if ( !anUri.srid().isEmpty() )
mSRId = anUri.srid().toInt();
else else
mSRId = -1; mSRId = -1;
mWkbType = anUri.wkbType(); mWkbType = mUri.wkbType();
mValid = true; mValid = true;
mUserName = anUri.username(); mUseEstimatedMetadata = mUri.useEstimatedMetadata();
mPassword = anUri.password();
mService = anUri.service();
mDatabaseName = anUri.database();
mHost = anUri.host();
mUseEstimatedMetadata = anUri.useEstimatedMetadata();
if ( mReadFlags & Qgis::DataProviderReadFlag::TrustDataSource ) if ( mReadFlags & Qgis::DataProviderReadFlag::TrustDataSource )
{ {
mUseEstimatedMetadata = true; mUseEstimatedMetadata = true;
} }
mDisableInvalidGeometryHandling = anUri.hasParam( QStringLiteral( "disableInvalidGeometryHandling" ) ) mDisableInvalidGeometryHandling = mUri.hasParam( QStringLiteral( "disableInvalidGeometryHandling" ) )
? anUri.param( QStringLiteral( "disableInvalidGeometryHandling" ) ).toInt() ? mUri.param( QStringLiteral( "disableInvalidGeometryHandling" ) ).toInt()
: false; : false;
mUseGeometryColumnsTableForExtent = anUri.hasParam( QStringLiteral( "extentInGeometryColumns" ) ) mUseGeometryColumnsTableForExtent = mUri.hasParam( QStringLiteral( "extentInGeometryColumns" ) )
? anUri.param( QStringLiteral( "extentInGeometryColumns" ) ).toInt() ? mUri.param( QStringLiteral( "extentInGeometryColumns" ) ).toInt()
: false; : false;
mSqlWhereClause = anUri.sql(); mSqlWhereClause = mUri.sql();
mConn = QgsMssqlDatabase::connectDb( mService, mHost, mDatabaseName, mUserName, mPassword, false ); mConn = QgsMssqlDatabase::connectDb( mUri, false );
if ( !mConn ) if ( !mConn )
{ {
mValid = false; mValid = false;
@ -124,23 +117,23 @@ QgsMssqlProvider::QgsMssqlProvider( const QString &uri, const ProviderOptions &o
// Database successfully opened; we can now issue SQL commands. // Database successfully opened; we can now issue SQL commands.
if ( mSchemaName.isEmpty() && anUri.table().startsWith( '(' ) && anUri.table().endsWith( ')' ) ) if ( mSchemaName.isEmpty() && mUri.table().startsWith( '(' ) && mUri.table().endsWith( ')' ) )
{ {
mIsQuery = true; mIsQuery = true;
mQuery = anUri.table(); mQuery = mUri.table();
} }
else else
{ {
mIsQuery = false; mIsQuery = false;
if ( !anUri.schema().isEmpty() ) if ( !mUri.schema().isEmpty() )
mSchemaName = anUri.schema(); mSchemaName = mUri.schema();
else else
mSchemaName = QStringLiteral( "dbo" ); mSchemaName = QStringLiteral( "dbo" );
if ( !anUri.table().isEmpty() ) if ( !mUri.table().isEmpty() )
{ {
// the layer name has been specified // the layer name has been specified
mTableName = anUri.table(); mTableName = mUri.table();
QStringList sl = mTableName.split( '.' ); QStringList sl = mTableName.split( '.' );
if ( sl.length() == 2 ) if ( sl.length() == 2 )
{ {
@ -162,8 +155,8 @@ QgsMssqlProvider::QgsMssqlProvider( const QString &uri, const ProviderOptions &o
if ( mValid ) if ( mValid )
{ {
if ( !anUri.geometryColumn().isEmpty() ) if ( !mUri.geometryColumn().isEmpty() )
mGeometryColName = anUri.geometryColumn(); mGeometryColName = mUri.geometryColumn();
if ( !mIsQuery ) if ( !mIsQuery )
{ {
@ -181,8 +174,8 @@ QgsMssqlProvider::QgsMssqlProvider( const QString &uri, const ProviderOptions &o
UpdateStatistics( mUseEstimatedMetadata ); UpdateStatistics( mUseEstimatedMetadata );
//only for views, defined in layer data when loading layer for first time //only for views, defined in layer data when loading layer for first time
bool primaryKeyFromGeometryColumnsTable = anUri.hasParam( QStringLiteral( "primaryKeyInGeometryColumns" ) ) bool primaryKeyFromGeometryColumnsTable = mUri.hasParam( QStringLiteral( "primaryKeyInGeometryColumns" ) )
? anUri.param( QStringLiteral( "primaryKeyInGeometryColumns" ) ).toInt() ? mUri.param( QStringLiteral( "primaryKeyInGeometryColumns" ) ).toInt()
: false; : false;
QStringList cols; QStringList cols;
@ -192,12 +185,12 @@ QgsMssqlProvider::QgsMssqlProvider( const QString &uri, const ProviderOptions &o
mPrimaryKeyAttrs.clear(); mPrimaryKeyAttrs.clear();
primaryKeyFromGeometryColumnsTable = getPrimaryKeyFromGeometryColumns( cols ); primaryKeyFromGeometryColumnsTable = getPrimaryKeyFromGeometryColumns( cols );
if ( !primaryKeyFromGeometryColumnsTable ) if ( !primaryKeyFromGeometryColumnsTable )
QgsMessageLog::logMessage( tr( "Invalid primary key from geometry_columns table for layer '%1', get primary key from the layer." ).arg( anUri.table() ), tr( "MS SQL Server" ) ); QgsMessageLog::logMessage( tr( "Invalid primary key from geometry_columns table for layer '%1', get primary key from the layer." ).arg( mUri.table() ), tr( "MS SQL Server" ) );
} }
if ( !primaryKeyFromGeometryColumnsTable ) if ( !primaryKeyFromGeometryColumnsTable )
{ {
const QString primaryKey = anUri.keyColumn(); const QString primaryKey = mUri.keyColumn();
if ( !primaryKey.isEmpty() ) if ( !primaryKey.isEmpty() )
{ {
mPrimaryKeyAttrs.clear(); mPrimaryKeyAttrs.clear();
@ -2357,7 +2350,7 @@ bool QgsMssqlProviderMetadata::styleExists( const QString &uri, const QString &s
errorCause.clear(); errorCause.clear();
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {
@ -2416,7 +2409,7 @@ bool QgsMssqlProviderMetadata::saveStyle( const QString &uri, const QString &qml
{ {
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {
@ -2580,7 +2573,7 @@ QString QgsMssqlProviderMetadata::loadStoredStyle( const QString &uri, QString &
errCause.clear(); errCause.clear();
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {
@ -2645,7 +2638,7 @@ int QgsMssqlProviderMetadata::listStyles( const QString &uri, QStringList &ids,
{ {
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {
@ -2742,7 +2735,7 @@ QString QgsMssqlProviderMetadata::getStyleById( const QString &uri, const QStrin
{ {
const QgsDataSourceUri dsUri( uri ); const QgsDataSourceUri dsUri( uri );
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {

View File

@ -213,19 +213,12 @@ class QgsMssqlProvider final : public QgsVectorDataProvider
mutable Qgis::WkbType mWkbType = Qgis::WkbType::Unknown; mutable Qgis::WkbType mWkbType = Qgis::WkbType::Unknown;
QgsDataSourceUri mUri;
// current layer name // current layer name
QString mSchemaName; QString mSchemaName;
QString mTableName; QString mTableName;
// login
QString mUserName;
QString mPassword;
// server access
QString mService;
QString mDatabaseName;
QString mHost;
// available tables // available tables
QStringList mTables; QStringList mTables;

View File

@ -256,7 +256,7 @@ QgsAbstractDatabaseProviderConnection::QueryResult QgsMssqlProviderConnection::e
const QgsDataSourceUri dsUri { uri() }; const QgsDataSourceUri dsUri { uri() };
// connect to database // connect to database
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri.service(), dsUri.host(), dsUri.database(), dsUri.username(), dsUri.password() ); std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( dsUri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {

View File

@ -404,7 +404,14 @@ void QgsMssqlSourceSelect::btnConnect_clicked()
mConnInfo += " service='" + service + '\''; mConnInfo += " service='" + service + '\'';
QgsDebugMsgLevel( QStringLiteral( "GetDatabase" ), 2 ); QgsDebugMsgLevel( QStringLiteral( "GetDatabase" ), 2 );
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( service, host, database, username, password );
QgsDataSourceUri uri;
uri.setService( service );
uri.setHost( host );
uri.setDatabase( database );
uri.setUsername( username );
uri.setPassword( password );
std::shared_ptr<QgsMssqlDatabase> db = QgsMssqlDatabase::connectDb( uri );
if ( !db->isValid() ) if ( !db->isValid() )
{ {