25 #include <QStringList> 
   26 #include <QRegularExpression> 
   39   while ( i < 
uri.length() )
 
   45       QgsDebugMsg( QStringLiteral( 
"parameter name expected before =" ) );
 
   52     while ( i < 
uri.length() && 
uri[i] != 
'=' && !
uri[i].isSpace() )
 
   55     const QString pname = 
uri.mid( start, i - start );
 
   59     if ( i == 
uri.length() || 
uri[i] != 
'=' )
 
   67     if ( pname == QLatin1String( 
"sql" ) )
 
   76       const QString pval = getValue( 
uri, i );
 
   78       if ( pname == QLatin1String( 
"table" ) )
 
   80         if ( i < 
uri.length() && 
uri[i] == 
'.' )
 
   85           mTable = getValue( 
uri, i );
 
   92         if ( i < 
uri.length() && 
uri[i] == 
'(' )
 
   97           while ( i < 
uri.length() && 
uri[i] != 
')' )
 
  104           if ( i == 
uri.length() )
 
  106             QgsDebugMsg( QStringLiteral( 
"closing parenthesis missing" ) );
 
  109           mGeometryColumn = 
uri.mid( start, i - start );
 
  110           mGeometryColumn.replace( QLatin1String( 
"\\)" ), QLatin1String( 
")" ) );
 
  111           mGeometryColumn.replace( QLatin1String( 
"\\\\" ), QLatin1String( 
"\\" ) );
 
  117           mGeometryColumn = QString();
 
  120       else if ( pname == QLatin1String( 
"schema" ) )
 
  124       else if ( pname == QLatin1String( 
"key" ) )
 
  128       else if ( pname == QLatin1String( 
"estimatedmetadata" ) )
 
  130         mUseEstimatedMetadata = pval == QLatin1String( 
"true" );
 
  132       else if ( pname == QLatin1String( 
"srid" ) )
 
  136       else if ( pname == QLatin1String( 
"type" ) )
 
  140       else if ( pname == QLatin1String( 
"selectatid" ) )
 
  142         mSelectAtIdDisabledSet = 
true;
 
  143         mSelectAtIdDisabled = pval == QLatin1String( 
"false" );
 
  145       else if ( pname == QLatin1String( 
"service" ) )
 
  149       else if ( pname == QLatin1String( 
"authcfg" ) )
 
  151         mAuthConfigId = pval;
 
  153       else if ( pname == QLatin1String( 
"user" ) || pname == QLatin1String( 
"username" ) ) 
 
  157       else if ( pname == QLatin1String( 
"password" ) )
 
  161       else if ( pname == QLatin1String( 
"connect_timeout" ) )
 
  165       else if ( pname == QLatin1String( 
"dbname" ) )
 
  169       else if ( pname == QLatin1String( 
"host" ) )
 
  173       else if ( pname == QLatin1String( 
"hostaddr" ) )
 
  175         QgsDebugMsg( QStringLiteral( 
"database host ip address ignored" ) );
 
  177       else if ( pname == QLatin1String( 
"port" ) )
 
  181       else if ( pname == QLatin1String( 
"driver" ) )
 
  185       else if ( pname == QLatin1String( 
"tty" ) )
 
  187         QgsDebugMsg( QStringLiteral( 
"backend debug tty ignored" ) );
 
  189       else if ( pname == QLatin1String( 
"options" ) )
 
  191         QgsDebugMsg( QStringLiteral( 
"backend debug options ignored" ) );
 
  193       else if ( pname == QLatin1String( 
"sslmode" ) )
 
  197       else if ( pname == QLatin1String( 
"requiressl" ) )
 
  199         if ( pval == QLatin1String( 
"0" ) )
 
  204       else if ( pname == QLatin1String( 
"krbsrvname" ) )
 
  206         QgsDebugMsg( QStringLiteral( 
"kerberos server name ignored" ) );
 
  208       else if ( pname == QLatin1String( 
"gsslib" ) )
 
  214         QgsDebugMsgLevel( 
"parameter \"" + pname + 
"\":\"" + pval + 
"\" added", 4 );
 
  223   QRegularExpression regexp;
 
  224   regexp.setPatternOptions( QRegularExpression::InvertedGreedinessOption );
 
  225   QString safeName( aUri );
 
  226   if ( aUri.contains( QLatin1String( 
" password=" ) ) )
 
  228     regexp.setPattern( QStringLiteral( 
" password=.* " ) );
 
  229     safeName.replace( regexp, QStringLiteral( 
" " ) );
 
  231   else if ( aUri.contains( QLatin1String( 
",password=" ) ) )
 
  233     regexp.setPattern( QStringLiteral( 
",password=.*," ) );
 
  234     safeName.replace( regexp, QStringLiteral( 
"," ) );
 
  236   else if ( aUri.contains( QLatin1String( 
"IDB:" ) ) )
 
  238     regexp.setPattern( QStringLiteral( 
" pass=.* " ) );
 
  239     safeName.replace( regexp, QStringLiteral( 
" " ) );
 
  241   else if ( ( aUri.contains( QLatin1String( 
"OCI:" ) ) )
 
  242             || ( aUri.contains( QLatin1String( 
"ODBC:" ) ) ) )
 
  244     regexp.setPattern( QStringLiteral( 
"/.*@" ) );
 
  245     safeName.replace( regexp, QStringLiteral( 
"/@" ) );
 
  247   else if ( aUri.contains( QLatin1String( 
"SDE:" ) ) )
 
  249     QStringList strlist = aUri.split( 
',' );
 
  250     safeName = strlist[0] + 
