Quantum GIS API Documentation  1.7.4
src/core/qgsdatasourceuri.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002       qgsdatasourceuri.h  -  Structure to contain the component parts
00003                              of a data source URI
00004                              -------------------
00005     begin                : Dec 5, 2004
00006     copyright            : (C) 2004 by Gary E.Sherman
00007     email                : sherman at mrcc.com
00008  ***************************************************************************/
00009 
00010 /***************************************************************************
00011  *                                                                         *
00012  *   This program is free software; you can redistribute it and/or modify  *
00013  *   it under the terms of the GNU General Public License as published by  *
00014  *   the Free Software Foundation; either version 2 of the License, or     *
00015  *   (at your option) any later version.                                   *
00016  *                                                                         *
00017  ***************************************************************************/
00018 /* $Id: qgsdatasourceuri.h 5839 2006-09-19 18:04:21Z wonder $ */
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   // do nothing
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       // rest of line is a sql where clause
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         mService = pval;
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( ",password=" ) )
00204   {
00205     regexp.setPattern( ",password=.*," );
00206     safeName.replace( regexp, "," );
00207   }
00208   else if ( aUri.contains( "IDB:" ) )
00209   {
00210     regexp.setPattern( " pass=.* " );
00211     safeName.replace( regexp, " " );
00212   }
00213   else if (( aUri.contains( "OCI:" ) )
00214            || ( aUri.contains( "ODBC:" ) ) )
00215   {
00216     regexp.setPattern( "/.*@" );
00217     safeName.replace( regexp, "/@" );
00218   }
00219   else if ( aUri.contains( "SDE:" ) )
00220   {
00221     QStringList strlist = aUri.split( "," );
00222     safeName = strlist[0] + "," + strlist[1] + "," + strlist[2] + "," + strlist[3];
00223   }
00224   return safeName;
00225 }
00226 
00227 QString QgsDataSourceURI::username() const
00228 {
00229   return mUsername;
00230 }
00231 
00232 void QgsDataSourceURI::setUsername( QString username )
00233 {
00234   mUsername = username;
00235 }
00236 
00237 QString QgsDataSourceURI::service() const
00238 {
00239   return mService;
00240 }
00241 
00242 QString QgsDataSourceURI::host() const
00243 {
00244   return mHost;
00245 }
00246 
00247 QString QgsDataSourceURI::database() const
00248 {
00249   return mDatabase;
00250 }
00251 
00252 QString QgsDataSourceURI::password() const
00253 {
00254   return mPassword;
00255 }
00256 
00257 void QgsDataSourceURI::setPassword( QString password )
00258 {
00259   mPassword = password;
00260 }
00261 
00262 QString QgsDataSourceURI::port() const
00263 {
00264   return mPort;
00265 }
00266 
00267 QgsDataSourceURI::SSLmode QgsDataSourceURI::sslMode() const
00268 {
00269   return mSSLmode;
00270 }
00271 
00272 QString QgsDataSourceURI::schema() const
00273 {
00274   return mSchema;
00275 }
00276 
00277 QString QgsDataSourceURI::table() const
00278 {
00279   return mTable;
00280 }
00281 
00282 QString QgsDataSourceURI::sql() const
00283 {
00284   return mSql;
00285 }
00286 
00287 QString QgsDataSourceURI::geometryColumn() const
00288 {
00289   return mGeometryColumn;
00290 }
00291 
00292 QString QgsDataSourceURI::keyColumn() const
00293 {
00294   return mKeyColumn;
00295 }
00296 
00297 void QgsDataSourceURI::setKeyColumn( QString column )
00298 {
00299   mKeyColumn = column;
00300 }
00301 
00302 
00303 void QgsDataSourceURI::setUseEstimatedMetadata( bool theFlag )
00304 {
00305   mUseEstimatedMetadata = theFlag;
00306 }
00307 
00308 bool QgsDataSourceURI::useEstimatedMetadata() const
00309 {
00310   return mUseEstimatedMetadata;
00311 }
00312 
00313 void QgsDataSourceURI::setSql( QString sql )
00314 {
00315   mSql = sql;
00316 }
00317 
00318 void QgsDataSourceURI::clearSchema()
00319 {
00320   mSchema = "";
00321 }
00322 
00323 QString QgsDataSourceURI::escape( const QString &theVal, QChar delim = '\'' ) const
00324 {
00325   QString val = theVal;
00326 
00327   val.replace( "\\", "\\\\" );
00328   val.replace( delim, QString( "\\%1" ).arg( delim ) );
00329 
00330   return val;
00331 }
00332 
00333 void QgsDataSourceURI::skipBlanks( const QString &uri, int &i )
00334 {
00335   // skip space before value
00336   while ( i < uri.length() && uri[i].isSpace() )
00337     i++;
00338 }
00339 
00340 QString QgsDataSourceURI::getValue( const QString &uri, int &i )
00341 {
00342   skipBlanks( uri, i );
00343 
00344   // Get the parameter value
00345   QString pval;
00346   if ( uri[i] == '\'' || uri[i] == '"' )
00347   {
00348     QChar delim = uri[i];
00349 
00350     i++;
00351 
00352     // value is quoted
00353     for ( ;; )
00354     {
00355       if ( i == uri.length() )
00356       {
00357         QgsDebugMsg( "unterminated quoted string in connection info string" );
00358         return pval;
00359       }
00360 
00361       if ( uri[i] == '\\' )
00362       {
00363         i++;
00364         if ( i == uri.length() )
00365           continue;
00366         if ( uri[i] != delim && uri[i] != '\\' )
00367           i--;
00368       }
00369       else if ( uri[i] == delim )
00370       {
00371         i++;
00372         break;
00373       }
00374 
00375       pval += uri[i++];
00376     }
00377   }
00378   else
00379   {
00380     // value is not quoted
00381     while ( i < uri.length() )
00382     {
00383       if ( uri[i].isSpace() )
00384       {
00385         // end of value
00386         break;
00387       }
00388 
00389       if ( uri[i] == '\\' )
00390       {
00391         i++;
00392         if ( i == uri.length() )
00393           break;
00394         if ( uri[i] != '\\' && uri[i] != '\'' )
00395           i--;
00396       }
00397 
00398       pval += uri[i++];
00399     }
00400   }
00401 
00402   skipBlanks( uri, i );
00403 
00404   return pval;
00405 }
00406 
00407 QString QgsDataSourceURI::connectionInfo() const
00408 {
00409   QStringList connectionItems;
00410 
00411   if ( mDatabase != "" )
00412   {
00413     connectionItems << "dbname='" + escape( mDatabase ) + "'";
00414   }
00415 
00416   if ( mService != "" )
00417   {
00418     connectionItems << "service='" + escape( mService ) + "'";
00419   }
00420   else if ( mHost != "" )
00421   {
00422     connectionItems << "host=" + mHost;
00423     if ( mPort != "" )
00424       connectionItems << "port=" + mPort;
00425   }
00426 
00427   if ( mUsername != "" )
00428   {
00429     connectionItems << "user='" + escape( mUsername ) + "'";
00430 
00431     if ( mPassword != "" )
00432     {
00433       connectionItems << "password='" + escape( mPassword ) + "'";
00434     }
00435   }
00436 
00437   if ( mSSLmode == SSLdisable )
00438     connectionItems << "sslmode=disable";
00439   else if ( mSSLmode == SSLallow )
00440     connectionItems << "sslmode=allow";
00441   else if ( mSSLmode == SSLrequire )
00442     connectionItems << "sslmode=require";
00443 #if 0
00444   else if ( mSSLmode == SSLprefer )
00445     connectionItems << "sslmode=prefer";
00446 #endif
00447 
00448   return connectionItems.join( " " );
00449 }
00450 
00451 QString QgsDataSourceURI::uri() const
00452 {
00453   QString theUri = connectionInfo();
00454 
00455   if ( !mKeyColumn.isEmpty() )
00456   {
00457     theUri += QString( " key='%1'" ).arg( escape( mKeyColumn ) );
00458   }
00459 
00460   if ( mUseEstimatedMetadata )
00461   {
00462     theUri += QString( " estimatedmetadata=true" );
00463   }
00464 
00465   theUri += QString( " table=%1%2 sql=%3" )
00466             .arg( quotedTablename() )
00467             .arg( mGeometryColumn.isNull() ? QString() : QString( " (%1)" ).arg( mGeometryColumn ) )
00468             .arg( mSql );
00469 
00470   return theUri;
00471 }
00472 
00473 QString QgsDataSourceURI::quotedTablename() const
00474 {
00475   if ( !mSchema.isEmpty() )
00476     return QString( "\"%1\".\"%2\"" )
00477            .arg( escape( mSchema, '"' ) )
00478            .arg( escape( mTable, '"' ) );
00479   else
00480     return QString( "\"%1\"" )
00481            .arg( escape( mTable, '"' ) );
00482 }
00483 
00484 void QgsDataSourceURI::setConnection( const QString &host,
00485                                       const QString &port,
00486                                       const QString &database,
00487                                       const QString &username,
00488                                       const QString &password,
00489                                       SSLmode sslmode )
00490 {
00491   mHost = host;
00492   mDatabase = database;
00493   mPort = port;
00494   mUsername = username;
00495   mPassword = password;
00496   mSSLmode = sslmode;
00497 }
00498 
00499 void QgsDataSourceURI::setConnection( const QString &service,
00500                                       const QString &database,
00501                                       const QString &username,
00502                                       const QString &password,
00503                                       SSLmode sslmode )
00504 {
00505   mService = service;
00506   mDatabase = database;
00507   mUsername = username;
00508   mPassword = password;
00509   mSSLmode = sslmode;
00510 }
00511 
00512 void QgsDataSourceURI::setDataSource( const QString &schema,
00513                                       const QString &table,
00514                                       const QString &geometryColumn,
00515                                       const QString &sql,
00516                                       const QString &keyColumn )
00517 {
00518   mSchema = schema;
00519   mTable = table;
00520   mGeometryColumn = geometryColumn;
00521   mSql = sql;
00522   mKeyColumn = keyColumn;
00523 }
00524 
00525 void QgsDataSourceURI::setDatabase( const QString &database )
00526 {
00527   mDatabase = database;
00528 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines