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 );
737 if ( !mSchema.isEmpty() )
738 return QStringLiteral(
"\"%1\".\"%2\"" )
739 .arg( escape( mSchema,
'"' ),
740 escape( mTable,
'"' ) );
742 return QStringLiteral(
"\"%1\"" )
743 .arg( escape( mTable,
'"' ) );
748 const QString &database,
749 const QString &username,
750 const QString &password,
752 const QString &authConfigId )
764 const QString &database,
765 const QString &username,
766 const QString &password,
768 const QString &authConfigId )
779 const QString &table,
780 const QString &geometryColumn,
782 const QString &keyColumn )
793 mAuthConfigId = authcfg;
823 if (
sslMode == QLatin1String(
"prefer" ) )
825 else if (
sslMode == QLatin1String(
"disable" ) )
827 else if (
sslMode == QLatin1String(
"allow" ) )
829 else if (
sslMode == QLatin1String(
"require" ) )
831 else if (
sslMode == QLatin1String(
"verify-ca" ) )
833 else if (
sslMode == QLatin1String(
"verify-full" ) )
843 case SslPrefer:
return QStringLiteral(
"prefer" );
844 case SslDisable:
return QStringLiteral(
"disable" );
845 case SslAllow:
return QStringLiteral(
"allow" );
846 case SslRequire:
return QStringLiteral(
"require" );
847 case SslVerifyCa:
return QStringLiteral(
"verify-ca" );
856 if ( key == QLatin1String(
"username" ) )
858 else if ( key == QLatin1String(
"password" ) )
860 else if ( key == QLatin1String(
"authcfg" ) )
861 mAuthConfigId = value;
865 mParams.insert( key, value );
871 for (
const QString &val : value )
879 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
884 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
889 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
891 mAuthConfigId.clear();
895 return mParams.remove( key );
901 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
903 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
905 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
906 return mAuthConfigId;
908 return mParams.value( key );
914 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
915 return QStringList() << mUsername;
916 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
917 return QStringList() << mPassword;
918 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
919 return QStringList() << mAuthConfigId;
921 return mParams.values( key );
927 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
929 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
931 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
934 return mParams.contains( key );
939 QSet<QString> paramKeys;
940 for (
auto it = mParams.constBegin(); it != mParams.constEnd(); it++ )
941 paramKeys.insert( it.key() );
943 if ( !mHost.isEmpty() )
944 paramKeys.insert( QLatin1String(
"host" ) );
945 if ( !mPort.isEmpty() )
946 paramKeys.insert( QLatin1String(
"port" ) );
947 if ( !mDriver.isEmpty() )
948 paramKeys.insert( QLatin1String(
"driver" ) );
949 if ( !mService.isEmpty() )
950 paramKeys.insert( QLatin1String(
"service" ) );
951 if ( !mDatabase.isEmpty() )
952 paramKeys.insert( QLatin1String(
"dbname" ) );
953 if ( !mSchema.isEmpty() )
954 paramKeys.insert( QLatin1String(
"schema" ) );
955 if ( !mTable.isEmpty() )
956 paramKeys.insert( QLatin1String(
"table" ) );
958 if ( !mSql.isEmpty() )
959 paramKeys.insert( QLatin1String(
"sql" ) );
960 if ( !mAuthConfigId.isEmpty() )
961 paramKeys.insert( QLatin1String(
"authcfg" ) );
962 if ( !mUsername.isEmpty() )
963 paramKeys.insert( QLatin1String(
"username" ) );
964 if ( !mPassword.isEmpty() )
965 paramKeys.insert( QLatin1String(
"password" ) );
967 paramKeys.insert( QLatin1String(
"sslmode" ) );
968 if ( !mKeyColumn.isEmpty() )
969 paramKeys.insert( QLatin1String(
"key" ) );
970 if ( mUseEstimatedMetadata )
971 paramKeys.insert( QLatin1String(
"estimatedmetadata" ) );
972 if ( mSelectAtIdDisabledSet )
973 paramKeys.insert( QLatin1String(
"selectatid" ) );
975 paramKeys.insert( QLatin1String(
"type" ) );
976 if ( !mSrid.isEmpty() )
977 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)