20#include "moc_qgsdatasourceuri.cpp"
27#include <QRegularExpression>
31#define HIDING_TOKEN QStringLiteral( "XXXXXXXX" )
42 while ( i <
uri.length() )
48 QgsDebugError( QStringLiteral(
"parameter name expected before =" ) );
55 while ( i <
uri.length() &&
uri[i] !=
'=' && !
uri[i].isSpace() )
58 const QString pname =
uri.mid( start, i - start );
62 if ( i ==
uri.length() ||
uri[i] !=
'=' )
70 if ( pname == QLatin1String(
"sql" ) )
79 if ( mSql == QLatin1String(
"''" ) || mSql == QLatin1String(
"\"\"" ) )
85 const QString pval = getValue(
uri, i );
87 if ( pname == QLatin1String(
"table" ) )
89 if ( i <
uri.length() &&
uri[i] ==
'.' )
94 mTable = getValue(
uri, i );
101 if ( i <
uri.length() &&
uri[i] ==
'(' )
106 while ( i <
uri.length() &&
uri[i] !=
')' )
108 if (
uri[i] ==
'\\' )
113 if ( i ==
uri.length() )
115 QgsDebugError( QStringLiteral(
"closing parenthesis missing" ) );
118 mGeometryColumn =
uri.mid( start, i - start );
119 mGeometryColumn.replace( QLatin1String(
"\\)" ), QLatin1String(
")" ) );
120 mGeometryColumn.replace( QLatin1String(
"\\\\" ), QLatin1String(
"\\" ) );
126 mGeometryColumn = QString();
129 else if ( pname == QLatin1String(
"schema" ) )
133 else if ( pname == QLatin1String(
"key" ) )
137 else if ( pname == QLatin1String(
"estimatedmetadata" ) )
139 mUseEstimatedMetadata = pval == QLatin1String(
"true" );
141 else if ( pname == QLatin1String(
"srid" ) )
145 else if ( pname == QLatin1String(
"type" ) )
149 else if ( pname == QLatin1String(
"selectatid" ) )
151 mSelectAtIdDisabledSet =
true;
152 mSelectAtIdDisabled = pval == QLatin1String(
"false" );
154 else if ( pname == QLatin1String(
"service" ) )
158 else if ( pname == QLatin1String(
"authcfg" ) )
160 mAuthConfigId = pval;
162 else if ( pname == QLatin1String(
"user" ) || pname == QLatin1String(
"username" ) )
166 else if ( pname == QLatin1String(
"password" ) )
170 else if ( pname == QLatin1String(
"connect_timeout" ) )
174 else if ( pname == QLatin1String(
"dbname" ) )
178 else if ( pname == QLatin1String(
"host" ) )
182 else if ( pname == QLatin1String(
"hostaddr" ) )
184 QgsDebugMsgLevel( QStringLiteral(
"database host ip address ignored" ), 2 );
186 else if ( pname == QLatin1String(
"port" ) )
190 else if ( pname == QLatin1String(
"driver" ) )
194 else if ( pname == QLatin1String(
"tty" ) )
198 else if ( pname == QLatin1String(
"options" ) )
202 else if ( pname == QLatin1String(
"sslmode" ) )
206 else if ( pname == QLatin1String(
"requiressl" ) )
208 if ( pval == QLatin1String(
"0" ) )
213 else if ( pname == QLatin1String(
"krbsrvname" ) )
217 else if ( pname == QLatin1String(
"gsslib" ) )
223 mHttpHeaders.
insert( pname, pval );
227 QgsDebugMsgLevel(
"parameter \"" + pname +
"\":\"" + pval +
"\" added", 4 );
236 QRegularExpression regexp;
237 regexp.setPatternOptions( QRegularExpression::InvertedGreedinessOption );
238 QString safeName( aUri );
239 if ( aUri.contains( QLatin1String(
" password=" ) ) )
241 regexp.setPattern( QStringLiteral(
" password=.* " ) );
245 safeName.replace( regexp, QStringLiteral(
" password=%1 " ).arg(
HIDING_TOKEN ) );
249 safeName.replace( regexp, QStringLiteral(
" " ) );
252 else if ( aUri.contains( QLatin1String(
",password=" ) ) )
254 regexp.setPattern( QStringLiteral(
",password=.*," ) );
258 safeName.replace( regexp, QStringLiteral(
",password=%1," ).arg(
HIDING_TOKEN ) );
262 safeName.replace( regexp, QStringLiteral(
"," ) );
265 else if ( aUri.contains( QLatin1String(
"IDB:" ) ) )
267 regexp.setPattern( QStringLiteral(
" pass=.* " ) );
271 safeName.replace( regexp, QStringLiteral(
" pass=%1 " ).arg(
HIDING_TOKEN ) );
275 safeName.replace( regexp, QStringLiteral(
" " ) );
278 else if ( ( aUri.contains( QLatin1String(
"OCI:" ) ) )
279 || ( aUri.contains( QLatin1String(
"ODBC:" ) ) ) )
281 regexp.setPattern( QStringLiteral(
"/.*@" ) );
285 safeName.replace( regexp, QStringLiteral(
"/%1@" ).arg(
HIDING_TOKEN ) );
289 safeName.replace( regexp, QStringLiteral(
"/@" ) );
292 else if ( aUri.contains( QLatin1String(
"postgresql:" ) ) )
295 regexp.setPattern( QStringLiteral(
"/.*@" ) );
296 const QString matched = regexp.match( aUri ).captured();
298 QString anonymised = matched;
299 const QStringList items = matched.split( QStringLiteral(
":" ) );
300 if ( items.size() > 1 )
302 anonymised = matched.split( QStringLiteral(
":" ) )[0];
305 anonymised.append( QStringLiteral(
":%1" ).arg(
HIDING_TOKEN ) );
307 anonymised.append( QStringLiteral(
"@" ) );
310 safeName.replace( regexp, anonymised );
312 else if ( aUri.contains( QLatin1String(
"SDE:" ) ) )
314 QStringList strlist = aUri.split(
',' );
315 safeName = strlist[0] +
',' + strlist[1] +
',' + strlist[2] +
',' + strlist[3];
322 return mAuthConfigId;
392 return mGeometryColumn;
415 mUseEstimatedMetadata = flag;
420 return mUseEstimatedMetadata;
425 mSelectAtIdDisabledSet =
true;
426 mSelectAtIdDisabled = flag;
431 return mSelectAtIdDisabled;
449QString QgsDataSourceUri::escape(
const QString &val, QChar delim =
'\'' )
const
451 QString escaped = val;
453 escaped.replace(
'\\', QLatin1String(
"\\\\" ) );
454 escaped.replace( delim, QStringLiteral(
"\\%1" ).arg( delim ) );
469void QgsDataSourceUri::skipBlanks(
const QString &uri,
int &i )
472 while ( i <
uri.length() &&
uri[i].isSpace() )
476QString QgsDataSourceUri::getValue(
const QString &uri,
int &i )
478 skipBlanks(
uri, i );
482 if ( i <
uri.length() && (
uri[i] ==
'\'' ||
uri[i] ==
'"' ) )
484 const QChar delim =
uri[i];
491 if ( i ==
uri.length() )
493 QgsDebugError( QStringLiteral(
"unterminated quoted string in connection info string" ) );
497 if (
uri[i] ==
'\\' )
500 if ( i ==
uri.length() )
502 if (
uri[i] != delim &&
uri[i] !=
'\\' )
505 else if (
uri[i] == delim )
517 while ( i <
uri.length() )
519 if (
uri[i].isSpace() )
525 if (
uri[i] ==
'\\' )
528 if ( i ==
uri.length() )
530 if (
uri[i] !=
'\\' &&
uri[i] !=
'\'' )
538 skipBlanks(
uri, i );
545 QStringList connectionItems;
547 if ( !mDatabase.isEmpty() )
549 connectionItems <<
"dbname='" + escape( mDatabase ) +
'\'';
552 if ( !mService.isEmpty() )
554 connectionItems <<
"service='" + escape( mService ) +
'\'';
556 else if ( !mHost.isEmpty() )
558 connectionItems <<
"host=" + mHost;
561 if ( mService.isEmpty() )
563 if ( !mPort.isEmpty() )
564 connectionItems <<
"port=" + mPort;
567 if ( !mDriver.isEmpty() )
569 connectionItems <<
"driver='" + escape( mDriver ) +
'\'';
572 if ( !mUsername.isEmpty() )
574 connectionItems <<
"user='" + escape( mUsername ) +
'\'';
576 if ( !mPassword.isEmpty() )
578 connectionItems <<
"password='" + escape( mPassword ) +
'\'';
584 connectionItems << QStringLiteral(
"sslmode=" ) +
encodeSslMode( mSSLmode );
587 if ( !mAuthConfigId.isEmpty() )
589 if ( expandAuthConfig )
593 QgsDebugError( QStringLiteral(
"Data source URI FAILED to update via loading configuration ID '%1'" ).arg( mAuthConfigId ) );
598 connectionItems <<
"authcfg=" + mAuthConfigId;
602 return connectionItems.join( QLatin1Char(
' ' ) );
609 if ( !mKeyColumn.isEmpty() )
611 uri += QStringLiteral(
" key='%1'" ).arg( escape( mKeyColumn ) );
614 if ( mUseEstimatedMetadata )
616 uri += QLatin1String(
" estimatedmetadata=true" );
619 if ( !mSrid.isEmpty() )
621 uri += QStringLiteral(
" srid=%1" ).arg( mSrid );
626 uri += QLatin1String(
" type=" );
630 if ( mSelectAtIdDisabled )
632 uri += QLatin1String(
" selectatid=false" );
635 for (
auto it = mParams.constBegin(); it != mParams.constEnd(); ++it )
637 if ( it.key().contains(
'=' ) || it.key().contains(
' ' ) )
639 QgsDebugError( QStringLiteral(
"invalid uri parameter %1 skipped" ).arg( it.key() ) );
643 uri +=
' ' + it.key() +
"='" + escape( it.value() ) +
'\'';
648 QString columnName( mGeometryColumn );
649 columnName.replace(
'\\', QLatin1String(
"\\\\" ) );
650 columnName.replace(
')', QLatin1String(
"\\)" ) );
652 if ( !mTable.isEmpty() )
654 uri += QStringLiteral(
" table=%1%2" )
656 mGeometryColumn.isEmpty() ? QString() : QStringLiteral(
" (%1)" ).arg( columnName ) );
658 else if ( !mSchema.isEmpty() )
660 uri += QStringLiteral(
" schema='%1'" ).arg( escape( mSchema ) );
663 if ( !mSql.isEmpty() )
665 uri += QStringLiteral(
" sql=" ) + mSql;
674 if (
string.isEmpty() )
675 return string.isNull() ? QByteArray() : QByteArray(
"" );
676 return string.toLatin1();
682 for (
auto it = mParams.constBegin(); it != mParams.constEnd(); ++it )
684 url.addQueryItem( it.key(), it.value() );
687 if ( !mUsername.isEmpty() )
688 url.addQueryItem( QStringLiteral(
"username" ), mUsername );
690 if ( !mPassword.isEmpty() )
691 url.addQueryItem( QStringLiteral(
"password" ), mPassword );
693 if ( !mAuthConfigId.isEmpty() )
694 url.addQueryItem( QStringLiteral(
"authcfg" ), mAuthConfigId );
706 mAuthConfigId.clear();
709 url.setQuery( QString::fromLatin1(
uri ) );
710 const QUrlQuery query( url );
714 const auto constQueryItems = query.queryItems();
715 for (
const QPair<QString, QString> &item : constQueryItems )
719 if ( item.first == QLatin1String(
"username" ) )
720 mUsername = query.queryItemValue( QStringLiteral(
"username" ), QUrl::ComponentFormattingOption::FullyDecoded );
721 else if ( item.first == QLatin1String(
"password" ) )
722 mPassword = query.queryItemValue( QStringLiteral(
"password" ), QUrl::ComponentFormattingOption::FullyDecoded );
723 else if ( item.first == QLatin1String(
"authcfg" ) )
724 mAuthConfigId = query.queryItemValue( QStringLiteral(
"authcfg" ), QUrl::ComponentFormattingOption::FullyDecoded );
726 mParams.insert( item.first, item.second );
735 setEncodedUri( url.query( QUrl::EncodeUnicode ).toLatin1() );
740 if ( !mSchema.isEmpty() )
741 return QStringLiteral(
"\"%1\".\"%2\"" )
742 .arg( escape( mSchema,
'"' ),
743 escape( mTable,
'"' ) );
745 return QStringLiteral(
"\"%1\"" )
746 .arg( escape( mTable,
'"' ) );
751 const QString &database,
752 const QString &username,
753 const QString &password,
755 const QString &authConfigId )
767 const QString &database,
768 const QString &username,
769 const QString &password,
771 const QString &authConfigId )
782 const QString &table,
783 const QString &geometryColumn,
785 const QString &keyColumn )
796 mAuthConfigId = authcfg;
826 if (
sslMode == QLatin1String(
"prefer" ) )
828 else if (
sslMode == QLatin1String(
"disable" ) )
830 else if (
sslMode == QLatin1String(
"allow" ) )
832 else if (
sslMode == QLatin1String(
"require" ) )
834 else if (
sslMode == QLatin1String(
"verify-ca" ) )
836 else if (
sslMode == QLatin1String(
"verify-full" ) )
846 case SslPrefer:
return QStringLiteral(
"prefer" );
847 case SslDisable:
return QStringLiteral(
"disable" );
848 case SslAllow:
return QStringLiteral(
"allow" );
849 case SslRequire:
return QStringLiteral(
"require" );
850 case SslVerifyCa:
return QStringLiteral(
"verify-ca" );
859 if ( key == QLatin1String(
"username" ) )
861 else if ( key == QLatin1String(
"password" ) )
863 else if ( key == QLatin1String(
"authcfg" ) )
864 mAuthConfigId = value;
868 mParams.insert( key, value );
874 for (
const QString &val : value )
882 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
887 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
892 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
894 mAuthConfigId.clear();
898 return mParams.remove( key );
904 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
906 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
908 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
909 return mAuthConfigId;
911 return mParams.value( key );
917 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
918 return QStringList() << mUsername;
919 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
920 return QStringList() << mPassword;
921 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
922 return QStringList() << mAuthConfigId;
924 return mParams.values( key );
930 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
932 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
934 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
937 return mParams.contains( key );
942 QSet<QString> paramKeys;
943 for (
auto it = mParams.constBegin(); it != mParams.constEnd(); it++ )
944 paramKeys.insert( it.key() );
946 if ( !mHost.isEmpty() )
947 paramKeys.insert( QLatin1String(
"host" ) );
948 if ( !mPort.isEmpty() )
949 paramKeys.insert( QLatin1String(
"port" ) );
950 if ( !mDriver.isEmpty() )
951 paramKeys.insert( QLatin1String(
"driver" ) );
952 if ( !mService.isEmpty() )
953 paramKeys.insert( QLatin1String(
"service" ) );
954 if ( !mDatabase.isEmpty() )
955 paramKeys.insert( QLatin1String(
"dbname" ) );
956 if ( !mSchema.isEmpty() )
957 paramKeys.insert( QLatin1String(
"schema" ) );
958 if ( !mTable.isEmpty() )
959 paramKeys.insert( QLatin1String(
"table" ) );
961 if ( !mSql.isEmpty() )
962 paramKeys.insert( QLatin1String(
"sql" ) );
963 if ( !mAuthConfigId.isEmpty() )
964 paramKeys.insert( QLatin1String(
"authcfg" ) );
965 if ( !mUsername.isEmpty() )
966 paramKeys.insert( QLatin1String(
"username" ) );
967 if ( !mPassword.isEmpty() )
968 paramKeys.insert( QLatin1String(
"password" ) );
970 paramKeys.insert( QLatin1String(
"sslmode" ) );
971 if ( !mKeyColumn.isEmpty() )
972 paramKeys.insert( QLatin1String(
"key" ) );
973 if ( mUseEstimatedMetadata )
974 paramKeys.insert( QLatin1String(
"estimatedmetadata" ) );
975 if ( mSelectAtIdDisabledSet )
976 paramKeys.insert( QLatin1String(
"selectatid" ) );
978 paramKeys.insert( QLatin1String(
"type" ) );
979 if ( !mSrid.isEmpty() )
980 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)