26#include <QRegularExpression> 
   30#define HIDING_TOKEN QStringLiteral( "XXXXXXXX" ) 
   41  while ( i < 
uri.length() )
 
   47      QgsDebugError( QStringLiteral( 
"parameter name expected before =" ) );
 
   54    while ( i < 
uri.length() && 
uri[i] != 
'=' && !
uri[i].isSpace() )
 
   57    const QString pname = 
uri.mid( start, i - start );
 
   61    if ( i == 
uri.length() || 
uri[i] != 
'=' )
 
   69    if ( pname == QLatin1String( 
"sql" ) )
 
   78      if ( mSql == QLatin1String( 
"''" ) || mSql == QLatin1String( 
"\"\"" ) )
 
   84      const QString pval = getValue( 
uri, i );
 
   86      if ( pname == QLatin1String( 
"table" ) )
 
   88        if ( i < 
uri.length() && 
uri[i] == 
'.' )
 
   93          mTable = getValue( 
uri, i );
 
  100        if ( i < 
uri.length() && 
uri[i] == 
'(' )
 
  105          while ( i < 
uri.length() && 
uri[i] != 
')' )
 
  107            if ( 
uri[i] == 
'\\' )
 
  112          if ( i == 
uri.length() )
 
  114            QgsDebugError( QStringLiteral( 
"closing parenthesis missing" ) );
 
  117          mGeometryColumn = 
uri.mid( start, i - start );
 
  118          mGeometryColumn.replace( QLatin1String( 
"\\)" ), QLatin1String( 
")" ) );
 
  119          mGeometryColumn.replace( QLatin1String( 
"\\\\" ), QLatin1String( 
"\\" ) );
 
  125          mGeometryColumn = QString();
 
  128      else if ( pname == QLatin1String( 
"schema" ) )
 
  132      else if ( pname == QLatin1String( 
"key" ) )
 
  136      else if ( pname == QLatin1String( 
"estimatedmetadata" ) )
 
  138        mUseEstimatedMetadata = pval == QLatin1String( 
"true" );
 
  140      else if ( pname == QLatin1String( 
"srid" ) )
 
  144      else if ( pname == QLatin1String( 
"type" ) )
 
  148      else if ( pname == QLatin1String( 
"selectatid" ) )
 
  150        mSelectAtIdDisabledSet = 
true;
 
  151        mSelectAtIdDisabled = pval == QLatin1String( 
"false" );
 
  153      else if ( pname == QLatin1String( 
"service" ) )
 
  157      else if ( pname == QLatin1String( 
"authcfg" ) )
 
  159        mAuthConfigId = pval;
 
  161      else if ( pname == QLatin1String( 
"user" ) || pname == QLatin1String( 
"username" ) ) 
 
  165      else if ( pname == QLatin1String( 
"password" ) )
 
  169      else if ( pname == QLatin1String( 
"connect_timeout" ) )
 
  173      else if ( pname == QLatin1String( 
"dbname" ) )
 
  177      else if ( pname == QLatin1String( 
"host" ) )
 
  181      else if ( pname == QLatin1String( 
"hostaddr" ) )
 
  183        QgsDebugMsgLevel( QStringLiteral( 
"database host ip address ignored" ), 2 );
 
  185      else if ( pname == QLatin1String( 
"port" ) )
 
  189      else if ( pname == QLatin1String( 
"driver" ) )
 
  193      else if ( pname == QLatin1String( 
"tty" ) )
 
  197      else if ( pname == QLatin1String( 
"options" ) )
 
  201      else if ( pname == QLatin1String( 
"sslmode" ) )
 
  205      else if ( pname == QLatin1String( 
"requiressl" ) )
 
  207        if ( pval == QLatin1String( 
"0" ) )
 
  212      else if ( pname == QLatin1String( 
"krbsrvname" ) )
 
  216      else if ( pname == QLatin1String( 
"gsslib" ) )
 
  222        mHttpHeaders.
