PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/database/query/postgresql.php

https://bitbucket.org/biojazzard/joomla-eboracast
PHP | 630 lines | 295 code | 76 blank | 259 comment | 29 complexity | df105c89592bccacb8796be5244b8eb8 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, MIT, BSD-3-Clause
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Database
  5. *
  6. * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * Query Building Class.
  12. *
  13. * @package Joomla.Platform
  14. * @subpackage Database
  15. * @since 11.3
  16. */
  17. class JDatabaseQueryPostgresql extends JDatabaseQuery implements JDatabaseQueryLimitable
  18. {
  19. /**
  20. * @var object The FOR UPDATE element used in "FOR UPDATE" lock
  21. * @since 11.3
  22. */
  23. protected $forUpdate = null;
  24. /**
  25. * @var object The FOR SHARE element used in "FOR SHARE" lock
  26. * @since 11.3
  27. */
  28. protected $forShare = null;
  29. /**
  30. * @var object The NOWAIT element used in "FOR SHARE" and "FOR UPDATE" lock
  31. * @since 11.3
  32. */
  33. protected $noWait = null;
  34. /**
  35. * @var object The LIMIT element
  36. * @since 11.3
  37. */
  38. protected $limit = null;
  39. /**
  40. * @var object The OFFSET element
  41. * @since 11.3
  42. */
  43. protected $offset = null;
  44. /**
  45. * @var object The RETURNING element of INSERT INTO
  46. * @since 11.3
  47. */
  48. protected $returning = null;
  49. /**
  50. * Magic function to convert the query to a string, only for postgresql specific query
  51. *
  52. * @return string The completed query.
  53. *
  54. * @since 11.3
  55. */
  56. public function __toString()
  57. {
  58. $query = '';
  59. switch ($this->type)
  60. {
  61. case 'select':
  62. $query .= (string) $this->select;
  63. $query .= (string) $this->from;
  64. if ($this->join)
  65. {
  66. // Special case for joins
  67. foreach ($this->join as $join)
  68. {
  69. $query .= (string) $join;
  70. }
  71. }
  72. if ($this->where)
  73. {
  74. $query .= (string) $this->where;
  75. }
  76. if ($this->group)
  77. {
  78. $query .= (string) $this->group;
  79. }
  80. if ($this->having)
  81. {
  82. $query .= (string) $this->having;
  83. }
  84. if ($this->order)
  85. {
  86. $query .= (string) $this->order;
  87. }
  88. if ($this->limit)
  89. {
  90. $query .= (string) $this->limit;
  91. }
  92. if ($this->offset)
  93. {
  94. $query .= (string) $this->offset;
  95. }
  96. if ($this->forUpdate)
  97. {
  98. $query .= (string) $this->forUpdate;
  99. }
  100. else
  101. {
  102. if ($this->forShare)
  103. {
  104. $query .= (string) $this->forShare;
  105. }
  106. }
  107. if ($this->noWait)
  108. {
  109. $query .= (string) $this->noWait;
  110. }
  111. break;
  112. case 'update':
  113. $query .= (string) $this->update;
  114. $query .= (string) $this->set;
  115. if ($this->join)
  116. {
  117. $onWord = ' ON ';
  118. // Workaround for special case of JOIN with UPDATE
  119. foreach ($this->join as $join)
  120. {
  121. $joinElem = $join->getElements();
  122. $joinArray = explode($onWord, $joinElem[0]);
  123. $this->from($joinArray[0]);
  124. $this->where($joinArray[1]);
  125. }
  126. $query .= (string) $this->from;
  127. }
  128. if ($this->where)
  129. {
  130. $query .= (string) $this->where;
  131. }
  132. break;
  133. case 'insert':
  134. $query .= (string) $this->insert;
  135. if ($this->values)
  136. {
  137. if ($this->columns)
  138. {
  139. $query .= (string) $this->columns;
  140. }
  141. $elements = $this->values->getElements();
  142. if (!($elements[0] instanceof $this))
  143. {
  144. $query .= ' VALUES ';
  145. }
  146. $query .= (string) $this->values;
  147. if ($this->returning)
  148. {
  149. $query .= (string) $this->returning;
  150. }
  151. }
  152. break;
  153. default:
  154. $query = parent::__toString();
  155. break;
  156. }
  157. return $query;
  158. }
  159. /**
  160. * Clear data from the query or a specific clause of the query.
  161. *
  162. * @param string $clause Optionally, the name of the clause to clear, or nothing to clear the whole query.
  163. *
  164. * @return void
  165. *
  166. * @since 11.3
  167. */
  168. public function clear($clause = null)
  169. {
  170. switch ($clause)
  171. {
  172. case 'limit':
  173. $this->limit = null;
  174. break;
  175. case 'offset':
  176. $this->offset = null;
  177. break;
  178. case 'forUpdate':
  179. $this->forUpdate = null;
  180. break;
  181. case 'forShare':
  182. $this->forShare = null;
  183. break;
  184. case 'noWait':
  185. $this->noWait = null;
  186. break;
  187. case 'returning':
  188. $this->returning = null;
  189. break;
  190. case 'select':
  191. case 'update':
  192. case 'delete':
  193. case 'insert':
  194. case 'from':
  195. case 'join':
  196. case 'set':
  197. case 'where':
  198. case 'group':
  199. case 'having':
  200. case 'order':
  201. case 'columns':
  202. case 'values':
  203. parent::clear($clause);
  204. break;
  205. default:
  206. $this->type = null;
  207. $this->limit = null;
  208. $this->offset = null;
  209. $this->forUpdate = null;
  210. $this->forShare = null;
  211. $this->noWait = null;
  212. $this->returning = null;
  213. parent::clear($clause);
  214. break;
  215. }
  216. return $this;
  217. }
  218. /**
  219. * Casts a value to a char.
  220. *
  221. * Ensure that the value is properly quoted before passing to the method.
  222. *
  223. * Usage:
  224. * $query->select($query->castAsChar('a'));
  225. *
  226. * @param string $value The value to cast as a char.
  227. *
  228. * @return string Returns the cast value.
  229. *
  230. * @since 11.1
  231. */
  232. public function castAsChar($value)
  233. {
  234. return $value . '::text';
  235. }
  236. /**
  237. * Concatenates an array of column names or values.
  238. *
  239. * Usage:
  240. * $query->select($query->concatenate(array('a', 'b')));
  241. *
  242. * @param array $values An array of values to concatenate.
  243. * @param string $separator As separator to place between each value.
  244. *
  245. * @return string The concatenated values.
  246. *
  247. * @since 11.3
  248. */
  249. public function concatenate($values, $separator = null)
  250. {
  251. if ($separator)
  252. {
  253. return implode(' || ' . $this->quote($separator) . ' || ', $values);
  254. }
  255. else
  256. {
  257. return implode(' || ', $values);
  258. }
  259. }
  260. /**
  261. * Gets the current date and time.
  262. *
  263. * @return string Return string used in query to obtain
  264. *
  265. * @since 11.3
  266. */
  267. public function currentTimestamp()
  268. {
  269. return 'NOW()';
  270. }
  271. /**
  272. * Sets the FOR UPDATE lock on select's output row
  273. *
  274. * @param string $table_name The table to lock
  275. * @param boolean $glue The glue by which to join the conditions. Defaults to ',' .
  276. *
  277. * @return JDatabaseQuery FOR UPDATE query element
  278. *
  279. * @since 11.3
  280. */
  281. public function forUpdate ($table_name, $glue = ',')
  282. {
  283. $this->type = 'forUpdate';
  284. if ( is_null($this->forUpdate) )
  285. {
  286. $glue = strtoupper($glue);
  287. $this->forUpdate = new JDatabaseQueryElement('FOR UPDATE', 'OF ' . $table_name, "$glue ");
  288. }
  289. else
  290. {
  291. $this->forUpdate->append($table_name);
  292. }
  293. return $this;
  294. }
  295. /**
  296. * Sets the FOR SHARE lock on select's output row
  297. *
  298. * @param string $table_name The table to lock
  299. * @param boolean $glue The glue by which to join the conditions. Defaults to ',' .
  300. *
  301. * @return JDatabaseQuery FOR SHARE query element
  302. *
  303. * @since 11.3
  304. */
  305. public function forShare ($table_name, $glue = ',')
  306. {
  307. $this->type = 'forShare';
  308. if ( is_null($this->forShare) )
  309. {
  310. $glue = strtoupper($glue);
  311. $this->forShare = new JDatabaseQueryElement('FOR SHARE', 'OF ' . $table_name, "$glue ");
  312. }
  313. else
  314. {
  315. $this->forShare->append($table_name);
  316. }
  317. return $this;
  318. }
  319. /**
  320. * Used to get a string to extract year from date column.
  321. *
  322. * Usage:
  323. * $query->select($query->year($query->quoteName('dateColumn')));
  324. *
  325. * @param string $date Date column containing year to be extracted.
  326. *
  327. * @return string Returns string to extract year from a date.
  328. *
  329. * @since 12.1
  330. */
  331. public function year($date)
  332. {
  333. return 'EXTRACT (YEAR FROM ' . $date . ')';
  334. }
  335. /**
  336. * Used to get a string to extract month from date column.
  337. *
  338. * Usage:
  339. * $query->select($query->month($query->quoteName('dateColumn')));
  340. *
  341. * @param string $date Date column containing month to be extracted.
  342. *
  343. * @return string Returns string to extract month from a date.
  344. *
  345. * @since 12.1
  346. */
  347. public function month($date)
  348. {
  349. return 'EXTRACT (MONTH FROM ' . $date . ')';
  350. }
  351. /**
  352. * Used to get a string to extract day from date column.
  353. *
  354. * Usage:
  355. * $query->select($query->day($query->quoteName('dateColumn')));
  356. *
  357. * @param string $date Date column containing day to be extracted.
  358. *
  359. * @return string Returns string to extract day from a date.
  360. *
  361. * @since 12.1
  362. */
  363. public function day($date)
  364. {
  365. return 'EXTRACT (DAY FROM ' . $date . ')';
  366. }
  367. /**
  368. * Used to get a string to extract hour from date column.
  369. *
  370. * Usage:
  371. * $query->select($query->hour($query->quoteName('dateColumn')));
  372. *
  373. * @param string $date Date column containing hour to be extracted.
  374. *
  375. * @return string Returns string to extract hour from a date.
  376. *
  377. * @since 12.1
  378. */
  379. public function hour($date)
  380. {
  381. return 'EXTRACT (HOUR FROM ' . $date . ')';
  382. }
  383. /**
  384. * Used to get a string to extract minute from date column.
  385. *
  386. * Usage:
  387. * $query->select($query->minute($query->quoteName('dateColumn')));
  388. *
  389. * @param string $date Date column containing minute to be extracted.
  390. *
  391. * @return string Returns string to extract minute from a date.
  392. *
  393. * @since 12.1
  394. */
  395. public function minute($date)
  396. {
  397. return 'EXTRACT (MINUTE FROM ' . $date . ')';
  398. }
  399. /**
  400. * Used to get a string to extract seconds from date column.
  401. *
  402. * Usage:
  403. * $query->select($query->second($query->quoteName('dateColumn')));
  404. *
  405. * @param string $date Date column containing second to be extracted.
  406. *
  407. * @return string Returns string to extract second from a date.
  408. *
  409. * @since 12.1
  410. */
  411. public function second($date)
  412. {
  413. return 'EXTRACT (SECOND FROM ' . $date . ')';
  414. }
  415. /**
  416. * Sets the NOWAIT lock on select's output row
  417. *
  418. * @return JDatabaseQuery NO WAIT query element
  419. *
  420. * @since 11.3
  421. */
  422. public function noWait ()
  423. {
  424. $this->type = 'noWait';
  425. if ( is_null($this->noWait) )
  426. {
  427. $this->noWait = new JDatabaseQueryElement('NOWAIT', null);
  428. }
  429. return $this;
  430. }
  431. /**
  432. * Set the LIMIT clause to the query
  433. *
  434. * @param int $limit An int of how many row will be returned
  435. *
  436. * @return JDatabaseQuery Returns this object to allow chaining.
  437. *
  438. * @since 11.3
  439. */
  440. public function limit( $limit = 0 )
  441. {
  442. if (is_null($this->limit))
  443. {
  444. $this->limit = new JDatabaseQueryElement('LIMIT', (int) $limit);
  445. }
  446. return $this;
  447. }
  448. /**
  449. * Set the OFFSET clause to the query
  450. *
  451. * @param int $offset An int for skipping row
  452. *
  453. * @return JDatabaseQuery Returns this object to allow chaining.
  454. *
  455. * @since 11.3
  456. */
  457. public function offset( $offset = 0 )
  458. {
  459. if (is_null($this->offset))
  460. {
  461. $this->offset = new JDatabaseQueryElement('OFFSET', (int) $offset);
  462. }
  463. return $this;
  464. }
  465. /**
  466. * Add the RETURNING element to INSERT INTO statement.
  467. *
  468. * @param mixed $pkCol The name of the primary key column.
  469. *
  470. * @return JDatabaseQuery Returns this object to allow chaining.
  471. *
  472. * @since 11.3
  473. */
  474. public function returning( $pkCol )
  475. {
  476. if (is_null($this->returning))
  477. {
  478. $this->returning = new JDatabaseQueryElement('RETURNING', $pkCol);
  479. }
  480. return $this;
  481. }
  482. /**
  483. * Sets the offset and limit for the result set, if the database driver supports it.
  484. *
  485. * Usage:
  486. * $query->setLimit(100, 0); (retrieve 100 rows, starting at first record)
  487. * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record)
  488. *
  489. * @param integer $limit The limit for the result set
  490. * @param integer $offset The offset for the result set
  491. *
  492. * @return JDatabaseQuery Returns this object to allow chaining.
  493. *
  494. * @since 12.1
  495. */
  496. public function setLimit($limit = 0, $offset = 0)
  497. {
  498. $this->limit = (int) $limit;
  499. $this->offset = (int) $offset;
  500. return $this;
  501. }
  502. /**
  503. * Method to modify a query already in string format with the needed
  504. * additions to make the query limited to a particular number of
  505. * results, or start at a particular offset.
  506. *
  507. * @param string $query The query in string format
  508. * @param integer $limit The limit for the result set
  509. * @param integer $offset The offset for the result set
  510. *
  511. * @return string
  512. *
  513. * @since 12.1
  514. */
  515. public function processLimit($query, $limit, $offset = 0)
  516. {
  517. if ($limit > 0)
  518. {
  519. $query .= ' LIMIT ' . $limit;
  520. }
  521. if ($offset > 0)
  522. {
  523. $query .= ' OFFSET ' . $offset;
  524. }
  525. return $query;
  526. }
  527. /**
  528. * Add to the current date and time in Postgresql.
  529. * Usage:
  530. * $query->select($query->dateAdd());
  531. * Prefixing the interval with a - (negative sign) will cause subtraction to be used.
  532. *
  533. * @param datetime $date The date to add to
  534. * @param string $interval The string representation of the appropriate number of units
  535. * @param string $datePart The part of the date to perform the addition on
  536. *
  537. * @return string The string with the appropriate sql for addition of dates
  538. *
  539. * @since 13.1
  540. * @note Not all drivers support all units. Check appropriate references
  541. * @link http://www.postgresql.org/docs/9.0/static/functions-datetime.html.
  542. */
  543. public function dateAdd($date, $interval, $datePart)
  544. {
  545. if (substr($interval, 0, 1) != '-')
  546. {
  547. return "timestamp '" . $date . "' + interval '" . $interval . " " . $datePart . "'";
  548. }
  549. else
  550. {
  551. return "timestamp '" . $date . "' - interval '" . ltrim($interval, '-') . " " . $datePart . "'";
  552. }
  553. }
  554. }