',' + strlist[1] + 
',' + strlist[2] + 
',' + strlist[3];
 
  257   return mAuthConfigId;
 
  327   return mGeometryColumn;
 
  350   mUseEstimatedMetadata = flag;
 
  355   return mUseEstimatedMetadata;
 
  360   mSelectAtIdDisabledSet = 
true;
 
  361   mSelectAtIdDisabled = flag;
 
  366   return mSelectAtIdDisabled;
 
  384 QString QgsDataSourceUri::escape( 
const QString &val, QChar delim = 
'\'' )
 const 
  386   QString escaped = val;
 
  388   escaped.replace( 
'\\', QLatin1String( 
"\\\\" ) );
 
  389   escaped.replace( delim, QStringLiteral( 
"\\%1" ).arg( delim ) );
 
  404 void QgsDataSourceUri::skipBlanks( 
const QString &uri, 
int &i )
 
  407   while ( i < 
uri.length() && 
uri[i].isSpace() )
 
  411 QString QgsDataSourceUri::getValue( 
const QString &uri, 
int &i )
 
  413   skipBlanks( 
uri, i );
 
  417   if ( i < 
uri.length() && ( 
uri[i] == 
'\'' || 
uri[i] == 
'"' ) )
 
  419     const QChar delim = 
uri[i];
 
  426       if ( i == 
uri.length() )
 
  428         QgsDebugMsg( QStringLiteral( 
"unterminated quoted string in connection info string" ) );
 
  432       if ( 
uri[i] == 
'\\' )
 
  435         if ( i == 
uri.length() )
 
  437         if ( 
uri[i] != delim && 
uri[i] != 
'\\' )
 
  440       else if ( 
uri[i] == delim )
 
  452     while ( i < 
uri.length() )
 
  454       if ( 
uri[i].isSpace() )
 
  460       if ( 
uri[i] == 
'\\' )
 
  463         if ( i == 
uri.length() )
 
  465         if ( 
uri[i] != 
'\\' && 
uri[i] != 
'\'' )
 
  473   skipBlanks( 
uri, i );
 
  480   QStringList connectionItems;
 
  482   if ( !mDatabase.isEmpty() )
 
  484     connectionItems << 
"dbname='" + escape( mDatabase ) + 
'\'';
 
  487   if ( !mService.isEmpty() )
 
  489     connectionItems << 
"service='" + escape( mService ) + 
'\'';
 
  491   else if ( !mHost.isEmpty() )
 
  493     connectionItems << 
"host=" + mHost;
 
  496   if ( mService.isEmpty() )
 
  498     if ( !mPort.isEmpty() )
 
  499       connectionItems << 
"port=" + mPort;
 
  502   if ( !mDriver.isEmpty() )
 
  504     connectionItems << 
"driver='" + escape( mDriver ) + 
'\'';
 
  507   if ( !mUsername.isEmpty() )
 
  509     connectionItems << 
"user='" + escape( mUsername ) + 
'\'';
 
  511     if ( !mPassword.isEmpty() )
 
  513       connectionItems << 
"password='" + escape( mPassword ) + 
'\'';
 
  519     connectionItems << QStringLiteral( 
"sslmode=" ) + 
encodeSslMode( mSSLmode );
 
  522   if ( !mAuthConfigId.isEmpty() )
 
  524     if ( expandAuthConfig )
 
  528         QgsDebugMsg( QStringLiteral( 
"Data source URI FAILED to update via loading configuration ID '%1'" ).arg( mAuthConfigId ) );
 
  533       connectionItems << 
