/src/core/qgsdatasourceuri.cpp

https://github.com/linz/Quantum-GIS · C++ · 527 lines · 456 code · 51 blank · 20 comment · 100 complexity · 96829e5f2be6946f172c623007a98141 MD5 · raw 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. * This program is free software; you can redistribute it and/or modify *
  12. * it under the terms of the GNU General Public License as published by *
  13. * the Free Software Foundation; either version 2 of the License, or *
  14. * (at your option) any later version. *
  15. * *
  16. ***************************************************************************/
  17. #include "qgsdatasourceuri.h"
  18. #include "qgslogger.h"
  19. #include <QStringList>
  20. #include <QRegExp>
  21. QgsDataSourceURI::QgsDataSourceURI() : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
  22. {
  23. // do nothing
  24. }
  25. QgsDataSourceURI::QgsDataSourceURI( QString uri ) : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
  26. {
  27. int i = 0;
  28. while ( i < uri.length() )
  29. {
  30. skipBlanks( uri, i );
  31. if ( uri[i] == '=' )
  32. {
  33. QgsDebugMsg( "parameter name expected before =" );
  34. i++;
  35. continue;
  36. }
  37. int start = i;
  38. while ( i < uri.length() && uri[i] != '=' && !uri[i].isSpace() )
  39. i++;
  40. QString pname = uri.mid( start, i - start );
  41. skipBlanks( uri, i );
  42. if ( uri[i] != '=' )
  43. {
  44. QgsDebugMsg( "= expected after parameter name" );
  45. return;
  46. }
  47. i++;
  48. if ( pname == "sql" )
  49. {
  50. // rest of line is a sql where clause
  51. skipBlanks( uri, i );
  52. mSql = uri.mid( i );
  53. break;
  54. }
  55. else
  56. {
  57. QString pval = getValue( uri, i );
  58. if ( pname == "table" )
  59. {
  60. if ( uri[i] == '.' )
  61. {
  62. i++;
  63. mSchema = pval;
  64. mTable = getValue( uri, i );
  65. }
  66. else
  67. {
  68. mSchema = "";
  69. mTable = pval;
  70. }
  71. if ( uri[i] == '(' )
  72. {
  73. i++;
  74. int start = i;
  75. QString col;
  76. while ( i < uri.length() && uri[i] != ')' )
  77. i++;
  78. if ( i == uri.length() )
  79. {
  80. QgsDebugMsg( "closing parenthesis missing" );
  81. }
  82. mGeometryColumn = uri.mid( start, i - start );
  83. i++;
  84. }
  85. else
  86. {
  87. mGeometryColumn = QString::null;
  88. }
  89. }
  90. else if ( pname == "key" )
  91. {
  92. mKeyColumn = pval;
  93. }
  94. else if ( pname == "estimatedmetadata" )
  95. {
  96. mUseEstimatedMetadata = pval == "true";
  97. }
  98. else if ( pname == "service" )
  99. {
  100. mService = pval;
  101. }
  102. else if ( pname == "user" )
  103. {
  104. mUsername = pval;
  105. }
  106. else if ( pname == "password" )
  107. {
  108. mPassword = pval;
  109. }
  110. else if ( pname == "connect_timeout" )
  111. {
  112. QgsDebugMsg( "connection timeout ignored" );
  113. }
  114. else if ( pname == "dbname" )
  115. {
  116. mDatabase = pval;
  117. }
  118. else if ( pname == "host" )
  119. {
  120. mHost = pval;
  121. }
  122. else if ( pname == "hostaddr" )
  123. {
  124. QgsDebugMsg( "database host ip address ignored" );
  125. }
  126. else if ( pname == "port" )
  127. {
  128. mPort = pval;
  129. }
  130. else if ( pname == "tty" )
  131. {
  132. QgsDebugMsg( "backend debug tty ignored" );
  133. }
  134. else if ( pname == "options" )
  135. {
  136. QgsDebugMsg( "backend debug options ignored" );
  137. }
  138. else if ( pname == "sslmode" )
  139. {
  140. if ( pval == "disable" )
  141. mSSLmode = SSLdisable;
  142. else if ( pval == "allow" )
  143. mSSLmode = SSLallow;
  144. else if ( pval == "prefer" )
  145. mSSLmode = SSLprefer;
  146. else if ( pval == "require" )
  147. mSSLmode = SSLrequire;
  148. }
  149. else if ( pname == "requiressl" )
  150. {
  151. if ( pval == "0" )
  152. mSSLmode = SSLdisable;
  153. else
  154. mSSLmode = SSLprefer;
  155. }
  156. else if ( pname == "krbsrvname" )
  157. {
  158. QgsDebugMsg( "kerberos server name ignored" );
  159. }
  160. else if ( pname == "gsslib" )
  161. {
  162. QgsDebugMsg( "gsslib ignored" );
  163. }
  164. else
  165. {
  166. QgsDebugMsg( "invalid connection option \"" + pname + "\" ignored" );
  167. }
  168. }
  169. }
  170. }
  171. QString QgsDataSourceURI::removePassword( const QString& aUri )
  172. {
  173. QRegExp regexp;
  174. regexp.setMinimal( true );
  175. QString safeName( aUri );
  176. if ( aUri.contains( " password=" ) )
  177. {
  178. regexp.setPattern( " password=.* " );
  179. safeName.replace( regexp, " " );
  180. }
  181. else if ( aUri.contains( ",password=" ) )
  182. {
  183. regexp.setPattern( ",password=.*," );
  184. safeName.replace( regexp, "," );
  185. }
  186. else if ( aUri.contains( "IDB:" ) )
  187. {
  188. regexp.setPattern( " pass=.* " );
  189. safeName.replace( regexp, " " );
  190. }
  191. else if (( aUri.contains( "OCI:" ) )
  192. || ( aUri.contains( "ODBC:" ) ) )
  193. {
  194. regexp.setPattern( "/.*@" );
  195. safeName.replace( regexp, "/@" );
  196. }
  197. else if ( aUri.contains( "SDE:" ) )
  198. {
  199. QStringList strlist = aUri.split( "," );
  200. safeName = strlist[0] + "," + strlist[1] + "," + strlist[2] + "," + strlist[3];
  201. }
  202. return safeName;
  203. }
  204. QString QgsDataSourceURI::username() const
  205. {
  206. return mUsername;
  207. }
  208. void QgsDataSourceURI::setUsername( QString username )
  209. {
  210. mUsername = username;
  211. }
  212. QString QgsDataSourceURI::service() const
  213. {
  214. return mService;
  215. }
  216. QString QgsDataSourceURI::host() const
  217. {
  218. return mHost;
  219. }
  220. QString QgsDataSourceURI::database() const
  221. {
  222. return mDatabase;
  223. }
  224. QString QgsDataSourceURI::password() const
  225. {
  226. return mPassword;
  227. }
  228. void QgsDataSourceURI::setPassword( QString password )
  229. {
  230. mPassword = password;
  231. }
  232. QString QgsDataSourceURI::port() const
  233. {
  234. return mPort;
  235. }
  236. QgsDataSourceURI::SSLmode QgsDataSourceURI::sslMode() const
  237. {
  238. return mSSLmode;
  239. }
  240. QString QgsDataSourceURI::schema() const
  241. {
  242. return mSchema;
  243. }
  244. QString QgsDataSourceURI::table() const
  245. {
  246. return mTable;
  247. }
  248. QString QgsDataSourceURI::sql() const
  249. {
  250. return mSql;
  251. }
  252. QString QgsDataSourceURI::geometryColumn() const
  253. {
  254. return mGeometryColumn;
  255. }
  256. QString QgsDataSourceURI::keyColumn() const
  257. {
  258. return mKeyColumn;
  259. }
  260. void QgsDataSourceURI::setKeyColumn( QString column )
  261. {
  262. mKeyColumn = column;
  263. }
  264. void QgsDataSourceURI::setUseEstimatedMetadata( bool theFlag )
  265. {
  266. mUseEstimatedMetadata = theFlag;
  267. }
  268. bool QgsDataSourceURI::useEstimatedMetadata() const
  269. {
  270. return mUseEstimatedMetadata;
  271. }
  272. void QgsDataSourceURI::setSql( QString sql )
  273. {
  274. mSql = sql;
  275. }
  276. void QgsDataSourceURI::clearSchema()
  277. {
  278. mSchema = "";
  279. }
  280. QString QgsDataSourceURI::escape( const QString &theVal, QChar delim = '\'' ) const
  281. {
  282. QString val = theVal;
  283. val.replace( "\\", "\\\\" );
  284. val.replace( delim, QString( "\\%1" ).arg( delim ) );
  285. return val;
  286. }
  287. void QgsDataSourceURI::skipBlanks( const QString &uri, int &i )
  288. {
  289. // skip space before value
  290. while ( i < uri.length() && uri[i].isSpace() )
  291. i++;
  292. }
  293. QString QgsDataSourceURI::getValue( const QString &uri, int &i )
  294. {
  295. skipBlanks( uri, i );
  296. // Get the parameter value
  297. QString pval;
  298. if ( uri[i] == '\'' || uri[i] == '"' )
  299. {
  300. QChar delim = uri[i];
  301. i++;
  302. // value is quoted
  303. for ( ;; )
  304. {
  305. if ( i == uri.length() )
  306. {
  307. QgsDebugMsg( "unterminated quoted string in connection info string" );
  308. return pval;
  309. }
  310. if ( uri[i] == '\\' )
  311. {
  312. i++;
  313. if ( i == uri.length() )
  314. continue;
  315. if ( uri[i] != delim && uri[i] != '\\' )
  316. i--;
  317. }
  318. else if ( uri[i] == delim )
  319. {
  320. i++;
  321. break;
  322. }
  323. pval += uri[i++];
  324. }
  325. }
  326. else
  327. {
  328. // value is not quoted
  329. while ( i < uri.length() )
  330. {
  331. if ( uri[i].isSpace() )
  332. {
  333. // end of value
  334. break;
  335. }
  336. if ( uri[i] == '\\' )
  337. {
  338. i++;
  339. if ( i == uri.length() )
  340. break;
  341. if ( uri[i] != '\\' && uri[i] != '\'' )
  342. i--;
  343. }
  344. pval += uri[i++];
  345. }
  346. }
  347. skipBlanks( uri, i );
  348. return pval;
  349. }
  350. QString QgsDataSourceURI::connectionInfo() const
  351. {
  352. QStringList connectionItems;
  353. if ( mDatabase != "" )
  354. {
  355. connectionItems << "dbname='" + escape( mDatabase ) + "'";
  356. }
  357. if ( mService != "" )
  358. {
  359. connectionItems << "service='" + escape( mService ) + "'";
  360. }
  361. else if ( mHost != "" )
  362. {
  363. connectionItems << "host=" + mHost;
  364. if ( mPort != "" )
  365. connectionItems << "port=" + mPort;
  366. }
  367. if ( mUsername != "" )
  368. {
  369. connectionItems << "user='" + escape( mUsername ) + "'";
  370. if ( mPassword != "" )
  371. {
  372. connectionItems << "password='" + escape( mPassword ) + "'";
  373. }
  374. }
  375. if ( mSSLmode == SSLdisable )
  376. connectionItems << "sslmode=disable";
  377. else if ( mSSLmode == SSLallow )
  378. connectionItems << "sslmode=allow";
  379. else if ( mSSLmode == SSLrequire )
  380. connectionItems << "sslmode=require";
  381. #if 0
  382. else if ( mSSLmode == SSLprefer )
  383. connectionItems << "sslmode=prefer";
  384. #endif
  385. return connectionItems.join( " " );
  386. }
  387. QString QgsDataSourceURI::uri() const
  388. {
  389. QString theUri = connectionInfo();
  390. if ( !mKeyColumn.isEmpty() )
  391. {
  392. theUri += QString( " key='%1'" ).arg( escape( mKeyColumn ) );
  393. }
  394. if ( mUseEstimatedMetadata )
  395. {
  396. theUri += QString( " estimatedmetadata=true" );
  397. }
  398. theUri += QString( " table=%1%2 sql=%3" )
  399. .arg( quotedTablename() )
  400. .arg( mGeometryColumn.isNull() ? QString() : QString( " (%1)" ).arg( mGeometryColumn ) )
  401. .arg( mSql );
  402. return theUri;
  403. }
  404. QString QgsDataSourceURI::quotedTablename() const
  405. {
  406. if ( !mSchema.isEmpty() )
  407. return QString( "\"%1\".\"%2\"" )
  408. .arg( escape( mSchema, '"' ) )
  409. .arg( escape( mTable, '"' ) );
  410. else
  411. return QString( "\"%1\"" )
  412. .arg( escape( mTable, '"' ) );
  413. }
  414. void QgsDataSourceURI::setConnection( const QString &host,
  415. const QString &port,
  416. const QString &database,
  417. const QString &username,
  418. const QString &password,
  419. SSLmode sslmode )
  420. {
  421. mHost = host;
  422. mDatabase = database;
  423. mPort = port;
  424. mUsername = username;
  425. mPassword = password;
  426. mSSLmode = sslmode;
  427. }
  428. void QgsDataSourceURI::setConnection( const QString &service,
  429. const QString &database,
  430. const QString &username,
  431. const QString &password,
  432. SSLmode sslmode )
  433. {
  434. mService = service;
  435. mDatabase = database;
  436. mUsername = username;
  437. mPassword = password;
  438. mSSLmode = sslmode;
  439. }
  440. void QgsDataSourceURI::setDataSource( const QString &schema,
  441. const QString &table,
  442. const QString &geometryColumn,
  443. const QString &sql,
  444. const QString &keyColumn )
  445. {
  446. mSchema = schema;
  447. mTable = table;
  448. mGeometryColumn = geometryColumn;
  449. mSql = sql;
  450. mKeyColumn = keyColumn;
  451. }
  452. void QgsDataSourceURI::setDatabase( const QString &database )
  453. {
  454. mDatabase = database;
  455. }