insert( pname, pval );
 
  226        QgsDebugMsgLevel( 
"parameter \"" + pname + 
"\":\"" + pval + 
"\" added", 4 );
 
 
  235  QRegularExpression regexp;
 
  236  regexp.setPatternOptions( QRegularExpression::InvertedGreedinessOption );
 
  237  QString safeName( aUri );
 
  238  if ( aUri.contains( QLatin1String( 
" password=" ) ) )
 
  240    regexp.setPattern( QStringLiteral( 
" password=.* " ) );
 
  244      safeName.replace( regexp, QStringLiteral( 
" password=%1 " ).arg( 
HIDING_TOKEN ) );
 
  248      safeName.replace( regexp, QStringLiteral( 
" " ) );
 
  251  else if ( aUri.contains( QLatin1String( 
",password=" ) ) )
 
  253    regexp.setPattern( QStringLiteral( 
",password=.*," ) );
 
  257      safeName.replace( regexp, QStringLiteral( 
",password=%1," ).arg( 
HIDING_TOKEN ) );
 
  261      safeName.replace( regexp, QStringLiteral( 
"," ) );
 
  264  else if ( aUri.contains( QLatin1String( 
"IDB:" ) ) )
 
  266    regexp.setPattern( QStringLiteral( 
" pass=.* " ) );
 
  270      safeName.replace( regexp, QStringLiteral( 
" pass=%1 " ).arg( 
HIDING_TOKEN ) );
 
  274      safeName.replace( regexp, QStringLiteral( 
" " ) );
 
  277  else if ( ( aUri.contains( QLatin1String( 
"OCI:" ) ) )
 
  278            || ( aUri.contains( QLatin1String( 
"ODBC:" ) ) ) )
 
  280    regexp.setPattern( QStringLiteral( 
"/.*@" ) );
 
  284      safeName.replace( regexp, QStringLiteral( 
"/%1@" ).arg( 
HIDING_TOKEN ) );
 
  288      safeName.replace( regexp, QStringLiteral( 
"/@" ) );
 
  291  else if ( aUri.contains( QLatin1String( 
"postgresql:" ) ) )
 
  294    regexp.setPattern( QStringLiteral( 
"/.*@" ) );
 
  295    const QString matched = regexp.match( aUri ).captured();
 
  297    QString anonymised = matched;
 
  298    const QStringList items = matched.split( QStringLiteral( 
":" ) );
 
  299    if ( items.size() > 1 )
 
  301      anonymised = matched.split( QStringLiteral( 
":" ) )[0];
 
  304        anonymised.append( QStringLiteral( 
":%1" ).arg( 
HIDING_TOKEN ) );
 
  306      anonymised.append( QStringLiteral( 
"@" ) );
 
  309    safeName.replace( regexp, anonymised );
 
  311  else if ( aUri.contains( QLatin1String( 
"SDE:" ) ) )
 
  313    QStringList strlist = aUri.split( 
',' );
 
  314    safeName = strlist[0] + 
',' + strlist[1] + 
',' + strlist[2] + 
',' + strlist[3];
 
 
  321  return mAuthConfigId;
 
 
  391  return mGeometryColumn;
 
 
  414  mUseEstimatedMetadata = flag;
 
 
  419  return mUseEstimatedMetadata;
 
 
  424  mSelectAtIdDisabledSet = 
true;
 
  425  mSelectAtIdDisabled = flag;
 
 
  430  return mSelectAtIdDisabled;
 
 
  448QString QgsDataSourceUri::escape( 
const QString &val, QChar delim = 
'\'' )
 const 
  450  QString escaped = val;
 
  452  escaped.replace( 
'\\', QLatin1String( 
"\\\\" ) );
 
  453  escaped.replace( delim, QStringLiteral( 
"\\%1" ).arg( delim ) );
 
  468void QgsDataSourceUri::skipBlanks( 
const QString &uri, 
int &i )
 
  471  while ( i < 
uri.length() && 
uri[i].isSpace() )
 
  475QString QgsDataSourceUri::getValue( 
const QString &uri, 
int &i )
 
  477  skipBlanks( 
uri, i );
 
  481  if ( i < 
uri.length() && ( 
uri[i] == 
'\'' || 
uri[i] == 
'"' ) )
 
  483    const QChar delim = 
uri[i];
 
  490      if ( i == 
uri.length() )
 
  492        QgsDebugError( QStringLiteral( 
"unterminated quoted string in connection info string" ) );
 
  496      if ( 
uri[i] == 
'\\' )
 
  499        if ( i == 
uri.length() )
 
  501        if ( 
uri[i] != delim && 
uri[i] != 
'\\' )
 
  504      else if ( 
uri[i] == delim )
 
  516    while ( i < 
uri.length() )
 
  518      if ( 
uri[i].isSpace() )
 
  524      if ( 
uri[i] == 
'\\' )
 
  527        if ( i == 
uri.length() )
 
  529        if ( 
uri[i] != 
'\\' && 
uri[i] != 
'\'' )
 
  537  skipBlanks( 
uri, i );
 
  544  QStringList connectionItems;
 
  546  if ( !mDatabase.isEmpty() )
 
  548    connectionItems << 
"dbname='" + escape( mDatabase ) + 
'\'';
 
  551  if ( !mService.isEmpty() )
 
  553    connectionItems << 
"service='" + escape( mService ) + 
'\'';
 
  555  else if ( !mHost.isEmpty() )
 
  557    connectionItems << 
"host=" + mHost;
 
  560  if ( mService.isEmpty() )
 
  562    if ( !mPort.isEmpty() )
 
  563      connectionItems << 
"port=" + mPort;
 
  566  if ( !mDriver.isEmpty() )
 
  568    connectionItems << 
"driver='" + escape( mDriver ) + 
'\'';
 
  571  if ( !mUsername.isEmpty() )
 
  573    connectionItems << 
"user='" + escape( mUsername ) + 
'\'';
 
  575    if ( !mPassword.isEmpty() )
 
  577      connectionItems << 
"password='" + escape( mPassword ) + 
'\'';
 
  583    connectionItems << QStringLiteral( 
"sslmode=" ) + 
encodeSslMode( mSSLmode );
 
  586  if ( !mAuthConfigId.isEmpty() )
 
  588    if ( expandAuthConfig )
 
  592        QgsDebugError( QStringLiteral( 
"Data source URI FAILED to update via loading configuration ID '%1'" ).arg( mAuthConfigId ) );
 
  597      connectionItems << 
"authcfg=" + mAuthConfigId;
 
  601  return connectionItems.join( QLatin1Char( 
' ' ) );
 
 
  608  if ( !mKeyColumn.isEmpty() )
 
  610    uri += QStringLiteral( 
" key='%1'" ).arg( escape( mKeyColumn ) );
 
  613  if ( mUseEstimatedMetadata )
 
  615    uri += QLatin1String( 
" estimatedmetadata=true" );
 
  618  if ( !mSrid.isEmpty() )
 
  620    uri += QStringLiteral( 
" srid=%1" ).arg( mSrid );
 
  625    uri += QLatin1String( 
" type=" );
 
  629  if ( mSelectAtIdDisabled )
 
  631    uri += QLatin1String( 
" selectatid=false" );
 
  634  for ( 
auto it = mParams.constBegin(); it != mParams.constEnd(); ++it )
 
  636    if ( it.key().contains( 
'=' ) || it.key().contains( 
' ' ) )
 
  638      QgsDebugError( QStringLiteral( 
"invalid uri parameter %1 skipped" ).arg( it.key() ) );
 
  642    uri += 
' ' + it.key() + 
"='" + escape( it.value() ) + 
'\'';
 
  647  QString columnName( mGeometryColumn );
 
  648  columnName.replace( 
'\\', QLatin1String( 
"\\\\" ) );
 
  649  columnName.replace( 
')', QLatin1String( 
"\\)" ) );
 
  651  if ( !mTable.isEmpty() )
 
  653    uri += QStringLiteral( 
" table=%1%2" )
 
  655                 mGeometryColumn.isEmpty() ? QString() : QStringLiteral( 
" (%1)" ).arg( columnName ) );
 
  657  else if ( !mSchema.isEmpty() )
 
  659    uri += QStringLiteral( 
" schema='%1'" ).arg( escape( mSchema ) );
 
  662  if ( !mSql.isEmpty() )
 
  664    uri += QStringLiteral( 
" sql=" ) + mSql;
 
 
  673  if ( 
string.isEmpty() )
 
  674    return string.isNull() ? QByteArray() : QByteArray( 
"" );
 
  675  return string.toLatin1();
 
 
  681  for ( 
auto it = mParams.constBegin(); it != mParams.constEnd(); ++it )
 
  683    url.addQueryItem( it.key(), it.value() );
 
  686  if ( !mUsername.isEmpty() )
 
  687    url.addQueryItem( QStringLiteral( 
"username" ), mUsername );
 
  689  if ( !mPassword.isEmpty() )
 
  690    url.addQueryItem( QStringLiteral( 
"password" ), mPassword );
 
  692  if ( !mAuthConfigId.isEmpty() )
 
  693    url.addQueryItem( QStringLiteral( 
"authcfg" ), mAuthConfigId );
 
 
  705  mAuthConfigId.clear();
 
  708  url.setQuery( QString::fromLatin1( 
uri ) );
 
  709  const QUrlQuery query( url );
 
  713  const auto constQueryItems = query.queryItems();
 
  714  for ( 
const QPair<QString, QString> &item : constQueryItems )
 
  718      if ( item.first == QLatin1String( 
"username" ) )
 
  719        mUsername = query.queryItemValue( QStringLiteral( 
"username" ), QUrl::ComponentFormattingOption::FullyDecoded );
 
  720      else if ( item.first == QLatin1String( 
"password" ) )
 
  721        mPassword = query.queryItemValue( QStringLiteral( 
"password" ), QUrl::ComponentFormattingOption::FullyDecoded );
 
  722      else if ( item.first == QLatin1String( 
"authcfg" ) )
 
  723        mAuthConfigId = query.queryItemValue( QStringLiteral( 
"authcfg" ), QUrl::ComponentFormattingOption::FullyDecoded );
 
  725        mParams.insert( item.first, item.second );
 
 
  734  setEncodedUri( url.query( QUrl::EncodeUnicode ).toLatin1() );
 
 
  739  if ( !mSchema.isEmpty() )
 
  740    return QStringLiteral( 
"\"%1\".\"%2\"" )
 
  741           .arg( escape( mSchema, 
'"' ),
 
  742                 escape( mTable, 
'"' ) );
 
  744    return QStringLiteral( 
"\"%1\"" )
 
  745           .arg( escape( mTable, 
'"' ) );
 
 
  750                                      const QString &database,
 
  751                                      const QString &username,
 
  752                                      const QString &password,
 
  754                                      const QString &authConfigId )
 
 
  766                                      const QString &database,
 
  767                                      const QString &username,
 
  768                                      const QString &password,
 
  770                                      const QString &authConfigId )
 
 
  781                                      const QString &table,
 
  782                                      const QString &geometryColumn,
 
  784                                      const QString &keyColumn )
 
 
  795  mAuthConfigId = authcfg;
 
 
  825  if ( 
sslMode == QLatin1String( 
"prefer" ) )
 
  827  else if ( 
sslMode == QLatin1String( 
"disable" ) )
 
  829  else if ( 
sslMode == QLatin1String( 
"allow" ) )
 
  831  else if ( 
sslMode == QLatin1String( 
"require" ) )
 
  833  else if ( 
sslMode == QLatin1String( 
"verify-ca" ) )
 
  835  else if ( 
sslMode == QLatin1String( 
"verify-full" ) )
 
 
  845    case SslPrefer: 
return QStringLiteral( 
"prefer" );
 
  846    case SslDisable: 
return QStringLiteral( 
"disable" );
 
  847    case SslAllow: 
return QStringLiteral( 
"allow" );
 
  848    case SslRequire: 
return QStringLiteral( 
"require" );
 
  849    case SslVerifyCa: 
return QStringLiteral( 
"verify-ca" );
 
 
  858  if ( key == QLatin1String( 
"username" ) )
 
  860  else if ( key == QLatin1String( 
"password" ) )
 
  862  else if ( key == QLatin1String( 
"authcfg" ) )
 
  863    mAuthConfigId = value;
 
  867    mParams.insert( key, value );
 
 
  873  for ( 
const QString &val : value )
 
 
  881  if ( key == QLatin1String( 
"username" ) && !mUsername.isEmpty() )
 
  886  else if ( key == QLatin1String( 
"password" ) && !mPassword.isEmpty() )
 
  891  else if ( key == QLatin1String( 
"authcfg" ) && !mAuthConfigId.isEmpty() )
 
  893    mAuthConfigId.clear();
 
  897  return mParams.remove( key );
 
 
  903  if ( key == QLatin1String( 
"username" ) && !mUsername.isEmpty() )
 
  905  else if ( key == QLatin1String( 
"password" ) && !mPassword.isEmpty() )
 
  907  else if ( key == QLatin1String( 
"authcfg" ) && !mAuthConfigId.isEmpty() )
 
  908    return mAuthConfigId;
 
  910  return mParams.value( key );
 
 
  916  if ( key == QLatin1String( 
"username" ) && !mUsername.isEmpty() )
 
  917    return QStringList() << mUsername;
 
  918  else if ( key == QLatin1String( 
"password" ) && !mPassword.isEmpty() )
 
  919    return QStringList() << mPassword;
 
  920  else if ( key == QLatin1String( 
"authcfg" ) && !mAuthConfigId.isEmpty() )
 
  921    return QStringList() << mAuthConfigId;
 
  923  return mParams.values( key );
 
 
  929  if ( key == QLatin1String( 
"username" ) && !mUsername.isEmpty() )
 
  931  else if ( key == QLatin1String( 
"password" ) && !mPassword.isEmpty() )
 
  933  else if ( key == QLatin1String( 
"authcfg" ) && !mAuthConfigId.isEmpty() )
 
  936  return mParams.contains( key );
 
 
  941  QSet<QString> paramKeys;
 
  942  for ( 
auto it = mParams.constBegin(); it != mParams.constEnd(); it++ )
 
  943    paramKeys.insert( it.key() );
 
  945  if ( !mHost.isEmpty() )
 
  946    paramKeys.insert( QLatin1String( 
"host" ) );
 
  947  if ( !mPort.isEmpty() )
 
  948    paramKeys.insert( QLatin1String( 
"port" ) );
 
  949  if ( !mDriver.isEmpty() )
 
  950    paramKeys.insert( QLatin1String( 
"driver" ) );
 
  951  if ( !mService.isEmpty() )
 
  952    paramKeys.insert( QLatin1String( 
"service" ) );
 
  953  if ( !mDatabase.isEmpty() )
 
  954    paramKeys.insert( QLatin1String( 
"dbname" ) );
 
  955  if ( !mSchema.isEmpty() )
 
  956    paramKeys.insert( QLatin1String( 
"schema" ) );
 
  957  if ( !mTable.isEmpty() )
 
  958    paramKeys.insert( QLatin1String( 
"table" ) );
 
  960  if ( !mSql.isEmpty() )
 
  961    paramKeys.insert( QLatin1String( 
"sql" ) );
 
  962  if ( !mAuthConfigId.isEmpty() )
 
  963    paramKeys.insert( QLatin1String( 
"authcfg" ) );
 
  964  if ( !mUsername.isEmpty() )
 
  965    paramKeys.insert( QLatin1String( 
"username" ) );
 
  966  if ( !mPassword.isEmpty() )
 
  967    paramKeys.insert( QLatin1String( 
"password" ) );
 
  969    paramKeys.insert( QLatin1String( 
"sslmode" ) );
 
  970  if ( !mKeyColumn.isEmpty() )
 
  971    paramKeys.insert( QLatin1String( 
"key" ) );
 
  972  if ( mUseEstimatedMetadata )
 
  973    paramKeys.insert( QLatin1String( 
"estimatedmetadata" ) );
 
  974  if ( mSelectAtIdDisabledSet )
 
  975    paramKeys.insert( QLatin1String( 
"selectatid" ) );
 
  977    paramKeys.insert( QLatin1String( 
"type" ) );
 
  978  if ( !mSrid.isEmpty() )
 
  979    paramKeys.insert( QLatin1String( 
"srid" ) );
 
 
WkbType
The WKB type describes the number of dimensions a geometry has.
 
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
 
QString srid() const
Returns the spatial reference ID associated with the URI.
 
SslMode
Available SSL connection modes.
 
void setConnection(const QString &aHost, const QString &aPort, const QString &aDatabase, const QString &aUsername, const QString &aPassword, SslMode sslmode=SslPrefer, const QString &authConfigId=QString())
Sets all connection related members at once.
 
QByteArray encodedUri() const
Returns the complete encoded URI as a byte array.
 
QStringList params(const QString &key) const
Returns multiple generic parameter values corresponding to the specified key.
 
void setSchema(const QString &schema)
Sets the scheme for the URI.
 
bool hasParam(const QString &key) const
Returns true if a parameter with the specified key exists.
 
int removeParam(const QString &key)
Removes a generic parameter by key.
 
static SslMode decodeSslMode(const QString &sslMode)
Decodes SSL mode string into enum value.
 
void setSql(const QString &sql)
Sets the sql filter for the URI.
 
void setEncodedUri(const QByteArray &uri)
Sets the complete encoded uri.
 
QString table() const
Returns the table name stored in the URI.
 
void setTable(const QString &table)
Sets table to table.
 
void setAuthConfigId(const QString &authcfg)
Sets the authentication configuration ID for the URI.
 
QString quotedTablename() const
Returns the URI's table name, escaped and quoted.
 
void setGeometryColumn(const QString &geometryColumn)
Sets geometry column name to geometryColumn.
 
QString schema() const
Returns the schema stored in the URI.
 
void setUseEstimatedMetadata(bool flag)
Sets whether estimated metadata should be used for the connection.
 
QString connectionInfo(bool expandAuthConfig=true) const
Returns the connection part of the URI.
 
QString uri(bool expandAuthConfig=true) const
Returns the complete URI as a string.
 
void setUsername(const QString &username)
Sets the username for the URI.
 
QString param(const QString &key) const
Returns a generic parameter value corresponding to the specified key.
 
void disableSelectAtId(bool flag)
Set to true to disable selection by feature ID.
 
bool selectAtIdDisabled() const
Returns whether the selection by feature ID is disabled.
 
void setDataSource(const QString &aSchema, const QString &aTable, const QString &aGeometryColumn, const QString &aSql=QString(), const QString &aKeyColumn=QString())
Sets all data source related members at once.
 
QString username() const
Returns the username stored in the URI.
 
static QString encodeSslMode(SslMode sslMode)
Encodes SSL mode enum value into a string.
 
Qgis::WkbType wkbType() const
Returns the WKB type associated with the URI.
 
void setWkbType(Qgis::WkbType type)
Sets the WKB type associated with the URI.
 
QString driver() const
Returns the driver name stored in the URI.
 
QString host() const
Returns the host name stored in the URI.
 
void setParam(const QString &key, const QString &value)
Sets a generic parameter value on the URI.
 
QString service() const
Returns the service name associated with the URI.
 
void setKeyColumn(const QString &column)
Sets the name of the (primary) key column.
 
bool useEstimatedMetadata() const
Returns true if estimated metadata should be used for the connection.
 
SslMode sslMode() const
Returns the SSL mode associated with the URI.
 
QString password() const
Returns the password stored in the URI.
 
QString keyColumn() const
Returns the name of the (primary) key column for the referenced table.
 
QString authConfigId() const
Returns any associated authentication configuration ID stored in the URI.
 
QString port() const
Returns the port stored in the URI.
 
QSet< QString > parameterKeys() const
Returns parameter keys used in the uri: specialized ones ("table", "schema", etc.) or generic paramet...
 
QString database() const
Returns the database name stored in the URI.
 
void clearSchema()
Clears the schema stored in the URI.
 
void setDriver(const QString &driver)
Sets the driver name stored in the URI.
 
static QString removePassword(const QString &aUri, bool hide=false)
Removes the password element from a URI.
 
void setDatabase(const QString &database)
Sets the URI database name.
 
QString geometryColumn() const
Returns the name of the geometry column stored in the URI, if set.
 
void setSrid(const QString &srid)
Sets the spatial reference ID associated with the URI.
 
QString sql() const
Returns the SQL filter stored in the URI, if set.
 
void setPassword(const QString &password)
Sets the password for the URI.
 
static Qgis::WkbType parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
 
static QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
 
QByteArray toLatin1_helper(const QString &string)
 
#define QgsDebugMsgLevel(str, level)
 
#define QgsDebugError(str)