Quantum GIS API Documentation  1.8
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 
00019 #include "qgsdatasourceuri.h"
00020 #include "qgslogger.h"
00021 
00022 #include <QStringList>
00023 #include <QRegExp>
00024 
00025 QgsDataSourceURI::QgsDataSourceURI()
00026     : mSSLmode( SSLprefer )
00027     , mKeyColumn( "" )
00028     , mUseEstimatedMetadata( false )
00029     , mSelectAtIdDisabled( false )
00030     , mWkbType( QGis::WKBUnknown )
00031 {
00032   // do nothing
00033 }
00034 
00035 QgsDataSourceURI::QgsDataSourceURI( QString uri )
00036     : mSSLmode( SSLprefer )
00037     , mKeyColumn( "" )
00038     , mUseEstimatedMetadata( false )
00039     , mSelectAtIdDisabled( false )
00040     , mWkbType( QGis::WKBUnknown )
00041 {
00042   int i = 0;
00043   while ( i < uri.length() )
00044   {
00045     skipBlanks( uri, i );
00046 
00047     if ( uri[i] == '=' )
00048     {
00049       QgsDebugMsg( "parameter name expected before =" );
00050       i++;
00051       continue;
00052     }
00053 
00054     int start = i;
00055 
00056     while ( i < uri.length() && uri[i] != '=' && !uri[i].isSpace() )
00057       i++;
00058 
00059     QString pname = uri.mid( start, i - start );
00060 
00061     skipBlanks( uri, i );
00062 
00063     if ( uri[i] != '=' )
00064     {
00065       QgsDebugMsg( "= expected after parameter name" );
00066       return;
00067     }
00068 
00069     i++;
00070 
00071     if ( pname == "sql" )
00072     {
00073       // rest of line is a sql where clause
00074       skipBlanks( uri, i );
00075       mSql = uri.mid( i );
00076       break;
00077     }
00078     else
00079     {
00080       QString pval = getValue( uri, i );
00081 
00082       if ( pname == "table" )
00083       {
00084         if ( uri[i] == '.' )
00085         {
00086           i++;
00087 
00088           mSchema = pval;
00089           mTable = getValue( uri, i );
00090         }
00091         else
00092         {
00093           mSchema = "";
00094           mTable = pval;
00095         }
00096 
00097         if ( uri[i] == '(' )
00098         {
00099           i++;
00100 
00101           int start = i;
00102           QString col;
00103           while ( i < uri.length() && uri[i] != ')' )
00104             i++;
00105 
00106           if ( i == uri.length() )
00107           {
00108             QgsDebugMsg( "closing parenthesis missing" );
00109           }
00110 
00111           mGeometryColumn = uri.mid( start, i - start );
00112 
00113           i++;
00114         }
00115         else
00116         {
00117           mGeometryColumn = QString::null;
00118         }
00119       }
00120       else if ( pname == "key" )
00121       {
00122         mKeyColumn = pval;
00123       }
00124       else if ( pname == "estimatedmetadata" )
00125       {
00126         mUseEstimatedMetadata = pval == "true";
00127       }
00128       else if ( pname == "srid" )
00129       {
00130         mSrid = pval;
00131       }
00132       else if ( pname == "type" )
00133       {
00134         QString geomTypeUpper = pval.toUpper();
00135         if ( geomTypeUpper == "POINT" )
00136         {
00137           mWkbType = QGis::WKBPoint;
00138         }
00139         else if ( geomTypeUpper == "LINESTRING" || geomTypeUpper == "LINE" )
00140         {
00141           mWkbType = QGis::WKBLineString;
00142         }
00143         else if ( geomTypeUpper == "POLYGON" )
00144         {
00145           mWkbType = QGis::WKBPolygon;
00146         }
00147         else if ( geomTypeUpper == "MULTIPOINT" )
00148         {
00149           mWkbType = QGis::WKBMultiPoint;
00150         }
00151         else if ( geomTypeUpper == "MULTLINESTRING" )
00152         {
00153           mWkbType = QGis::WKBMultiLineString;
00154         }
00155         else if ( geomTypeUpper == "MULTIPOLYGON" )
00156         {
00157           mWkbType = QGis::WKBMultiPolygon;
00158         }
00159         else
00160         {
00161           mWkbType = QGis::WKBUnknown;
00162         }
00163       }
00164       else if ( pname == "selectatid" )
00165       {
00166         mSelectAtIdDisabled = pval == "false";
00167       }
00168       else if ( pname == "service" )
00169       {
00170         mService = pval;
00171       }
00172       else if ( pname == "user" )
00173       {
00174         mUsername = pval;
00175       }
00176       else if ( pname == "password" )
00177       {
00178         mPassword = pval;
00179       }
00180       else if ( pname == "connect_timeout" )
00181       {
00182         QgsDebugMsg( "connection timeout ignored" );
00183       }
00184       else if ( pname == "dbname" )
00185       {
00186         mDatabase = pval;
00187       }
00188       else if ( pname == "host" )
00189       {
00190         mHost = pval;
00191       }
00192       else if ( pname == "hostaddr" )
00193       {
00194         QgsDebugMsg( "database host ip address ignored" );
00195       }
00196       else if ( pname == "port" )
00197       {
00198         mPort = pval;
00199       }
00200       else if ( pname == "tty" )
00201       {
00202         QgsDebugMsg( "backend debug tty ignored" );
00203       }
00204       else if ( pname == "options" )
00205       {
00206         QgsDebugMsg( "backend debug options ignored" );
00207       }
00208       else if ( pname == "sslmode" )
00209       {
00210         if ( pval == "disable" )
00211           mSSLmode = SSLdisable;
00212         else if ( pval == "allow" )
00213           mSSLmode = SSLallow;
00214         else if ( pval == "prefer" )
00215           mSSLmode = SSLprefer;
00216         else if ( pval == "require" )
00217           mSSLmode = SSLrequire;
00218       }
00219       else if ( pname == "requiressl" )
00220       {
00221         if ( pval == "0" )
00222           mSSLmode = SSLdisable;
00223         else
00224           mSSLmode = SSLprefer;
00225       }
00226       else if ( pname == "krbsrvname" )
00227       {
00228         QgsDebugMsg( "kerberos server name ignored" );
00229       }
00230       else if ( pname == "gsslib" )
00231       {
00232         QgsDebugMsg( "gsslib ignored" );
00233       }
00234       else
00235       {
00236         QgsDebugMsg( "invalid connection option \"" + pname + "\" ignored" );
00237       }
00238     }
00239   }
00240 }
00241 
00242 QString QgsDataSourceURI::removePassword( const QString& aUri )
00243 {
00244   QRegExp regexp;
00245   regexp.setMinimal( true );
00246   QString safeName( aUri );
00247   if ( aUri.contains( " password=" ) )
00248   {
00249     regexp.setPattern( " password=.* " );
00250     safeName.replace( regexp, " " );
00251   }
00252   else if ( aUri.contains( ",password=" ) )
00253   {
00254     regexp.setPattern( ",password=.*," );
00255     safeName.replace( regexp, "," );
00256   }
00257   else if ( aUri.contains( "IDB:" ) )
00258   {
00259     regexp.setPattern( " pass=.* " );
00260     safeName.replace( regexp, " " );
00261   }
00262   else if (( aUri.contains( "OCI:" ) )
00263            || ( aUri.contains( "ODBC:" ) ) )
00264   {
00265     regexp.setPattern( "/.*@" );
00266     safeName.replace( regexp, "/@" );
00267   }
00268   else if ( aUri.contains( "SDE:" ) )
00269   {
00270     QStringList strlist = aUri.split( "," );
00271     safeName = strlist[0] + "," + strlist[1] + "," + strlist[2] + "," + strlist[3];
00272   }
00273   return safeName;
00274 }
00275 
00276 QString QgsDataSourceURI::username() const
00277 {
00278   return mUsername;
00279 }
00280 
00281 void QgsDataSourceURI::setUsername( QString username )
00282 {
00283   mUsername = username;
00284 }
00285 
00286 QString QgsDataSourceURI::service() const
00287 {
00288   return mService;
00289 }
00290 
00291 QString QgsDataSourceURI::host() const
00292 {
00293   return mHost;
00294 }
00295 
00296 QString QgsDataSourceURI::database() const
00297 {
00298   return mDatabase;
00299 }
00300 
00301 QString QgsDataSourceURI::password() const
00302 {
00303   return mPassword;
00304 }
00305 
00306 void QgsDataSourceURI::setPassword( QString password )
00307 {
00308   mPassword = password;
00309 }
00310 
00311 QString QgsDataSourceURI::port() const
00312 {
00313   return mPort;
00314 }
00315 
00316 QgsDataSourceURI::SSLmode QgsDataSourceURI::sslMode() const
00317 {
00318   return mSSLmode;
00319 }
00320 
00321 QString QgsDataSourceURI::schema() const
00322 {
00323   return mSchema;
00324 }
00325 
00326 QString QgsDataSourceURI::table() const
00327 {
00328   return mTable;
00329 }
00330 
00331 QString QgsDataSourceURI::sql() const
00332 {
00333   return mSql;
00334 }
00335 
00336 QString QgsDataSourceURI::geometryColumn() const
00337 {
00338   return mGeometryColumn;
00339 }
00340 
00341 QString QgsDataSourceURI::keyColumn() const
00342 {
00343   return mKeyColumn;
00344 }
00345 
00346 void QgsDataSourceURI::setKeyColumn( QString column )
00347 {
00348   mKeyColumn = column;
00349 }
00350 
00351 
00352 void QgsDataSourceURI::setUseEstimatedMetadata( bool theFlag )
00353 {
00354   mUseEstimatedMetadata = theFlag;
00355 }
00356 
00357 bool QgsDataSourceURI::useEstimatedMetadata() const
00358 {
00359   return mUseEstimatedMetadata;
00360 }
00361 
00362 void QgsDataSourceURI::disableSelectAtId( bool theFlag )
00363 {
00364   mSelectAtIdDisabled = theFlag;
00365 }
00366 
00367 bool QgsDataSourceURI::selectAtIdDisabled() const
00368 {
00369   return mSelectAtIdDisabled;
00370 }
00371 
00372 void QgsDataSourceURI::setSql( QString sql )
00373 {
00374   mSql = sql;
00375 }
00376 
00377 void QgsDataSourceURI::clearSchema()
00378 {
00379   mSchema = "";
00380 }
00381 
00382 QString QgsDataSourceURI::escape( const QString &theVal, QChar delim = '\'' ) const
00383 {
00384   QString val = theVal;
00385 
00386   val.replace( "\\", "\\\\" );
00387   val.replace( delim, QString( "\\%1" ).arg( delim ) );
00388 
00389   return val;
00390 }
00391 
00392 void QgsDataSourceURI::skipBlanks( const QString &uri, int &i )
00393 {
00394   // skip space before value
00395   while ( i < uri.length() && uri[i].isSpace() )
00396     i++;
00397 }
00398 
00399 QString QgsDataSourceURI::getValue( const QString &uri, int &i )
00400 {
00401   skipBlanks( uri, i );
00402 
00403   // Get the parameter value
00404   QString pval;
00405   if ( uri[i] == '\'' || uri[i] == '"' )
00406   {
00407     QChar delim = uri[i];
00408 
00409     i++;
00410 
00411     // value is quoted
00412     for ( ;; )
00413     {
00414       if ( i == uri.length() )
00415       {
00416         QgsDebugMsg( "unterminated quoted string in connection info string" );
00417         return pval;
00418       }
00419 
00420       if ( uri[i] == '\\' )
00421       {
00422         i++;
00423         if ( i == uri.length() )
00424           continue;
00425         if ( uri[i] != delim && uri[i] != '\\' )
00426           i--;
00427       }
00428       else if ( uri[i] == delim )
00429       {
00430         i++;
00431         break;
00432       }
00433 
00434       pval += uri[i++];
00435     }
00436   }
00437   else
00438   {
00439     // value is not quoted
00440     while ( i < uri.length() )
00441     {
00442       if ( uri[i].isSpace() )
00443       {
00444         // end of value
00445         break;
00446       }
00447 
00448       if ( uri[i] == '\\' )
00449       {
00450         i++;
00451         if ( i == uri.length() )
00452           break;
00453         if ( uri[i] != '\\' && uri[i] != '\'' )
00454           i--;
00455       }
00456 
00457       pval += uri[i++];
00458     }
00459   }
00460 
00461   skipBlanks( uri, i );
00462 
00463   return pval;
00464 }
00465 
00466 QString QgsDataSourceURI::connectionInfo() const
00467 {
00468   QStringList connectionItems;
00469 
00470   if ( mDatabase != "" )
00471   {
00472     connectionItems << "dbname='" + escape( mDatabase ) + "'";
00473   }
00474 
00475   if ( mService != "" )
00476   {
00477     connectionItems << "service='" + escape( mService ) + "'";
00478   }
00479   else if ( mHost != "" )
00480   {
00481     connectionItems << "host=" + mHost;
00482     if ( mPort != "" )
00483       connectionItems << "port=" + mPort;
00484   }
00485 
00486   if ( mUsername != "" )
00487   {
00488     connectionItems << "user='" + escape( mUsername ) + "'";
00489 
00490     if ( mPassword != "" )
00491     {
00492       connectionItems << "password='" + escape( mPassword ) + "'";
00493     }
00494   }
00495 
00496   if ( mSSLmode == SSLdisable )
00497     connectionItems << "sslmode=disable";
00498   else if ( mSSLmode == SSLallow )
00499     connectionItems << "sslmode=allow";
00500   else if ( mSSLmode == SSLrequire )
00501     connectionItems << "sslmode=require";
00502 #if 0
00503   else if ( mSSLmode == SSLprefer )
00504     connectionItems << "sslmode=prefer";
00505 #endif
00506 
00507   return connectionItems.join( " " );
00508 }
00509 
00510 QString QgsDataSourceURI::uri() const
00511 {
00512   QString theUri = connectionInfo();
00513 
00514   if ( !mKeyColumn.isEmpty() )
00515   {
00516     theUri += QString( " key='%1'" ).arg( escape( mKeyColumn ) );
00517   }
00518 
00519   if ( mUseEstimatedMetadata )
00520   {
00521     theUri += QString( " estimatedmetadata=true" );
00522   }
00523 
00524   if ( !mSrid.isEmpty() )
00525   {
00526     theUri += QString( " srid=%1" ).arg( mSrid );
00527   }
00528 
00529   if ( mWkbType != QGis::WKBUnknown && mWkbType != QGis::WKBNoGeometry )
00530   {
00531     theUri += " type=";
00532 
00533     switch ( mWkbType )
00534     {
00535       case QGis::WKBPoint:
00536         theUri += "POINT";
00537         break;
00538       case QGis::WKBLineString:
00539         theUri += "LINESTRING";
00540         break;
00541       case QGis::WKBPolygon:
00542         theUri += "POLYGON";
00543         break;
00544       case QGis::WKBMultiPoint:
00545         theUri += "MULTIPOINT";
00546         break;
00547       case QGis::WKBMultiLineString:
00548         theUri += "MULTILINESTRING";
00549         break;
00550       case QGis::WKBMultiPolygon:
00551         theUri += "MULTIPOLYGON";
00552         break;
00553       case QGis::WKBPoint25D:
00554         theUri += "POINTM";
00555         break;
00556       case QGis::WKBLineString25D:
00557         theUri += "LINESTRINGM";
00558         break;
00559       case QGis::WKBPolygon25D:
00560         theUri += "POLYGONM";
00561         break;
00562       case QGis::WKBMultiPoint25D:
00563         theUri += "MULTIPOINTM";
00564         break;
00565       case QGis::WKBMultiLineString25D:
00566         theUri += "MULTILINESTRINGM";
00567         break;
00568       case QGis::WKBMultiPolygon25D:
00569         theUri += "MULTIPOLYGONM";
00570         break;
00571       case QGis::WKBUnknown:
00572       case QGis::WKBNoGeometry:
00573         break;
00574     }
00575   }
00576 
00577   if ( mSelectAtIdDisabled )
00578   {
00579     theUri += QString( " selectatid=false" );
00580   }
00581 
00582   theUri += QString( " table=%1%2 sql=%3" )
00583             .arg( quotedTablename() )
00584             .arg( mGeometryColumn.isNull() ? QString() : QString( " (%1)" ).arg( mGeometryColumn ) )
00585             .arg( mSql );
00586 
00587   return theUri;
00588 }
00589 
00590 QString QgsDataSourceURI::quotedTablename() const
00591 {
00592   if ( !mSchema.isEmpty() )
00593     return QString( "\"%1\".\"%2\"" )
00594            .arg( escape( mSchema, '"' ) )
00595            .arg( escape( mTable, '"' ) );
00596   else
00597     return QString( "\"%1\"" )
00598            .arg( escape( mTable, '"' ) );
00599 }
00600 
00601 void QgsDataSourceURI::setConnection( const QString &host,
00602                                       const QString &port,
00603                                       const QString &database,
00604                                       const QString &username,
00605                                       const QString &password,
00606                                       SSLmode sslmode )
00607 {
00608   mHost = host;
00609   mDatabase = database;
00610   mPort = port;
00611   mUsername = username;
00612   mPassword = password;
00613   mSSLmode = sslmode;
00614 }
00615 
00616 void QgsDataSourceURI::setConnection( const QString &service,
00617                                       const QString &database,
00618                                       const QString &username,
00619                                       const QString &password,
00620                                       SSLmode sslmode )
00621 {
00622   mService = service;
00623   mDatabase = database;
00624   mUsername = username;
00625   mPassword = password;
00626   mSSLmode = sslmode;
00627 }
00628 
00629 void QgsDataSourceURI::setDataSource( const QString &schema,
00630                                       const QString &table,
00631                                       const QString &geometryColumn,
00632                                       const QString &sql,
00633                                       const QString &keyColumn )
00634 {
00635   mSchema = schema;
00636   mTable = table;
00637   mGeometryColumn = geometryColumn;
00638   mSql = sql;
00639   mKeyColumn = keyColumn;
00640 }
00641 
00642 void QgsDataSourceURI::setDatabase( const QString &database )
00643 {
00644   mDatabase = database;
00645 }
00646 
00647 QGis::WkbType QgsDataSourceURI::wkbType() const
00648 {
00649   return mWkbType;
00650 }
00651 
00652 void QgsDataSourceURI::setWkbType( QGis::WkbType wkbType )
00653 {
00654   mWkbType = wkbType;
00655 }
00656 
00657 QString QgsDataSourceURI::srid() const
00658 {
00659   return mSrid;
00660 }
00661 
00662 void QgsDataSourceURI::setSrid( QString srid )
00663 {
00664   mSrid = srid;
00665 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines