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;
407 return mGeometryColumn;
430 mUseEstimatedMetadata = flag;
435 return mUseEstimatedMetadata;
440 mSelectAtIdDisabledSet =
true;
441 mSelectAtIdDisabled = flag;
446 return mSelectAtIdDisabled;
469QString QgsDataSourceUri::escape(
const QString &val, QChar delim =
'\'' )
const
471 QString escaped = val;
473 escaped.replace(
'\\', QLatin1String(
"\\\\" ) );
474 escaped.replace( delim, QStringLiteral(
"\\%1" ).arg( delim ) );
489void QgsDataSourceUri::skipBlanks(
const QString &uri,
int &i )
492 while ( i <
uri.length() &&
uri[i].isSpace() )
496QString QgsDataSourceUri::getValue(
const QString &uri,
int &i )
498 skipBlanks(
uri, i );
502 if ( i <
uri.length() && (
uri[i] ==
'\'' ||
uri[i] ==
'"' ) )
504 const QChar delim =
uri[i];
511 if ( i ==
uri.length() )
513 QgsDebugError( QStringLiteral(
"unterminated quoted string in connection info string" ) );
517 if (
uri[i] ==
'\\' )
520 if ( i ==
uri.length() )
522 if (
uri[i] != delim &&
uri[i] !=
'\\' )
525 else if (
uri[i] == delim )
537 while ( i <
uri.length() )
539 if (
uri[i].isSpace() )
545 if (
uri[i] ==
'\\' )
548 if ( i ==
uri.length() )
550 if (
uri[i] !=
'\\' &&
uri[i] !=
'\'' )
558 skipBlanks(
uri, i );
565 QStringList connectionItems;
567 if ( !mDatabase.isEmpty() )
569 connectionItems <<
"dbname='" + escape( mDatabase ) +
'\'';
572 if ( !mService.isEmpty() )
574 connectionItems <<
"service='" + escape( mService ) +
'\'';
576 else if ( !mHost.isEmpty() )
578 connectionItems <<
"host=" + mHost;
581 if ( mService.isEmpty() )
583 if ( !mPort.isEmpty() )
584 connectionItems <<
"port=" + mPort;
587 if ( !mDriver.isEmpty() )
589 connectionItems <<
"driver='" + escape( mDriver ) +
'\'';
592 if ( !mUsername.isEmpty() )
594 connectionItems <<
"user='" + escape( mUsername ) +
'\'';
596 if ( !mPassword.isEmpty() )
598 connectionItems <<
"password='" + escape( mPassword ) +
'\'';
604 connectionItems << QStringLiteral(
"sslmode=" ) +
encodeSslMode( mSSLmode );
607 if ( !mAuthConfigId.isEmpty() )
609 if ( expandAuthConfig )
613 QgsDebugError( QStringLiteral(
"Data source URI FAILED to update via loading configuration ID '%1'" ).arg( mAuthConfigId ) );
618 connectionItems <<
"authcfg=" + mAuthConfigId;
622 return connectionItems.join( QLatin1Char(
' ' ) );
629 if ( !mKeyColumn.isEmpty() )
631 uri += QStringLiteral(
" key='%1'" ).arg( escape( mKeyColumn ) );
634 if ( mUseEstimatedMetadata )
636 uri += QLatin1String(
" estimatedmetadata=true" );
639 if ( !mSrid.isEmpty() )
641 uri += QStringLiteral(
" srid=%1" ).arg( mSrid );
646 uri += QLatin1String(
" type=" );
650 if ( mSelectAtIdDisabled )
652 uri += QLatin1String(
" selectatid=false" );
655 for (
auto it = mParams.constBegin(); it != mParams.constEnd(); ++it )
657 if ( it.key().contains(
'=' ) || it.key().contains(
' ' ) )
659 QgsDebugError( QStringLiteral(
"invalid uri parameter %1 skipped" ).arg( it.key() ) );
663 uri +=
' ' + it.key() +
"='" + escape( it.value() ) +
'\'';
668 QString columnName( mGeometryColumn );
669 columnName.replace(
'\\', QLatin1String(
"\\\\" ) );
670 columnName.replace(
')', QLatin1String(
"\\)" ) );
672 if ( !mTable.isEmpty() )
674 uri += QStringLiteral(
" table=%1%2" )
676 mGeometryColumn.isEmpty() ? QString() : QStringLiteral(
" (%1)" ).arg( columnName ) );
678 else if ( !mSchema.isEmpty() )
680 uri += QStringLiteral(
" schema='%1'" ).arg( escape( mSchema ) );
683 if ( !mSql.isEmpty() )
685 uri += QStringLiteral(
" sql=" ) + mSql;
694 if (
string.isEmpty() )
695 return string.isNull() ? QByteArray() : QByteArray(
"" );
696 return string.toLatin1();
702 for (
auto it = mParams.constBegin(); it != mParams.constEnd(); ++it )
704 url.addQueryItem( it.key(), it.value() );
707 if ( !mUsername.isEmpty() )
708 url.addQueryItem( QStringLiteral(
"username" ), mUsername );
710 if ( !mPassword.isEmpty() )
711 url.addQueryItem( QStringLiteral(
"password" ), mPassword );
713 if ( !mAuthConfigId.isEmpty() )
714 url.addQueryItem( QStringLiteral(
"authcfg" ), mAuthConfigId );
726 mAuthConfigId.clear();
729 url.setQuery( QString::fromLatin1(
uri ) );
730 const QUrlQuery query( url );
734 const auto constQueryItems = query.queryItems();
735 for (
const QPair<QString, QString> &item : constQueryItems )
739 if ( item.first == QLatin1String(
"username" ) )
740 mUsername = query.queryItemValue( QStringLiteral(
"username" ), QUrl::ComponentFormattingOption::FullyDecoded );
741 else if ( item.first == QLatin1String(
"password" ) )
742 mPassword = query.queryItemValue( QStringLiteral(
"password" ), QUrl::ComponentFormattingOption::FullyDecoded );
743 else if ( item.first == QLatin1String(
"authcfg" ) )
744 mAuthConfigId = query.queryItemValue( QStringLiteral(
"authcfg" ), QUrl::ComponentFormattingOption::FullyDecoded );
746 mParams.insert( item.first, item.second );
755 setEncodedUri( url.query( QUrl::EncodeUnicode ).toLatin1() );
760 if ( !mSchema.isEmpty() )
761 return QStringLiteral(
"\"%1\".\"%2\"" )
762 .arg( escape( mSchema,
'"' ),
763 escape( mTable,
'"' ) );
765 return QStringLiteral(
"\"%1\"" )
766 .arg( escape( mTable,
'"' ) );
771 const QString &database,
772 const QString &username,
773 const QString &password,
775 const QString &authConfigId )
787 const QString &database,
788 const QString &username,
789 const QString &password,
791 const QString &authConfigId )
802 const QString &table,
803 const QString &geometryColumn,
805 const QString &keyColumn )
816 mAuthConfigId = authcfg;
846 if (
sslMode == QLatin1String(
"prefer" ) )
848 else if (
sslMode == QLatin1String(
"disable" ) )
850 else if (
sslMode == QLatin1String(
"allow" ) )
852 else if (
sslMode == QLatin1String(
"require" ) )
854 else if (
sslMode == QLatin1String(
"verify-ca" ) )
856 else if (
sslMode == QLatin1String(
"verify-full" ) )
866 case SslPrefer:
return QStringLiteral(
"prefer" );
867 case SslDisable:
return QStringLiteral(
"disable" );
868 case SslAllow:
return QStringLiteral(
"allow" );
869 case SslRequire:
return QStringLiteral(
"require" );
870 case SslVerifyCa:
return QStringLiteral(
"verify-ca" );
879 if ( key == QLatin1String(
"username" ) )
881 else if ( key == QLatin1String(
"password" ) )
883 else if ( key == QLatin1String(
"authcfg" ) )
884 mAuthConfigId = value;
888 mParams.insert( key, value );
894 for (
const QString &val : value )
902 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
907 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
912 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
914 mAuthConfigId.clear();
918 return mParams.remove( key );
924 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
926 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
928 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
929 return mAuthConfigId;
931 return mParams.value( key );
937 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
938 return QStringList() << mUsername;
939 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
940 return QStringList() << mPassword;
941 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
942 return QStringList() << mAuthConfigId;
944 return mParams.values( key );
950 if ( key == QLatin1String(
"username" ) && !mUsername.isEmpty() )
952 else if ( key == QLatin1String(
"password" ) && !mPassword.isEmpty() )
954 else if ( key == QLatin1String(
"authcfg" ) && !mAuthConfigId.isEmpty() )
957 return mParams.contains( key );
962 QSet<QString> paramKeys;
963 for (
auto it = mParams.constBegin(); it != mParams.constEnd(); it++ )
964 paramKeys.insert( it.key() );
966 if ( !mHost.isEmpty() )
967 paramKeys.insert( QLatin1String(
"host" ) );
968 if ( !mPort.isEmpty() )
969 paramKeys.insert( QLatin1String(
"port" ) );
970 if ( !mDriver.isEmpty() )
971 paramKeys.insert( QLatin1String(
"driver" ) );
972 if ( !mService.isEmpty() )
973 paramKeys.insert( QLatin1String(
"service" ) );
974 if ( !mDatabase.isEmpty() )
975 paramKeys.insert( QLatin1String(
"dbname" ) );
976 if ( !mSchema.isEmpty() )
977 paramKeys.insert( QLatin1String(
"schema" ) );
978 if ( !mTable.isEmpty() )
979 paramKeys.insert( QLatin1String(
"table" ) );
981 if ( !mSql.isEmpty() )
982 paramKeys.insert( QLatin1String(
"sql" ) );
983 if ( !mAuthConfigId.isEmpty() )
984 paramKeys.insert( QLatin1String(
"authcfg" ) );
985 if ( !mUsername.isEmpty() )
986 paramKeys.insert( QLatin1String(
"username" ) );
987 if ( !mPassword.isEmpty() )
988 paramKeys.insert( QLatin1String(
"password" ) );
990 paramKeys.insert( QLatin1String(
"sslmode" ) );
991 if ( !mKeyColumn.isEmpty() )
992 paramKeys.insert( QLatin1String(
"key" ) );
993 if ( mUseEstimatedMetadata )
994 paramKeys.insert( QLatin1String(
"estimatedmetadata" ) );
995 if ( mSelectAtIdDisabledSet )
996 paramKeys.insert( QLatin1String(
"selectatid" ) );
998 paramKeys.insert( QLatin1String(
"type" ) );
999 if ( !mSrid.isEmpty() )
1000 paramKeys.insert( QLatin1String(
"srid" ) );
1007 if ( mUseEstimatedMetadata != other.mUseEstimatedMetadata ||
1008 mSelectAtIdDisabled != other.mSelectAtIdDisabled ||
1009 mSelectAtIdDisabledSet != other.mSelectAtIdDisabledSet ||
1010 mSSLmode != other.mSSLmode ||
1011 mWkbType != other.mWkbType )
1016 if ( mHost != other.mHost ||
1017 mPort != other.mPort ||
1018 mDriver != other.mDriver ||
1019 mService != other.mService ||
1020 mDatabase != other.mDatabase ||
1021 mSchema != other.mSchema ||
1022 mTable != other.mTable ||
1023 mGeometryColumn != other.mGeometryColumn ||
1024 mSql != other.mSql ||
1025 mAuthConfigId != other.mAuthConfigId ||
1026 mUsername != other.mUsername ||
1027 mPassword != other.mPassword ||
1028 mKeyColumn != other.mKeyColumn ||
1029 mSrid != other.mSrid ||
1030 mParams != other.mParams ||
1031 mHttpHeaders != other.mHttpHeaders )
1041 return !( *
this == other );
WkbType
The WKB type describes the number of dimensions a geometry has.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
Class for storing the component parts of a RDBMS data source URI (e.g.
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 setHost(const QString &host)
Sets the host name stored in the URI.
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.
void setService(const QString &service)
Sets the service name associated with 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 setSslMode(SslMode mode)
Sets the SSL mode 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 setPort(const QString &port)
Sets the port stored in the URI.
bool operator==(const QgsDataSourceUri &other) const
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.
bool operator!=(const QgsDataSourceUri &other) const
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)