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