QGIS API Documentation  2.14.11-Essen
qgsdatasourceuri.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdatasourceuri.h - Structure to contain the component parts
3  of a data source URI
4  -------------------
5  begin : Dec 5, 2004
6  copyright : (C) 2004 by Gary E.Sherman
7  email : sherman at mrcc.com
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 #include "qgsdatasourceuri.h"
20 #include "qgsauthmanager.h"
21 #include "qgslogger.h"
22 #include "qgswkbtypes.h"
23 
24 #include <QStringList>
25 #include <QRegExp>
26 #include <QUrl>
27 
29  : mSSLmode( SSLprefer )
30  , mKeyColumn( "" )
31  , mUseEstimatedMetadata( false )
32  , mSelectAtIdDisabled( false )
33  , mWkbType( QgsWKBTypes::Unknown )
34 {
35  // do nothing
36 }
37 
39  : mSSLmode( SSLprefer )
40  , mKeyColumn( "" )
41  , mUseEstimatedMetadata( false )
42  , mSelectAtIdDisabled( false )
43  , mWkbType( QgsWKBTypes::Unknown )
44 {
45  int i = 0;
46  while ( i < uri.length() )
47  {
48  skipBlanks( uri, i );
49 
50  if ( uri[i] == '=' )
51  {
52  QgsDebugMsg( "parameter name expected before =" );
53  i++;
54  continue;
55  }
56 
57  int start = i;
58 
59  while ( i < uri.length() && uri[i] != '=' && !uri[i].isSpace() )
60  i++;
61 
62  QString pname = uri.mid( start, i - start );
63 
64  skipBlanks( uri, i );
65 
66  if ( i == uri.length() || uri[i] != '=' )
67  {
68  QgsDebugMsg( QString( "= expected after parameter name, skipping text '%1'" ).arg( pname ) );
69  continue;
70  }
71 
72  i++;
73 
74  if ( pname == "sql" )
75  {
76  // rest of line is a sql where clause
77  skipBlanks( uri, i );
78  mSql = uri.mid( i );
79  break;
80  }
81  else
82  {
83  QString pval = getValue( uri, i );
84 
85  if ( pname == "table" )
86  {
87  if ( uri[i] == '.' )
88  {
89  i++;
90 
91  mSchema = pval;
92  mTable = getValue( uri, i );
93  }
94  else
95  {
96  mSchema = "";
97  mTable = pval;
98  }
99 
100  if ( uri[i] == '(' )
101  {
102  i++;
103 
104  int start = i;
105  while ( i < uri.length() && uri[i] != ')' )
106  {
107  if ( uri[i] == '\\' )
108  i++;
109  i++;
110  }
111 
112  if ( i == uri.length() )
113  {
114  QgsDebugMsg( "closing parenthesis missing" );
115  }
116 
117  mGeometryColumn = uri.mid( start, i - start );
118  mGeometryColumn.replace( "\\)", ")" );
119  mGeometryColumn.replace( "\\\\", "\\" );
120 
121  i++;
122  }
123  else
124  {
125  mGeometryColumn = QString::null;
126  }
127  }
128  else if ( pname == "key" )
129  {
130  mKeyColumn = pval;
131  }
132  else if ( pname == "estimatedmetadata" )
133  {
134  mUseEstimatedMetadata = pval == "true";
135  }
136  else if ( pname == "srid" )
137  {
138  mSrid = pval;
139  }
140  else if ( pname == "type" )
141  {
142  mWkbType = QgsWKBTypes::parseType( pval );
143  }
144  else if ( pname == "selectatid" )
145  {
146  mSelectAtIdDisabled = pval == "false";
147  }
148  else if ( pname == "service" )
149  {
150  mService = pval;
151  }
152  else if ( pname == "authcfg" )
153  {
154  mAuthConfigId = pval;
155  }
156  else if ( pname == "user" )
157  {
158  mUsername = pval;
159  }
160  else if ( pname == "password" )
161  {
162  mPassword = pval;
163  }
164  else if ( pname == "connect_timeout" )
165  {
166  QgsDebugMsg( "connection timeout ignored" );
167  }
168  else if ( pname == "dbname" )
169  {
170  mDatabase = pval;
171  }
172  else if ( pname == "host" )
173  {
174  mHost = pval;
175  }
176  else if ( pname == "hostaddr" )
177  {
178  QgsDebugMsg( "database host ip address ignored" );
179  }
180  else if ( pname == "port" )
181  {
182  mPort = pval;
183  }
184  else if ( pname == "tty" )
185  {
186  QgsDebugMsg( "backend debug tty ignored" );
187  }
188  else if ( pname == "options" )
189  {
190  QgsDebugMsg( "backend debug options ignored" );
191  }
192  else if ( pname == "sslmode" )
193  {
194  if ( pval == "disable" )
195  mSSLmode = SSLdisable;
196  else if ( pval == "allow" )
197  mSSLmode = SSLallow;
198  else if ( pval == "prefer" )
199  mSSLmode = SSLprefer;
200  else if ( pval == "require" )
201  mSSLmode = SSLrequire;
202  }
203  else if ( pname == "requiressl" )
204  {
205  if ( pval == "0" )
206  mSSLmode = SSLdisable;
207  else
208  mSSLmode = SSLprefer;
209  }
210  else if ( pname == "krbsrvname" )
211  {
212  QgsDebugMsg( "kerberos server name ignored" );
213  }
214  else if ( pname == "gsslib" )
215  {
216  QgsDebugMsg( "gsslib ignored" );
217  }
218  else
219  {
220  QgsDebugMsg( "parameter \"" + pname + "\":\"" + pval + "\" added" );
221  setParam( pname, pval );
222  }
223  }
224  }
225 }
226 
228 {
229  QRegExp regexp;
230  regexp.setMinimal( true );
231  QString safeName( aUri );
232  if ( aUri.contains( " password=" ) )
233  {
234  regexp.setPattern( " password=.* " );
235  safeName.replace( regexp, " " );
236  }
237  else if ( aUri.contains( ",password=" ) )
238  {
239  regexp.setPattern( ",password=.*," );
240  safeName.replace( regexp, "," );
241  }
242  else if ( aUri.contains( "IDB:" ) )
243  {
244  regexp.setPattern( " pass=.* " );
245  safeName.replace( regexp, " " );
246  }
247  else if (( aUri.contains( "OCI:" ) )
248  || ( aUri.contains( "ODBC:" ) ) )
249  {
250  regexp.setPattern( "/.*@" );
251  safeName.replace( regexp, "/@" );
252  }
253  else if ( aUri.contains( "SDE:" ) )
254  {
255  QStringList strlist = aUri.split( ',' );
256  safeName = strlist[0] + ',' + strlist[1] + ',' + strlist[2] + ',' + strlist[3];
257  }
258  return safeName;
259 }
260 
262 {
263  return mAuthConfigId;
264 }
265 
267 {
268  return mUsername;
269 }
270 
272 {
273  mUsername = username;
274 }
275 
277 {
278  return mService;
279 }
280 
282 {
283  return mHost;
284 }
285 
287 {
288  return mDatabase;
289 }
290 
292 {
293  return mPassword;
294 }
295 
297 {
298  mPassword = password;
299 }
300 
302 {
303  return mPort;
304 }
305 
307 {
308  return mSSLmode;
309 }
310 
312 {
313  return mSchema;
314 }
315 
317 {
318  return mTable;
319 }
320 
322 {
323  return mSql;
324 }
325 
327 {
328  return mGeometryColumn;
329 }
330 
332 {
333  return mKeyColumn;
334 }
335 
337 {
338  mKeyColumn = column;
339 }
340 
341 
343 {
344  mUseEstimatedMetadata = theFlag;
345 }
346 
348 {
349  return mUseEstimatedMetadata;
350 }
351 
353 {
354  mSelectAtIdDisabled = theFlag;
355 }
356 
358 {
359  return mSelectAtIdDisabled;
360 }
361 
363 {
364  mSql = sql;
365 }
366 
368 {
369  mSchema = "";
370 }
371 
373 {
374  mSchema = schema;
375 }
376 
377 QString QgsDataSourceURI::escape( const QString &theVal, QChar delim = '\'' ) const
378 {
379  QString val = theVal;
380 
381  val.replace( '\\', "\\\\" );
382  val.replace( delim, QString( "\\%1" ).arg( delim ) );
383 
384  return val;
385 }
386 
387 void QgsDataSourceURI::skipBlanks( const QString &uri, int &i )
388 {
389  // skip space before value
390  while ( i < uri.length() && uri[i].isSpace() )
391  i++;
392 }
393 
394 QString QgsDataSourceURI::getValue( const QString &uri, int &i )
395 {
396  skipBlanks( uri, i );
397 
398  // Get the parameter value
399  QString pval;
400  if ( i < uri.length() && ( uri[i] == '\'' || uri[i] == '"' ) )
401  {
402  QChar delim = uri[i];
403 
404  i++;
405 
406  // value is quoted
407  for ( ;; )
408  {
409  if ( i == uri.length() )
410  {
411  QgsDebugMsg( "unterminated quoted string in connection info string" );
412  return pval;
413  }
414 
415  if ( uri[i] == '\\' )
416  {
417  i++;
418  if ( i == uri.length() )
419  continue;
420  if ( uri[i] != delim && uri[i] != '\\' )
421  i--;
422  }
423  else if ( uri[i] == delim )
424  {
425  i++;
426  break;
427  }
428 
429  pval += uri[i++];
430  }
431  }
432  else
433  {
434  // value is not quoted
435  while ( i < uri.length() )
436  {
437  if ( uri[i].isSpace() )
438  {
439  // end of value
440  break;
441  }
442 
443  if ( uri[i] == '\\' )
444  {
445  i++;
446  if ( i == uri.length() )
447  break;
448  if ( uri[i] != '\\' && uri[i] != '\'' )
449  i--;
450  }
451 
452  pval += uri[i++];
453  }
454  }
455 
456  skipBlanks( uri, i );
457 
458  return pval;
459 }
460 
461 QString QgsDataSourceURI::connectionInfo( bool expandAuthConfig ) const
462 {
463  QStringList connectionItems;
464 
465  if ( mDatabase != "" )
466  {
467  connectionItems << "dbname='" + escape( mDatabase ) + '\'';
468  }
469 
470  if ( mService != "" )
471  {
472  connectionItems << "service='" + escape( mService ) + '\'';
473  }
474  else if ( mHost != "" )
475  {
476  connectionItems << "host=" + mHost;
477  }
478 
479  if ( mService.isEmpty() )
480  {
481  if ( mPort != "" )
482  connectionItems << "port=" + mPort;
483  }
484 
485  if ( mUsername != "" )
486  {
487  connectionItems << "user='" + escape( mUsername ) + '\'';
488 
489  if ( mPassword != "" )
490  {
491  connectionItems << "password='" + escape( mPassword ) + '\'';
492  }
493  }
494 
495  if ( mSSLmode == SSLdisable )
496  connectionItems << "sslmode=disable";
497  else if ( mSSLmode == SSLallow )
498  connectionItems << "sslmode=allow";
499  else if ( mSSLmode == SSLrequire )
500  connectionItems << "sslmode=require";
501 #if 0
502  else if ( mSSLmode == SSLprefer )
503  connectionItems << "sslmode=prefer";
504 #endif
505 
506  if ( !mAuthConfigId.isEmpty() )
507  {
508  if ( expandAuthConfig )
509  {
510  if ( !QgsAuthManager::instance()->updateDataSourceUriItems( connectionItems, mAuthConfigId ) )
511  {
512  QgsDebugMsg( QString( "Data source URI FAILED to update via loading configuration ID '%1'" ).arg( mAuthConfigId ) );
513  }
514  }
515  else
516  {
517  connectionItems << "authcfg=" + mAuthConfigId;
518  }
519  }
520 
521  return connectionItems.join( " " );
522 }
523 
524 QString QgsDataSourceURI::uri( bool expandAuthConfig ) const
525 {
526  QString theUri = connectionInfo( expandAuthConfig );
527 
528  if ( !mKeyColumn.isEmpty() )
529  {
530  theUri += QString( " key='%1'" ).arg( escape( mKeyColumn ) );
531  }
532 
533  if ( mUseEstimatedMetadata )
534  {
535  theUri += QString( " estimatedmetadata=true" );
536  }
537 
538  if ( !mSrid.isEmpty() )
539  {
540  theUri += QString( " srid=%1" ).arg( mSrid );
541  }
542 
543  if ( mWkbType != QgsWKBTypes::Unknown && mWkbType != QgsWKBTypes::NoGeometry )
544  {
545  theUri += " type=";
546  theUri += QgsWKBTypes::displayString( mWkbType );
547  }
548 
549  if ( mSelectAtIdDisabled )
550  {
551  theUri += QString( " selectatid=false" );
552  }
553 
554  for ( QMap<QString, QString>::const_iterator it = mParams.begin(); it != mParams.end(); ++it )
555  {
556  if ( it.key().contains( '=' ) || it.key().contains( ' ' ) )
557  {
558  QgsDebugMsg( QString( "invalid uri parameter %1 skipped" ).arg( it.key() ) );
559  continue;
560  }
561 
562  theUri += ' ' + it.key() + "='" + escape( it.value() ) + '\'';
563  }
564 
565  QString columnName( mGeometryColumn );
566  columnName.replace( '\\', "\\\\" );
567  columnName.replace( ')', "\\)" );
568 
569  theUri += QString( " table=%1%2 sql=%3" )
570  .arg( quotedTablename(),
571  mGeometryColumn.isNull() ? QString() : QString( " (%1)" ).arg( columnName ),
572  mSql );
573 
574  return theUri;
575 }
576 
578 {
579  QUrl url;
580  Q_FOREACH ( const QString& key, mParams.uniqueKeys() )
581  {
582  Q_FOREACH ( const QString& value, mParams.values( key ) )
583  {
584  url.addQueryItem( key, value );
585  }
586  }
587  return url.encodedQuery();
588 }
589 
591 {
592  mParams.clear();
593  QUrl url;
594  url.setEncodedQuery( uri );
596  Q_FOREACH ( item, url.queryItems() )
597  {
598  mParams.insertMulti( item.first, item.second );
599  }
600 }
601 
603 {
604  setEncodedUri( uri.toAscii() );
605 }
606 
608 {
609  if ( !mSchema.isEmpty() )
610  return QString( "\"%1\".\"%2\"" )
611  .arg( escape( mSchema, '"' ),
612  escape( mTable, '"' ) );
613  else
614  return QString( "\"%1\"" )
615  .arg( escape( mTable, '"' ) );
616 }
617 
619  const QString &port,
620  const QString &database,
621  const QString &username,
622  const QString &password,
623  SSLmode sslmode,
624  const QString &authConfigId )
625 {
626  mHost = host;
627  mDatabase = database;
628  mPort = port;
629  mUsername = username;
630  mPassword = password;
631  mSSLmode = sslmode;
632  mAuthConfigId = authConfigId;
633 }
634 
636  const QString &database,
637  const QString &username,
638  const QString &password,
639  SSLmode sslmode,
640  const QString &authConfigId )
641 {
642  mService = service;
643  mDatabase = database;
644  mUsername = username;
645  mPassword = password;
646  mSSLmode = sslmode;
647  mAuthConfigId = authConfigId;
648 }
649 
651  const QString &table,
652  const QString &geometryColumn,
653  const QString &sql,
654  const QString &keyColumn )
655 {
656  mSchema = schema;
657  mTable = table;
658  mGeometryColumn = geometryColumn;
659  mSql = sql;
660  mKeyColumn = keyColumn;
661 }
662 
664 {
665  mAuthConfigId = authcfg;
666 }
667 
669 {
670  mDatabase = database;
671 }
672 
674 {
675  return QGis::fromNewWkbType( mWkbType );
676 }
677 
679 {
680  return mWkbType;
681 }
682 
684 {
685  mWkbType = QGis::fromOldWkbType( wkbType );
686 }
687 
689 {
690  mWkbType = wkbType;
691 }
692 
694 {
695  return mSrid;
696 }
697 
699 {
700  mSrid = srid;
701 }
702 
703 void QgsDataSourceURI::setParam( const QString &key, const QString &value )
704 {
705  // may be multiple
706  mParams.insertMulti( key, value );
707 }
708 
709 void QgsDataSourceURI::setParam( const QString &key, const QStringList &value )
710 {
711  Q_FOREACH ( const QString& val, value )
712  {
713  mParams.insertMulti( key, val );
714  }
715 }
716 
718 {
719  return mParams.remove( key );
720 }
721 
723 {
724  return mParams.value( key );
725 }
726 
728 {
729  return mParams.values( key );
730 }
731 
732 bool QgsDataSourceURI::hasParam( const QString &key ) const
733 {
734  return mParams.contains( key );
735 }
bool selectAtIdDisabled() const
Returns whether the selection by id is disabled.
QgsDataSourceURI()
default constructor
bool contains(const Key &key) const
int removeParam(const QString &key)
Remove generic param (generic mode)
static QgsAuthManager * instance()
Enforce singleton pattern.
QList< T > values() const
void setMinimal(bool minimal)
void setEncodedUri(const QByteArray &uri)
set complete encoded uri (generic mode)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QString param(const QString &key) const
Get generic param (generic mode)
static QString removePassword(const QString &aUri)
Removes password element from uris.
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QList< QPair< QString, QString > > queryItems() const
void setDatabase(const QString &database)
Set database.
static QGis::WkbType fromNewWkbType(QgsWKBTypes::Type type)
Converts from new (post 2.10) WKB type (OGC) to old WKB type.
Definition: qgis.cpp:144
void setSrid(const QString &srid)
Sets the srid.
enum SSLmode sslMode() const
Returns the SSL mode.
WkbType
Used for symbology operations.
Definition: qgis.h:57
QString join(const QString &separator) const
void clear()
void setSql(const QString &sql)
Sets the SQL query.
QString keyColumn() const
Returns the name of the (primary) key column.
bool isNull() const
void setKeyColumn(const QString &column)
Sets the name of the (primary) key column.
QString port() const
Returns the port.
void setPattern(const QString &pattern)
static QgsWKBTypes::Type fromOldWkbType(QGis::WkbType type)
Converts from old (pre 2.10) WKB type (OGR) to new WKB type.
Definition: qgis.cpp:104
QString password() const
Returns the password.
Q_DECL_DEPRECATED QGis::WkbType wkbType() const
The (old) wkb type.
iterator insertMulti(const Key &key, const T &value)
void disableSelectAtId(bool theFlag)
Set to true to disable selection by id.
QString geometryColumn() const
Return the name of the geometry column.
QString schema() const
Returns the schema.
bool hasParam(const QString &key) const
Test if param exists (generic mode)
QString database() const
Returns the database.
void setParam(const QString &key, const QString &value)
Set generic param (generic mode)
void setUseEstimatedMetadata(bool theFlag)
set use Estimated Metadata
QString srid() const
Returns the srid.
void setSchema(const QString &schema)
set the table schema
bool isEmpty() const
QString service() const
Returns the service name.
bool updateDataSourceUriItems(QStringList &connectionItems, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QgsDataSourceURI with an authentication config.
void setConnection(const QString &aHost, const QString &aPort, const QString &aDatabase, const QString &aUsername, const QString &aPassword, SSLmode sslmode=SSLprefer, const QString &authConfigId=QString())
Set all connection related members at once.
QString uri(bool expandAuthConfig=true) const
return complete uri
QString sql() const
Returns the SQL query.
void setAuthConfigId(const QString &authcfg)
Set authentication configuration ID.
iterator end()
QString quotedTablename() const
quoted table name
iterator begin()
bool contains(QChar ch, Qt::CaseSensitivity cs) const
void clearSchema()
Clears the schema.
QString username() const
Returns the username.
QByteArray encodedUri() const
return complete encoded uri (generic mode)
void setUsername(const QString &username)
set username
QString & replace(int position, int n, QChar after)
void setEncodedQuery(const QByteArray &query)
QgsWKBTypes::Type newWkbType() const
The wkb type.
QString mid(int position, int n) const
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:36
Q_DECL_DEPRECATED void setWkbType(QGis::WkbType type)
QString host() const
Returns the host.
QByteArray encodedQuery() const
QString table() const
Returns the table.
int length() const
QString authConfigId() const
Any associated authentication configuration ID.
void addQueryItem(const QString &key, const QString &value)
static Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
Definition: qgswkbtypes.cpp:32
void setPassword(const QString &password)
set password
static QString displayString(Type type)
Returns a display string type for a WKB type, eg the geometry name used in WKT geometry representatio...
Definition: qgswkbtypes.cpp:48
QString connectionInfo(bool expandAuthConfig=true) const
return connection part of URI
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
bool useEstimatedMetadata() const
Returns true if estimated metadata are used.
QStringList params(const QString &key) const
Get multiple generic param (generic mode)
QByteArray toAscii() const
void setDataSource(const QString &aSchema, const QString &aTable, const QString &aGeometryColumn, const QString &aSql=QString(), const QString &aKeyColumn=QString())
Set all data source related members at once.
const T value(const Key &key) const
int remove(const Key &key)
QList< Key > uniqueKeys() const