00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "qgsdatasourceuri.h"
00021 #include "qgslogger.h"
00022
00023 #include <QStringList>
00024 #include <QRegExp>
00025
00026 QgsDataSourceURI::QgsDataSourceURI() : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
00027 {
00028
00029 }
00030
00031 QgsDataSourceURI::QgsDataSourceURI( QString uri ) : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
00032 {
00033 int i = 0;
00034 while ( i < uri.length() )
00035 {
00036 skipBlanks( uri, i );
00037
00038 if ( uri[i] == '=' )
00039 {
00040 QgsDebugMsg( "parameter name expected before =" );
00041 i++;
00042 continue;
00043 }
00044
00045 int start = i;
00046
00047 while ( i < uri.length() && uri[i] != '=' && !uri[i].isSpace() )
00048 i++;
00049
00050 QString pname = uri.mid( start, i - start );
00051
00052 skipBlanks( uri, i );
00053
00054 if ( uri[i] != '=' )
00055 {
00056 QgsDebugMsg( "= expected after parameter name" );
00057 return;
00058 }
00059
00060 i++;
00061
00062 if ( pname == "sql" )
00063 {
00064
00065 skipBlanks( uri, i );
00066 mSql = uri.mid( i );
00067 break;
00068 }
00069 else
00070 {
00071 QString pval = getValue( uri, i );
00072
00073 if ( pname == "table" )
00074 {
00075 if ( uri[i] == '.' )
00076 {
00077 i++;
00078
00079 mSchema = pval;
00080 mTable = getValue( uri, i );
00081 }
00082 else
00083 {
00084 mSchema = "";
00085 mTable = pval;
00086 }
00087
00088 if ( uri[i] == '(' )
00089 {
00090 i++;
00091
00092 int start = i;
00093 QString col;
00094 while ( i < uri.length() && uri[i] != ')' )
00095 i++;
00096
00097 if ( i == uri.length() )
00098 {
00099 QgsDebugMsg( "closing parenthesis missing" );
00100 }
00101
00102 mGeometryColumn = uri.mid( start, i - start );
00103
00104 i++;
00105 }
00106 else
00107 {
00108 mGeometryColumn = QString::null;
00109 }
00110 }
00111 else if ( pname == "key" )
00112 {
00113 mKeyColumn = pval;
00114 }
00115 else if ( pname == "estimatedmetadata" )
00116 {
00117 mUseEstimatedMetadata = pval == "true";
00118 }
00119 else if ( pname == "service" )
00120 {
00121 QgsDebugMsg( "service keyword ignored" );
00122 }
00123 else if ( pname == "user" )
00124 {
00125 mUsername = pval;
00126 }
00127 else if ( pname == "password" )
00128 {
00129 mPassword = pval;
00130 }
00131 else if ( pname == "connect_timeout" )
00132 {
00133 QgsDebugMsg( "connection timeout ignored" );
00134 }
00135 else if ( pname == "dbname" )
00136 {
00137 mDatabase = pval;
00138 }
00139 else if ( pname == "host" )
00140 {
00141 mHost = pval;
00142 }
00143 else if ( pname == "hostaddr" )
00144 {
00145 QgsDebugMsg( "database host ip address ignored" );
00146 }
00147 else if ( pname == "port" )
00148 {
00149 mPort = pval;
00150 }
00151 else if ( pname == "tty" )
00152 {
00153 QgsDebugMsg( "backend debug tty ignored" );
00154 }
00155 else if ( pname == "options" )
00156 {
00157 QgsDebugMsg( "backend debug options ignored" );
00158 }
00159 else if ( pname == "sslmode" )
00160 {
00161 if ( pval == "disable" )
00162 mSSLmode = SSLdisable;
00163 else if ( pval == "allow" )
00164 mSSLmode = SSLallow;
00165 else if ( pval == "prefer" )
00166 mSSLmode = SSLprefer;
00167 else if ( pval == "require" )
00168 mSSLmode = SSLrequire;
00169 }
00170 else if ( pname == "requiressl" )
00171 {
00172 if ( pval == "0" )
00173 mSSLmode = SSLdisable;
00174 else
00175 mSSLmode = SSLprefer;
00176 }
00177 else if ( pname == "krbsrvname" )
00178 {
00179 QgsDebugMsg( "kerberos server name ignored" );
00180 }
00181 else if ( pname == "gsslib" )
00182 {
00183 QgsDebugMsg( "gsslib ignored" );
00184 }
00185 else
00186 {
00187 QgsDebugMsg( "invalid connection option \"" + pname + "\" ignored" );
00188 }
00189 }
00190 }
00191 }
00192
00193 QString QgsDataSourceURI::removePassword( const QString& aUri )
00194 {
00195 QRegExp regexp;
00196 regexp.setMinimal( true );
00197 QString safeName( aUri );
00198 if ( aUri.contains( " password=" ) )
00199 {
00200 regexp.setPattern( " password=.* " );
00201 safeName.replace( regexp, " " );
00202 }
00203 else if ( aUri.contains( "IDB:" ) )
00204 {
00205 regexp.setPattern( " pass=.* " );
00206 safeName.replace( regexp, " " );
00207 }
00208 else if (( aUri.contains( "OCI:" ) )
00209 || ( aUri.contains( "ODBC:" ) ) )
00210 {
00211 regexp.setPattern( "/.*@" );
00212 safeName.replace( regexp, "/@" );
00213 }
00214 else if ( aUri.contains( "SDE:" ) )
00215 {
00216 QStringList strlist = aUri.split( "," );
00217 safeName = strlist[0] + "," + strlist[1] + "," + strlist[2] + "," + strlist[3];
00218 }
00219 return safeName;
00220 }
00221
00222 QString QgsDataSourceURI::username() const
00223 {
00224 return mUsername;
00225 }
00226
00227 void QgsDataSourceURI::setUsername( QString username )
00228 {
00229 mUsername = username;
00230 }
00231
00232 QString QgsDataSourceURI::host() const
00233 {
00234 return mHost;
00235 }
00236
00237 QString QgsDataSourceURI::database() const
00238 {
00239 return mDatabase;
00240 }
00241
00242 QString QgsDataSourceURI::password() const
00243 {
00244 return mPassword;
00245 }
00246
00247 void QgsDataSourceURI::setPassword( QString password )
00248 {
00249 mPassword = password;
00250 }
00251
00252 QString QgsDataSourceURI::port() const
00253 {
00254 return mPort;
00255 }
00256
00257 QgsDataSourceURI::SSLmode QgsDataSourceURI::sslMode() const
00258 {
00259 return mSSLmode;
00260 }
00261
00262 QString QgsDataSourceURI::schema() const
00263 {
00264 return mSchema;
00265 }
00266
00267 QString QgsDataSourceURI::table() const
00268 {
00269 return mTable;
00270 }
00271
00272 QString QgsDataSourceURI::sql() const
00273 {
00274 return mSql;
00275 }
00276
00277 QString QgsDataSourceURI::geometryColumn() const
00278 {
00279 return mGeometryColumn;
00280 }
00281
00282 QString QgsDataSourceURI::keyColumn() const
00283 {
00284 return mKeyColumn;
00285 }
00286
00287 void QgsDataSourceURI::setKeyColumn( QString column )
00288 {
00289 mKeyColumn = column;
00290 }
00291
00292
00293 void QgsDataSourceURI::setUseEstimatedMetadata( bool theFlag )
00294 {
00295 mUseEstimatedMetadata = theFlag;
00296 }
00297
00298 bool QgsDataSourceURI::useEstimatedMetadata() const
00299 {
00300 return mUseEstimatedMetadata;
00301 }
00302
00303 void QgsDataSourceURI::setSql( QString sql )
00304 {
00305 mSql = sql;
00306 }
00307
00308 void QgsDataSourceURI::clearSchema()
00309 {
00310 mSchema = "";
00311 }
00312
00313 QString QgsDataSourceURI::escape( const QString &theVal, QChar delim = '\'' ) const
00314 {
00315 QString val = theVal;
00316
00317 val.replace( "\\", "\\\\" );
00318 val.replace( delim, QString( "\\%1" ).arg( delim ) );
00319
00320 return val;
00321 }
00322
00323 void QgsDataSourceURI::skipBlanks( const QString &uri, int &i )
00324 {
00325
00326 while ( i < uri.length() && uri[i].isSpace() )
00327 i++;
00328 }
00329
00330 QString QgsDataSourceURI::getValue( const QString &uri, int &i )
00331 {
00332 skipBlanks( uri, i );
00333
00334
00335 QString pval;
00336 if ( uri[i] == '\'' || uri[i] == '"' )
00337 {
00338 QChar delim = uri[i];
00339
00340 i++;
00341
00342
00343 for ( ;; )
00344 {
00345 if ( i == uri.length() )
00346 {
00347 QgsDebugMsg( "unterminated quoted string in connection info string" );
00348 return pval;
00349 }
00350
00351 if ( uri[i] == '\\' )
00352 {
00353 i++;
00354 if ( i == uri.length() )
00355 continue;
00356 if ( uri[i] != delim && uri[i] != '\\' )
00357 i--;
00358 }
00359 else if ( uri[i] == delim )
00360 {
00361 i++;
00362 break;
00363 }
00364
00365 pval += uri[i++];
00366 }
00367 }
00368 else
00369 {
00370
00371 while ( i < uri.length() )
00372 {
00373 if ( uri[i].isSpace() )
00374 {
00375
00376 break;
00377 }
00378
00379 if ( uri[i] == '\\' )
00380 {
00381 i++;
00382 if ( i == uri.length() )
00383 break;
00384 if ( uri[i] != '\\' && uri[i] != '\'' )
00385 i--;
00386 }
00387
00388 pval += uri[i++];
00389 }
00390 }
00391
00392 skipBlanks( uri, i );
00393
00394 return pval;
00395 }
00396
00397 QString QgsDataSourceURI::connectionInfo() const
00398 {
00399 QString connectionInfo = "dbname='" + escape( mDatabase ) + "'";
00400
00401 if ( mHost != "" )
00402 {
00403 connectionInfo += " host=" + mHost;
00404 if ( mPort != "" )
00405 connectionInfo += " port=" + mPort;
00406 }
00407
00408 if ( mUsername != "" )
00409 {
00410 connectionInfo += " user='" + escape( mUsername ) + "'";
00411
00412 if ( mPassword != "" )
00413 {
00414 connectionInfo += " password='" + escape( mPassword ) + "'";
00415 }
00416 }
00417
00418 if ( mSSLmode == SSLdisable )
00419 connectionInfo += " sslmode=disable";
00420 else if ( mSSLmode == SSLallow )
00421 connectionInfo += " sslmode=allow";
00422 else if ( mSSLmode == SSLrequire )
00423 connectionInfo += " sslmode=require";
00424 #if 0
00425 else if ( mSSLmode == SSLprefer )
00426 connectionInfo += " sslmode=prefer";
00427 #endif
00428
00429 return connectionInfo;
00430 }
00431
00432 QString QgsDataSourceURI::uri() const
00433 {
00434 QString theUri = connectionInfo();
00435
00436 if ( !mKeyColumn.isEmpty() )
00437 {
00438 theUri += QString( " key='%1'" ).arg( escape( mKeyColumn ) );
00439 }
00440
00441 if ( mUseEstimatedMetadata )
00442 {
00443 theUri += QString( " estimatedmetadata=true" );
00444 }
00445
00446 theUri += QString( " table=%1%2 sql=%3" )
00447 .arg( quotedTablename() )
00448 .arg( mGeometryColumn.isNull() ? QString() : QString( " (%1)" ).arg( mGeometryColumn ) )
00449 .arg( mSql );
00450
00451 return theUri;
00452 }
00453
00454 QString QgsDataSourceURI::quotedTablename() const
00455 {
00456 if ( !mSchema.isEmpty() )
00457 return QString( "\"%1\".\"%2\"" )
00458 .arg( escape( mSchema, '"' ) )
00459 .arg( escape( mTable, '"' ) );
00460 else
00461 return QString( "\"%1\"" )
00462 .arg( escape( mTable, '"' ) );
00463 }
00464
00465 void QgsDataSourceURI::setConnection( const QString &host,
00466 const QString &port,
00467 const QString &database,
00468 const QString &username,
00469 const QString &password,
00470 SSLmode sslmode )
00471 {
00472 mHost = host;
00473 mDatabase = database;
00474 mPort = port;
00475 mUsername = username;
00476 mPassword = password;
00477 mSSLmode = sslmode;
00478 }
00479
00480 void QgsDataSourceURI::setDataSource( const QString &schema,
00481 const QString &table,
00482 const QString &geometryColumn,
00483 const QString &sql,
00484 const QString &keyColumn )
00485 {
00486 mSchema = schema;
00487 mTable = table;
00488 mGeometryColumn = geometryColumn;
00489 mSql = sql;
00490 mKeyColumn = keyColumn;
00491 }
00492
00493 void QgsDataSourceURI::setDatabase( const QString &database )
00494 {
00495 mDatabase = database;
00496 }