"authcfg=" + mAuthConfigId;
 
  537   return connectionItems.join( QLatin1Char( 
' ' ) );
 
  544   if ( !mKeyColumn.isEmpty() )
 
  546     uri += QStringLiteral( 
" key='%1'" ).arg( escape( mKeyColumn ) );
 
  549   if ( mUseEstimatedMetadata )
 
  551     uri += QLatin1String( 
" estimatedmetadata=true" );
 
  554   if ( !mSrid.isEmpty() )
 
  556     uri += QStringLiteral( 
" srid=%1" ).arg( mSrid );
 
  561     uri += QLatin1String( 
" type=" );
 
  565   if ( mSelectAtIdDisabled )
 
  567     uri += QLatin1String( 
" selectatid=false" );
 
  570   for ( 
auto it = mParams.constBegin(); it != mParams.constEnd(); ++it )
 
  572     if ( it.key().contains( 
'=' ) || it.key().contains( 
' ' ) )
 
  574       QgsDebugMsg( QStringLiteral( 
"invalid uri parameter %1 skipped" ).arg( it.key() ) );
 
  578     uri += 
' ' + it.key() + 
"='" + escape( it.value() ) + 
'\'';
 
  583   QString columnName( mGeometryColumn );
 
  584   columnName.replace( 
'\\', QLatin1String( 
"\\\\" ) );
 
  585   columnName.replace( 
')', QLatin1String( 
"\\)" ) );
 
  587   if ( !mTable.isEmpty() )
 
  589     uri += QStringLiteral( 
" table=%1%2" )
 
  591                  mGeometryColumn.isEmpty() ? QString() : QStringLiteral( 
" (%1)" ).arg( columnName ) );
 
  593   else if ( !mSchema.isEmpty() )
 
  595     uri += QStringLiteral( 
" schema='%1'" ).arg( escape( mSchema ) );
 
  598   if ( !mSql.isEmpty() )
 
  600     uri += QStringLiteral( 
" sql=" ) + mSql;
 
  609   if ( 
string.isEmpty() )
 
  610     return string.isNull() ? QByteArray() : QByteArray( 
"" );
 
  611   return string.toLatin1();
 
  617   for ( 
auto it = mParams.constBegin(); it != mParams.constEnd(); ++it )
 
  619     url.addQueryItem( it.key(), it.value() );
 
  622   if ( !mUsername.isEmpty() )
 
  623     url.addQueryItem( QStringLiteral( 
"username" ), mUsername );
 
  625   if ( !mPassword.isEmpty() )
 
  626     url.addQueryItem( QStringLiteral( 
"password" ), mPassword );
 
  628   if ( !mAuthConfigId.isEmpty() )
 
  629     url.addQueryItem( QStringLiteral( 
"authcfg" ), mAuthConfigId );
 
  641   mAuthConfigId.clear();
 
  644   url.setQuery( QString::fromLatin1( 
uri ) );
 
  645   const QUrlQuery query( url );
 
  649   const auto constQueryItems = query.queryItems( QUrl::ComponentFormattingOption::FullyDecoded );
 
  650   for ( 
const QPair<QString, QString> &item : constQueryItems )
 
  654       if ( item.first == QLatin1String( 
"username" ) )
 
  655         mUsername = item.second;
 
  656       else if ( item.first == QLatin1String( 
"password" ) )
 
  657         mPassword = item.second;
 
  658       else if ( item.first == QLatin1String( 
"authcfg" ) )
 
  659         mAuthConfigId = item.second;
 
  661         mParams.insert( item.first, item.second );
 
  673   if ( !mSchema.isEmpty() )
 
  674     return QStringLiteral( 
"\"%1\".\"%2\"" )
 
  675            .arg( escape( mSchema, 
'"' ),
 
  676                  escape( mTable, 
'"' ) );
 
  678     return QStringLiteral( 
"\"%1\"" )
 
  679            .arg( escape( mTable, 
'"' ) );
 
  684                                       const QString &database,
 
  685                                       const QString &username,
 
  686                                       const QString &password,
 
  688                                       const QString &authConfigId )
 
  700                                       const QString &database,
 
  701                                       const QString &username,
 
  702                                       const QString &password,
 
  704                                       const QString &authConfigId )
 
  715                                       const QString &table,
 
  716                                       const QString &geometryColumn,
 
  718                                       const QString &keyColumn )
 
  729   mAuthConfigId = authcfg;
 
  759   if ( 
sslMode == QLatin1String( 
"prefer" ) )
 
  761   else if ( 
sslMode == QLatin1String( 
"disable" ) )
 
  763   else if ( 
sslMode == QLatin1String( 
"allow" ) )
 
  765   else if ( 
sslMode == QLatin1String( 
"require" ) )
 
  767   else if ( 
sslMode == QLatin1String( 
"verify-ca" ) )
 
  769   else if ( 
sslMode == QLatin1String( 
"verify-full" ) )
 
  779     case SslPrefer: 
return QStringLiteral( 
"prefer" );
 
  780     case SslDisable: 
return QStringLiteral( 
"disable" );
 
  781     case SslAllow: 
return QStringLiteral( 
"allow" );
 
  782     case SslRequire: 
return QStringLiteral( 
"require" );
 
  783     case SslVerifyCa: 
return QStringLiteral( 
"verify-ca" );
 
  792   if ( key == QLatin1String( 
"username" ) )
 
  794   else if ( key == QLatin1String( 
"password" ) )
 
  796   else if ( key == QLatin1String( 
"authcfg" ) )
 
  797     mAuthConfigId = value;
 
  801     mParams.insert( key, value );
 
  807   for ( 
const QString &val : value )
 
  815   if ( key == QLatin1String( 
"username" ) && !mUsername.isEmpty() )
 
  820   else if ( key == QLatin1String( 
"password" ) && !mPassword.isEmpty() )
 
  825   else if ( key == QLatin1String( 
"authcfg" ) && !mAuthConfigId.isEmpty() )
 
  827     mAuthConfigId.clear();
 
  831   return mParams.remove( key );
 
  837   if ( key == QLatin1String( 
"username" ) && !mUsername.isEmpty() )
 
  839   else if ( key == QLatin1String( 
"password" ) && !mPassword.isEmpty() )
 
  841   else if ( key == QLatin1String( 
"authcfg" ) && !mAuthConfigId.isEmpty() )
 
  842     return mAuthConfigId;
 
  844   return mParams.value( key );
 
  850   if ( key == QLatin1String( 
"username" ) && !mUsername.isEmpty() )
 
  851     return QStringList() << mUsername;
 
  852   else if ( key == QLatin1String( 
"password" ) && !mPassword.isEmpty() )
 
  853     return QStringList() << mPassword;
 
  854   else if ( key == QLatin1String( 
"authcfg" ) && !mAuthConfigId.isEmpty() )
 
  855     return QStringList() << mAuthConfigId;
 
  857   return mParams.values( key );
 
  863   if ( key == QLatin1String( 
"username" ) && !mUsername.isEmpty() )
 
  865   else if ( key == QLatin1String( 
"password" ) && !mPassword.isEmpty() )
 
  867   else if ( key == QLatin1String( 
"authcfg" ) && !mAuthConfigId.isEmpty() )
 
  870   return mParams.contains( key );
 
  875   QSet<QString> paramKeys;
 
  876   for ( 
const QString &key : mParams.keys() )
 
  877     paramKeys.insert( key );
 
  878   if ( !mHost.isEmpty() )
 
  879     paramKeys.insert( QLatin1String( 
"host" ) );
 
  880   if ( !mPort.isEmpty() )
 
  881     paramKeys.insert( QLatin1String( 
"port" ) );
 
  882   if ( !mDriver.isEmpty() )
 
  883     paramKeys.insert( QLatin1String( 
"driver" ) );
 
  884   if ( !mService.isEmpty() )
 
  885     paramKeys.insert( QLatin1String( 
"service" ) );
 
  886   if ( !mDatabase.isEmpty() )
 
  887     paramKeys.insert( QLatin1String( 
"dbname" ) );
 
  888   if ( !mSchema.isEmpty() )
 
  889     paramKeys.insert( QLatin1String( 
"schema" ) );
 
  890   if ( !mTable.isEmpty() )
 
  891     paramKeys.insert( QLatin1String( 
"table" ) );
 
  893   if ( !mSql.isEmpty() )
 
  894     paramKeys.insert( QLatin1String( 
"sql" ) );
 
  895   if ( !mAuthConfigId.isEmpty() )
 
  896     paramKeys.insert( QLatin1String( 
"authcfg" ) );
 
  897   if ( !mUsername.isEmpty() )
 
  898     paramKeys.insert( QLatin1String( 
"username" ) );
 
  899   if ( !mPassword.isEmpty() )
 
  900     paramKeys.insert( QLatin1String( 
"password" ) );
 
  902     paramKeys.insert( QLatin1String( 
"sslmode" ) );
 
  903   if ( !mKeyColumn.isEmpty() )
 
  904     paramKeys.insert( QLatin1String( 
"key" ) );
 
  905   if ( mUseEstimatedMetadata )
 
  906     paramKeys.insert( QLatin1String( 
"estimatedmetadata" ) );
 
  907   if ( mSelectAtIdDisabledSet )
 
  908     paramKeys.insert( QLatin1String( 
"selectatid" ) );
 
  910     paramKeys.insert( QLatin1String( 
"type" ) );
 
  911   if ( !mSrid.isEmpty() )
 
  912     paramKeys.insert( QLatin1String( 
"srid" ) );