Path

ez components / documentation / api reference / 2008.1 / database


Database

[ Tutorial ] [ Class tree ] [ Element index ] [ ChangeLog ] [ Credits ]

Source for file query_select.php

Documentation is available at query_select.php

  1. <?php
  2. /**
  3.  * File containing the ezcQuerySelect class.
  4.  *
  5.  * @package Database
  6.  * @version 1.4
  7.  * @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
  8.  * @license http://ez.no/licenses/new_bsd New BSD License
  9.  */
 10.  
 11. /**
 12.  * Class to create select database independent SELECT queries.
 13.  *
 14.  * Note that this class creates queries that are syntactically independent
 15.  * of database. Semantically the queries still differ and so the same
 16.  * query may produce different results on different databases. Such
 17.  * differences are noted throughout the documentation of this class.
 18.  *
 19.  * This class implements SQL92. If your database differs from the SQL92
 20.  * implementation extend this class and reimplement the methods that produce
 21.  * different results. Some methods implemented in ezcQuery are not defined by SQL92.
 22.  * These methods are marked and ezcQuery will return MySQL syntax for these cases.
 23.  *
 24.  * The examples show the SQL generated by this class.
 25.  * Database specific implementations may produce different results.
 26.  *
 27.  * Example:
 28.  * <code>
 29.  * $q = ezcDbInstance::get()->createSelectQuery();
 30.  * $q->select( '*' )->from( 'Greetings' )
 31.  *     ->where( $q->expr->gt( 'age', 10 ),
 32.  *              $q->expr->eq( 'greeting', $q->bindValue( 'Hello world' ) ) )
 33.  *     ->orderBy( 'owner' )
 34.  *     ->limit( 10 );
 35.  * $stmt = $q->prepare(); // $stmt is a normal PDOStatement
 36.  * $stmt->execute();
 37.  * </code>
 38.  *
 39.  * Database independence:
 40.  * TRUE/FALSE, MySQL accepts 0 and 1 as boolean values. PostgreSQL does not, but accepts TRUE/FALSE.
 41.  * @todo introduction needs examples with clone(), reusing a query and advanced binding.
 42.  * @package Database
 43.  * @version 1.4
 44.  * @mainclass
 45.  */
 46. class ezcQuerySelect extends ezcQuery
 47. {
 48.     /**
 49.      * Sort the result ascending.
 50.      */
 51.     const ASC = 'ASC';
 52.  
 53.     /**
 54.      * Sort the result descending.
 55.      */
 56.     const DESC = 'DESC';
 57.  
 58.     /**
 59.      * Stores the SELECT part of the SQL.
 60.      *
 61.      * Everything from 'SELECT' until 'FROM' is stored.
 62.      * @var string 
 63.      */
 64.     protected $selectString = null;
 65.  
 66.     /**
 67.      * Stores the FROM part of the SQL.
 68.      *
 69.      * Everything from 'FROM' until 'WHERE' is stored.
 70.      * @var string 
 71.      */
 72.     protected $fromString = null;
 73.  
 74.     /**
 75.      * Stores the WHERE part of the SQL.
 76.      *
 77.      * Everything from 'WHERE' until 'GROUP', 'LIMIT', 'ORDER' or 'SORT' is stored.
 78.      * @var string 
 79.      */
 80.     protected $whereString = null;
 81.  
 82.     /**
 83.      * Stores the GROUP BY part of the SQL.
 84.      *
 85.      * @var string 
 86.      */
 87.     protected $groupString = null;
 88.  
 89.     /**
 90.      * Stores the HAVING part of SQL
 91.      *
 92.      * @var string 
 93.      */
 94.     protected $havingString = null;
 95.  
 96.     /**
 97.      * Stores the ORDER BY part of the SQL.
 98.      *
 99.      * @var string 
100.      */
101.     protected $orderString = null;
102.  
103.     /**
104.      * Stores the LIMIT part of the SQL.
105.      *
106.      * @var string 
107.      */
108.     protected $limitString = null;
109.  
110.     /**
111.      * Stores the name of last invoked SQL clause method.
112.      *
113.      * Could be 'select', 'from', 'where', 'group', 'having', 'order', 'limit'
114.      * @var string 
115.      */
116.     protected $lastInvokedMethod = null;
117.  
118.     /**
119.      * Constructs a new ezcQuery object.
120.      *
121.      * For an introduction to aliases see {@link ezcQuery::__construct()}.
122.      *
123.      * @param PDO $db a pointer to the database object.
124.      * @param array(string=>string) $aliases 
125.      */
126.     public function __constructPDO $dbarray $aliases array() )
127.     {
128.         parent::__construct$db$aliases );
129.     }
130.  
131.     /**
132.      * Resets the query object for reuse.
133.      *
134.      * @return void 
135.      */
136.     public function reset()
137.     {
138.         $this->selectString = null;
139.         $this->fromString = null;
140.         $this->whereString = null;
141.         $this->groupString = null;
142.         $this->havingString = null;
143.         $this->orderString = null;
144.         $this->limitString = null;
145.         $this->lastInvokedClauseMethod null;
146.  
147.         $this->boundCounter 0;
148.         $this->boundValues array();
149.     }
150.  
151.     /**
152.      * Opens the query and selects which columns you want to return with
153.      * the query.
154.      *
155.      * select() accepts an arbitrary number of parameters. Each parameter
156.      * must contain either the name of a column or an array containing
157.      * the names of the columns.
158.      * Each call to select() appends columns to the list of columns that will be
159.      * used in the query.
160.      *
161.      * Example:
162.      * <code>
163.      * $q->select( 'column1', 'column2' );
164.      * </code>
165.      * The same could also be written
166.      * <code>
167.      * $columns[] = 'column1';
168.      * $columns[] = 'column2;
169.      * $q->select( $columns );
170.      * </code>
171.      * or using several calls
172.      * <code>
173.      * $q->select( 'column1' )->select( 'column2' );
174.      * </code>
175.      *
176.      * Each of above code produce SQL clause 'SELECT column1, column2' for the query.
177.      *
178.      * @throws ezcQueryVariableParameterException if called with no parameters..
179.      * @param string|array(string)$... Either a string with a column name or an array of column names.
180.      * @return ezcQuery returns a pointer to $this.
181.      */
182.     public function select()
183.     {
184.         if $this->selectString == null )
185.         {
186.             $this->selectString = 'SELECT ';
187.         }
188.  
189.         $args func_get_args();
190.         $cols self::arrayFlatten$args );
191.  
192.         if count$cols )
193.         {
194.             throw new ezcQueryVariableParameterException'select'count$args ));
195.         }
196.         $this->lastInvokedMethod = 'select';
197.         $cols $this->getIdentifiers$cols );
198.  
199.         // glue string should be inserted each time but not before first entry
200.         if ( ( $this->selectString !== 'SELECT ' &&
201.              $this->selectString !== 'SELECT DISTINCT ' ) )
202.         {
203.             $this->selectString .= ', ';
204.         }
205.  
206.         $this->selectString .= join', '$cols );
207.         return $this;
208.     }
209.  
210.     /**
211.      * Returns SQL to create an alias
212.      *
213.      * This method can be used to create an alias for either a
214.      * table or a column.
215.      * Example:
216.      * <code>
217.      * // this will make the table users have the alias employees
218.      * // and the column user_id the alias employee_id
219.      * $q->select( $q->alias( 'user_id', 'employee_id' )
220.      *   ->from( $q->alias( 'users', 'employees' ) );
221.      * </code>
222.      *
223.      * @param string $name 
224.      * @param string $alias 
225.      * @return string the query string "columnname as targetname"
226.      */
227.     public function alias$name$alias )
228.     {
229.         $name $this->getIdentifier$name );
230.         return "{$name} AS {$alias}";
231.     }
232.  
233.     /**
234.      * Opens the query and uses a distinct select on the columns you want to
235.      * return with the query.
236.      *
237.      * selectDistinct() accepts an arbitrary number of parameters. Each
238.      * parameter  must contain either the name of a column or an array
239.      * containing the names of the columns.
240.      * Each call to selectDistinct() appends columns to the list of columns
241.      * that will be used in the query.
242.      *
243.      * Example:
244.      * <code>
245.      * $q->selectDistinct( 'column1', 'column2' );
246.      * </code>
247.      * The same could also be written
248.      * <code>
249.      * $columns[] = 'column1';
250.      * $columns[] = 'column2;
251.      * $q->selectDistinct( $columns );
252.      * </code>
253.      * or using several calls
254.      * <code>
255.      * $q->selectDistinct( 'column1' )->select( 'column2' );
256.      * </code>
257.      *
258.      * Each of above code produce SQL clause 'SELECT DISTINCT column1, column2'
259.      * for the query.
260.      *
261.      * You may call select() after calling selectDistinct() which will result
262.      * in the additional columns beein added. A call of selectDistinct() after
263.      * select() will result in an ezcQueryInvalidException.
264.      *
265.      * @throws ezcQueryVariableParameterException if called with no parameters..
266.      * @throws ezcQueryInvalidException if called after select()
267.      * @param string|array(string)$... Either a string with a column name or an array of column names.
268.      * @return ezcQuery returns a pointer to $this.
269.      */
270.     public function selectDistinct()
271.     {
272.         if $this->selectString == null )
273.         {
274.             $this->selectString = 'SELECT DISTINCT ';
275.         }
276.         elseif strpos $this->selectString'DISTINCT' === false )
277.         {
278.             throw new ezcQueryInvalidException
279.                 'SELECT',
280.                 'You can\'t use selectDistinct() after using select() in the same query.'
281.             );
282.         }
283.  
284.         // Call ezcQuerySelect::select() to do the parameter processing
285.         $args func_get_args();
286.         return call_user_func_array(
287.             array$this'select' ),
288.             $args
289.         );
290.     }
291.  
292.     /**
293.      * Select which tables you want to select from.
294.      *
295.      * from() accepts an arbitrary number of parameters. Each parameter
296.      * must contain either the name of a table or an array containing
297.      * the names of tables..
298.      * Each call to from() appends tables to the list of tables that will be
299.      * used in the query.
300.      *
301.      * Example:
302.      * <code>
303.      * // the following code will produce the SQL
304.      * // SELECT id FROM table_name
305.      * $q->select( 'id' )->from( 'table_name' );
306.      * </code>
307.      *
308.      * @throws ezcQueryVariableParameterException if called with no parameters.
309.      * @param string|array(string)$... Either a string with a table name or an array of table names.
310.      * @return ezcQuery a pointer to $this
311.      */
312.     public function from()
313.     {
314.         if $this->fromString == '' )
315.         {
316.             $this->fromString = 'FROM ';
317.         }
318.  
319.         $args func_get_args();
320.         $tables self::arrayFlatten$args );
321.         if count$tables )
322.         {
323.             throw new ezcQueryVariableParameterException'from'count$args ));
324.         }
325.         $this->lastInvokedMethod = 'from';
326.         $tables $this->getIdentifiers$tables );
327.  
328.         // glue string should be inserted each time but not before first entry
329.         if $this->fromString != 'FROM ' )
330.         {
331.             $this->fromString .= ', ';
332.         }
333.  
334.         $this->fromString .= join', '$tables );
335.         return $this;
336.     }
337.  
338.     /**
339.      * Returns the SQL for a join or prepares $fromString for a join.
340.      *
341.      * This method could be used in two forms:
342.      *
343.      * <b>doJoin( $joinType, 't2', $joinCondition )</b>
344.      *
345.      * Takes the join type and two string arguments and returns ezcQuery.
346.      *
347.      * The second parameter is the name of the table to join with. The table to
348.      * which is joined should have been previously set with the from() method.
349.      *
350.      * The third parameter should be a string containing a join condition that
351.      * is returned by an ezcQueryExpression.
352.      *
353.      * <b>doJoin( $joinType, 't2', 't1.id', 't2.id' )</b>
354.      *
355.      * Takes the join type and three string arguments and returns ezcQuery.
356.      * This is a simplified form of the three parameter version.  doJoin(
357.      * 'inner', 't2', 't1.id', 't2.id' ) is equal to doJoin( 'inner', 't2',
358.      * $this->expr->eq('t1.id', 't2.id' ) );
359.      *
360.      * The second parameter is the name of the table to join with. The table to
361.      * which is joined should have been previously set with the from() method.
362.      *
363.      * The third parameter is the name of the column on the table set
364.      * previously with the from() method and the fourth parameter the name of
365.      * the column to join with on the table that was specified in the first
366.      * parameter.
367.      *
368.      * @apichange Remove "5" argument version.
369.      *
370.      * @throws ezcQueryInvalidException if called with inconsistent parameters or if
371.      *          invoked without preceding call to from().
372.      *
373.      * @param string $type       The join type: inner, right or left.
374.      * @param string $table2,... The table to join with, followed by either the
375.      *                            two join columns, or a join condition.
376.      * @return ezcQuery 
377.      */
378.     protected function doJoin$type )
379.     {
380.         $args func_get_args();
381.         // Remove the first one, as that's the $type of join.
382.         array_shift$args );
383.  
384.         $sqlType strtoupper$type );
385.  
386.         $passedArgsCount func_num_args(1;
387.         if $passedArgsCount || $passedArgsCount )
388.         {
389.             throw new ezcQueryInvalidException'SELECT'"Wrong argument count passed to {$type}Join(): {$passedArgsCount});
390.         }
391.  
392.         // deprecated syntax
393.         if $passedArgsCount == )
394.         {
395.             if is_string$args[0&& is_string$args[1&&
396.                  is_string$args[2&& is_string$args[3)
397.                )
398.             {
399.                 $table1 $this->getIdentifier$args[0);
400.                 $table2 $this->getIdentifier$args[1);
401.                 $column1 $this->getIdentifier$args[2);
402.                 $column2 $this->getIdentifier$args[3);
403.  
404.                 return "{$table1} {$sqlType} JOIN {$table2} ON {$column1} = {$column2}";
405.             }
406.             else
407.             {
408.                 throw new ezcQueryInvalidException'SELECT'"Inconsistent types of arguments passed to {$type}Join().);
409.             }
410.         }
411.  
412.         // using from()->*Join() syntax assumed, so check if last call was to from()
413.         if $this->lastInvokedMethod != 'from' )
414.         {
415.             throw new ezcQueryInvalidException'SELECT'"Invoking {$type}Join() not immediately after from().);
416.         }
417.  
418.         $table '';
419.         if !is_string$args[0) )
420.         {
421.             throw new ezcQueryInvalidException'SELECT',
422.                      "Inconsistent type of first argument passed to {$type}Join(). Should be string with name of table.);
423.         }
424.         $table $this->getIdentifier$args[0);
425.  
426.         $condition '';
427.         if $passedArgsCount == && is_string$args[1) )
428.         {
429.             $condition $args[1];
430.         }
431.         else if $passedArgsCount == && is_string$args[1&& is_string$args[2) )
432.         {
433.             $arg1 $this->getIdentifier$args[1);
434.             $arg2 $this->getIdentifier$args[2);
435.  
436.             $condition "{$arg1} = {$arg2}";
437.         }
438.  
439.         $this->fromString .= " {$sqlType} JOIN {$table} ON {$condition}";
440.         return $this;
441.     }
442.  
443.     /**
444.      * Returns the SQL for an inner join or prepares $fromString for an inner join.
445.      * 
446.      * This method could be used in two forms:
447.      *
448.      * <b>innerJoin( 't2', $joinCondition )</b>
449.      * 
450.      * Takes 2 string arguments and returns ezcQuery.
451.      *
452.      * The first parameter is the name of the table to join with. The table to
453.      * which is joined should have been previously set with the from() method.
454.      *
455.      * The second parameter should be a string containing a join condition that
456.      * is returned by an ezcQueryExpression.
457.      *
458.      * Example:
459.      * <code>
460.      * // the following code will produce the SQL
461.      * // SELECT id FROM t1 INNER JOIN t2 ON t1.id = t2.id
462.      * $q->select( 'id' )->from( 't1' )->innerJoin( 't2', $q->expr->eq('t1.id', 't2.id' ) );
463.      * </code>
464.      *
465.      * <b>innerJoin( 't2', 't1.id', 't2.id' )</b>
466.      * 
467.      * Takes 3 string arguments and returns ezcQuery. This is a simplified form
468.      * of the 2 parameter version.  innerJoin( 't2', 't1.id', 't2.id' ) is
469.      * equal to innerJoin( 't2', $this->expr->eq('t1.id', 't2.id' ) );
470.      *
471.      * The first parameter is the name of the table to join with. The table to
472.      * which is joined should have been previously set with the from() method.
473.      * 
474.      * The second parameter is the name of the column on the table set
475.      * previously with the from() method and the third parameter the name of
476.      * the column to join with on the table that was specified in the first
477.      * parameter.
478.      *
479.      * Example:
480.      * <code>
481.      * // the following code will produce the SQL
482.      * // SELECT id FROM t1 INNER JOIN t2 ON t1.id = t2.id
483.      * $q->select( 'id' )->from( 't1' )->innerJoin( 't2', 't1.id', 't2.id' );
484.      * </code>
485.      *
486.      * @apichange Remove 4 argument version.
487.      *
488.      * @throws ezcQueryInvalidException if called with inconsistent parameters or if
489.      *          invoked without preceding call to from().
490.      *
491.      * @param string $table2,... The table to join with, followed by either the
492.      *                            two join columns, or a join condition.
493.      * @return ezcQuery 
494.      */
495.     public function innerJoin()
496.     {
497.         $args func_get_args();
498.         array_unshift$args'inner' );
499.         return call_user_func_arrayarray$this'doJoin' )$args );
500.     }
501.  
502.     /**
503.      * Returns the SQL for a left join or prepares $fromString for a left join.
504.      * 
505.      * This method could be used in two forms:
506.      *
507.      * <b>leftJoin( 't2', $joinCondition )</b>
508.      * 
509.      * Takes 2 string arguments and returns ezcQuery.
510.      *
511.      * The first parameter is the name of the table to join with. The table to
512.      * which is joined should have been previously set with the from() method.
513.      *
514.      * The second parameter should be a string containing a join condition that
515.      * is returned by an ezcQueryExpression.
516.      *
517.      * Example:
518.      * <code>
519.      * // the following code will produce the SQL
520.      * // SELECT id FROM t1 LEFT JOIN t2 ON t1.id = t2.id
521.      * $q->select( 'id' )->from( 't1' )->leftJoin( 't2', $q->expr->eq('t1.id', 't2.id' ) );
522.      * </code>
523.      *
524.      * <b>leftJoin( 't2', 't1.id', 't2.id' )</b>
525.      * 
526.      * Takes 3 string arguments and returns ezcQuery. This is a simplified form
527.      * of the 2 parameter version.  leftJoin( 't2', 't1.id', 't2.id' ) is
528.      * equal to leftJoin( 't2', $this->expr->eq('t1.id', 't2.id' ) );
529.      *
530.      * The first parameter is the name of the table to join with. The table to
531.      * which is joined should have been previously set with the from() method.
532.      * 
533.      * The second parameter is the name of the column on the table set
534.      * previously with the from() method and the third parameter the name of
535.      * the column to join with on the table that was specified in the first
536.      * parameter.
537.      *
538.      * Example:
539.      * <code>
540.      * // the following code will produce the SQL
541.      * // SELECT id FROM t1 LEFT JOIN t2 ON t1.id = t2.id
542.      * $q->select( 'id' )->from( 't1' )->leftJoin( 't2', 't1.id', 't2.id' );
543.      * </code>
544.      *
545.      * @apichange Remove 4 argument version.
546.      *
547.      * @throws ezcQueryInvalidException if called with inconsistent parameters or if
548.      *          invoked without preceding call to from().
549.      *
550.      * @param string $table2,... The table to join with, followed by either the
551.      *                            two join columns, or a join condition.
552.      * @return ezcQuery 
553.      */
554.     public function leftJoin()
555.     {
556.         $args func_get_args();
557.         array_unshift$args'left' );
558.         return call_user_func_arrayarray$this'doJoin' )$args );
559.     }
560.  
561.     /**
562.      * Returns the SQL for a right join or prepares $fromString for a right join.
563.      * 
564.      * This method could be used in two forms:
565.      *
566.      * <b>rightJoin( 't2', $joinCondition )</b>
567.      * 
568.      * Takes 2 string arguments and returns ezcQuery.
569.      *
570.      * The first parameter is the name of the table to join with. The table to
571.      * which is joined should have been previously set with the from() method.
572.      *
573.      * The second parameter should be a string containing a join condition that
574.      * is returned by an ezcQueryExpression.
575.      *
576.      * Example:
577.      * <code>
578.      * // the following code will produce the SQL
579.      * // SELECT id FROM t1 LEFT JOIN t2 ON t1.id = t2.id
580.      * $q->select( 'id' )->from( 't1' )->rightJoin( 't2', $q->expr->eq('t1.id', 't2.id' ) );
581.      * </code>
582.      *
583.      * <b>rightJoin( 't2', 't1.id', 't2.id' )</b>
584.      * 
585.      * Takes 3 string arguments and returns ezcQuery. This is a simplified form
586.      * of the 2 parameter version.  rightJoin( 't2', 't1.id', 't2.id' ) is
587.      * equal to rightJoin( 't2', $this->expr->eq('t1.id', 't2.id' ) );
588.      *
589.      * The first parameter is the name of the table to join with. The table to
590.      * which is joined should have been previously set with the from() method.
591.      * 
592.      * The second parameter is the name of the column on the table set
593.      * previously with the from() method and the third parameter the name of
594.      * the column to join with on the table that was specified in the first
595.      * parameter.
596.      *
597.      * Example:
598.      * <code>
599.      * // the following code will produce the SQL
600.      * // SELECT id FROM t1 LEFT JOIN t2 ON t1.id = t2.id
601.      * $q->select( 'id' )->from( 't1' )->rightJoin( 't2', 't1.id', 't2.id' );
602.      * </code>
603.      *
604.      * @apichange Remove 4 argument version.
605.      *
606.      * @throws ezcQueryInvalidException if called with inconsistent parameters or if
607.      *          invoked without preceding call to from().
608.      *
609.      * @param string $table2,... The table to join with, followed by either the
610.      *                            two join columns, or a join condition.
611.      * @return ezcQuery 
612.      */
613.     public function rightJoin()
614.     {
615.         $args func_get_args();
616.         array_unshift$args'right' );
617.         return call_user_func_arrayarray$this'doJoin' )$args );
618.     }
619.  
620.     /**
621.      * Adds a where clause with logical expressions to the query.
622.      *
623.      * where() accepts an arbitrary number of parameters. Each parameter
624.      * must contain a logical expression or an array with logical expressions.
625.      * If you specify multiple logical expression they are connected using
626.      * a logical and.
627.      *
628.      * Multiple calls to where() will join the expressions using a logical and.
629.      *
630.      * Example:
631.      * <code>
632.      * $q->select( '*' )->from( 'table' )->where( $q->expr->eq( 'id', 1 ) );
633.      * </code>
634.      *
635.      * @throws ezcQueryVariableParameterException if called with no parameters.
636.      * @param string|array(string)$... Either a string with a logical expression name
637.      *  or an array with logical expressions.
638.      * @return ezcQuerySelect 
639.      */
640.     public function where()
641.     {
642.         if $this->whereString == null )
643.         {
644.             $this->whereString = 'WHERE ';
645.         }
646.  
647.         $args func_get_args();
648.         $expressions self::arrayFlatten$args );
649.         if count$expressions )
650.         {
651.             throw new ezcQueryVariableParameterException'where'count$args ));
652.         }
653.  
654.         $this->lastInvokedMethod = 'where';
655.  
656.         // glue string should be inserted each time but not before first entry
657.         if $this->whereString != 'WHERE ' )
658.         {
659.             $this->whereString .= ' AND ';
660.         }
661.  
662.         $this->whereString .= join' AND '$expressions );
663.         return $this;
664.     }
665.  
666.  
667.     // limit, order and group
668.  
668.     
669.     /**
670.      * Returns SQL that limits the result set.
671.      *
672.      * $limit controls the maximum number of rows that will be returned.
673.      * $offset controls which row that will be the first in the result
674.      * set from the total amount of matching rows.
675.      *
676.      * Example:
677.      * <code>
678.      * $q->select( '*' )->from( 'table' )
679.      *                  ->limit( 10, 0 );
680.      * </code>
681.      *
682.      * LIMIT is not part of SQL92. It is implemented here anyway since all
683.      * databases support it one way or the other and because it is
684.      * essential.
685.      *
686.      * @param string $limit integer expression
687.      * @param string $offset integer expression
688.      * @return ezcQuerySelect 
689.      */
690.     public function limit$limit$offset '' )
691.     {
692.         if $offset === '' )
693.         {
694.             $this->limitString = "LIMIT {$limit}";
695.         }
696.         else
697.         {
698.             $this->limitString = "LIMIT {$limit} OFFSET {$offset}";
699.         }
700.         $this->lastInvokedMethod = 'limit';
701.  
702.         return $this;
703.     }
704.  
705.     /**
706.      * Returns SQL that orders the result set by a given column.
707.      *
708.      * You can call orderBy multiple times. Each call will add a
709.      * column to order by.
710.      *
711.      * Example:
712.      * <code>
713.      * $q->select( '*' )->from( 'table' )
714.      *                  ->orderBy( 'id' );
715.      * </code>
716.      *
717.      * @param string $column a column name in the result set
718.      * @param string $type if the column should be sorted ascending or descending.
719.      *         you can specify this using ezcQuerySelect::ASC or ezcQuerySelect::DESC
720.      * @return ezcQuery a pointer to $this
721.      */
722.     public function orderBy$column$type self::ASC )
723.     {
724.         $string $this->getIdentifier$column );
725.         if $type == self::DESC )
726.         {
727.             $string .= ' DESC';
728.         }
729.         if $this->orderString == '' )
730.         {
731.             $this->orderString = "ORDER BY {$string}";
732.         }
733.         else
734.         {
735.             $this->orderString .= ", {$string}";
736.         }
737.         $this->lastInvokedMethod = 'order';
738.  
739.         return $this;
740.     }
741.  
742.     /**
743.      * Returns SQL that groups the result set by a given column.
744.      *
745.      * You can call groupBy multiple times. Each call will add a
746.      * column to group by.
747.      *
748.      * Example:
749.      * <code>
750.      * $q->select( '*' )->from( 'table' )
751.      *                  ->groupBy( 'id' );
752.      * </code>
753.      *
754.      * @throws ezcQueryVariableParameterException if called with no parameters.
755.      * @param string $column a column name in the result set
756.      * @return ezcQuery a pointer to $this
757.      */
758.     public function groupBy()
759.     {
760.         $args func_get_args();
761.         $columns self::arrayFlatten$args );
762.         if count$columns )
763.         {
764.             throw new ezcQueryVariableParameterException'groupBy'count$args ));
765.         }
766.         $columns $this->getIdentifiers$columns );
767.  
768.         $string join', '$columns );
769.         if $this->groupString == '' )
770.         {
771.             $this->groupString = "GROUP BY {$string};
772.         }
773.         else
774.         {
775.             $this->groupString .= ", {$string}";
776.         }
777.  
778.         $this->lastInvokedMethod = 'group';
779.  
780.         return $this;
781.     }
782.  
783.     /**
784.      * Returns SQL that set having by a given expression.
785.      *
786.      * You can call having multiple times. Each call will add an
787.      * expression with a logical and.
788.      *
789.      * Example:
790.      * <code>
791.      * $q->select( '*' )->from( 'table' )->groupBy( 'id' )
792.      *                  ->having( $q->expr->eq('id',1) );
793.      * </code>
794.      *
795.      * @throws ezcQueryInvalidException
796.      *          if invoked without preceding call to groupBy().
797.      * @throws ezcQueryVariableParameterException
798.      *          if called with no parameters.
799.      * @param string|array(string)$... Either a string with a logical expression name
800.      *                              or an array with logical expressions.
801.      * @return ezcQuery a pointer to $this
802.      */
803.     public function having()
804.     {
805.         // using groupBy()->having() syntax assumed, so check if last call was to groupBy()
806.         if $this->lastInvokedMethod != 'group' && $this->lastInvokedMethod != 'having' )
807.         {
808.             throw new ezcQueryInvalidException'SELECT''Invoking having() not immediately after groupBy().' );
809.         }
810.  
811.         $args func_get_args();
812.         $expressions self::arrayFlatten$args );
813.         if count$expressions )
814.         {
815.             throw new ezcQueryVariableParameterException'having'count$args ));
816.         }
817.  
818.         if $this->havingString == null )
819.         {
820.             $this->havingString = 'HAVING ';
821.         }
822.  
823.         // will add "AND expression" in subsequent calls to having()
824.         if $this->havingString != 'HAVING ' )
825.         {
826.             $this->havingString .= ' AND ';
827.         }
828.  
829.         $this->havingString .= join' AND '$expressions );
830.         $this->lastInvokedMethod = 'having';
831.         return $this;
832.     }
833.  
834.     /**
835.      * Returns dummy table name.
836.      *
837.      * If your select query just evaluates an expression
838.      * without fetching table data (e.g. 'SELECT 1+1')
839.      * some databases require you to specify a dummy table in FROM clause.
840.      * (Oracle: 'SELECT 1+1 FROM dual').
841.      *
842.      * This methods returns name of such a dummy table.
843.      * For DBMSs that don't require that, the method returns false.
844.      * Otherwise the dummy table name is returned.
845.      *
846.      * @return bool|stringa dummy table name or false if not needed
847.      */
848.     static public function getDummyTableName()
849.     {
850.         return false;
851.     }
852.  
853.     /**
854.      * Returns the complete select query string.
855.      *
856.      * This method uses the build methods to build the
857.      * various parts of the select query.
858.      *
859.      * @todo add newlines? easier for debugging
860.      * @throws ezcQueryInvalidException if it was not possible to build a valid query.
861.      * @return string 
862.      */
863.     public function getQuery()
864.     {
865.         if $this->selectString == null )
866.         {
867.             throw new ezcQueryInvalidException"SELECT""select() was not called before getQuery()." );
868.         }
869.  
870.         $query "{$this->selectString}";
871.         if ( $this->fromString != null )
872.         {
873.             $query = "{$query} {$this->fromString}";
874.         }
875.         if ( $this->whereString != null )
876.         {
877.             $query = "{$query} {$this->whereString}";
878.         }
879.         if ( $this->groupString != null )
880.         {
881.             $query = "{$query} {$this->groupString}";
882.         }
883.         if ( $this->havingString != null )
884.         {
885.             $query = "{$query} {$this->havingString}";
886.         }
887.         if ( $this->orderString != null )
888.         {
889.             $query = "{$query} {$this->orderString}";
890.         }
891.         if ( $this->limitString != null )
892.         {
893.             $query = "{$query} {$this->limitString}";
894.         }
895.         return $query;
896.     }
897.  
898. }
899.  
Last updated: Wed, 18 Jun 2008