Path

ez components / documentation / api reference / 2008.1 / database


Database

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

Source for file query_select_sqlite.php

Documentation is available at query_select_sqlite.php

  1. <?php
  2. /**
  3.  * File containing the ezcQuerySelectSqlite 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.  * SQLite specific implementation of ezcQuery.
 13.  *
 14.  * This class reimplements methods where SQLite differs from the standard
 15.  * implementation in ezcQuery. The only difference is the right join syntax.
 16.  *
 17.  * @see ezcQuery
 18.  * @package Database
 19.  * @version 1.4
 20.  */
 21. class ezcQuerySelectSqlite extends ezcQuerySelect
 22. {
 23.     /**
 24.      * Store info for building emulation of right joins in FROM clause.
 25.      * 
 26.      * This array contains null if there was no calls to rightJoin().
 27.      * When call to rightJoin() occurs an item of right join info added.
 28.      * Right join info is array that consists of two arrays: 'tables' and 'conditions'.
 29.      * These arrays filled with values from parameters of rightJoin().
 30.      * If from() was called then new right join info item added to $rightJoins.
 31.      */
 32.     protected $rightJoins = arraynull );
 33.  
 34.     /**
 35.      * Store tables that appear in FROM clause.
 36.      * 
 37.      * Used for building fromString every time when it requested
 38.      */
 39.     protected $fromTables = array();
 40.  
 41.     /**
 42.      * Constructs a new ezcQuerySelectSqlite object.
 43.      *
 44.      * @param PDO $db 
 45.      */
 46.     public function __constructPDO $db )
 47.     {
 48.         parent::__construct$db );
 49.     }
 50.  
 51.  
 52.     /**
 53.      * Resets the query object for reuse.
 54.      *
 55.      * @return void 
 56.      */
 57.     public function reset()
 58.     {
 59.         parent::reset();
 60.         $this->fromTables = array();
 61.         $this->rightJoins = arraynull );
 62.     }
 63.  
 64.     /**
 65.      * Select which tables you want to select from.
 66.      *
 67.      * from() accepts an arbitrary number of parameters. Each parameter
 68.      * must contain either the name of a table or an array containing
 69.      * the names of tables..
 70.      * from() could be invoked several times. All provided arguments
 71.      * added to the end of $fromString.
 72.      * 
 73.      * Additional actions performed to emulate right joins in SQLite.
 74.      *
 75.      * Example:
 76.      * <code>
 77.      * // the following code will produce the SQL
 78.      * // SELECT id FROM t2 LEFT JOIN t1 ON t1.id = t2.id
 79.      * $q->select( 'id' )->from( $q->rightJoin( 't1', 't2', 't1.id', 't2.id' ) );
 80.      * 
 81.      * // the following code will produce the same SQL
 82.      * // SELECT id FROM t2 LEFT JOIN t1 ON t1.id = t2.id
 83.      * $q->select( 'id' )->from( 't1' )->rightJoin( 't2', 't1.id', 't2.id' );
 84.      * </code>
 85.      *
 86.      * @throws ezcQueryVariableParameterException if called with no parameters.
 87.      * @param string|array(string)$... Either a string with a table name or an array of table names.
 88.      * @return pointer to $this
 89.      */
 90.     public function from()
 91.     {
 92.         $args func_get_args();
 93.         $tables self::arrayFlatten$args );
 94.         if count$tables )
 95.         {
 96.             throw new ezcQueryVariableParameterException'from'count$args ));
 97.         }
 98.         $this->lastInvokedMethod = 'from';
 99.         $tables $this->getIdentifiers$tables );
100.  
101.         $this->fromTables = array_merge$this->fromTables$tables );
102.  
103.         $this->fromString ='FROM '.join', '$this->fromTables );
104.  
105.         // adding right join part of query to the end of fromString.
106.         $rightJoinPart $this->buildRightJoins();
107.         if $rightJoinPart != '' 
108.         {
109.             $this->fromString .= ', '.$rightJoinPart;
110.         }
111.  
112.         // adding new empty entry to $rightJoins if last entry was already filled
113.         $lastRightJoin end$this->rightJoins );
114.         if $lastRightJoin != null 
115.         {
116.             $this->rightJoins[null// adding empty stub to the rightJoins
117.                                         // it could be filled by next rightJoin()
118.         }
119.         return $this;
120.     }
121.  
122.     /**
123.      * Returns SQL string with part of FROM clause that performs right join emulation.
124.      * 
125.      * SQLite don't support right joins directly but there is workaround.
126.      * identical result could be acheived using right joins for tables in reverce order.
127.      * 
128.      * String created from entries of $rightJoins.
129.      * One entry is a complete table_reference clause of SQL FROM clause.
130.      * 
131.      * <code>
132.      * rightJoins[0][tables] = array( 'table1', 'table2', 'table3' )
133.      * rightJoins[0][conditions] = array( condition1, condition2 )
134.      * </code>
135.      * forms SQL: 'table3 LEFT JOIN table2 condition2 ON LEFT JOIN table1 ON condition1'.
136.      * 
137.      * 
138.      * @return string the SQL call including all right joins set in query.
139.      */
140.     private function buildRightJoins()
141.     {
142.         $resultArray array();
143.  
144.         foreach $this->rightJoins as $rJoinPart )
145.         {
146.             $oneItemResult '';
147.             if $rJoinPart === null 
148.             {
149.                 break// this is last empty entry so cancel adding.
150.             }
151.  
152.             // reverse lists of tables and conditions to make LEFT JOIN 
153.             // that will produce result equal to original right join.
154.             $reversedTables array_reverse$rJoinPart['tables');
155.             $reversedConditions array_reverse$rJoinPart['conditions');
156.  
157.             // adding first table.
158.             list$key$val each$reversedTables )
159.             $oneItemResult .= $val;
160.  
161.             while list$key$nextCondition each$reversedConditions ) )
162.             {
163.                 list$key2$nextTable each$reversedTables );   
164.                $oneItemResult .= " LEFT JOIN {$nextTable} ON {$nextCondition}";
165.             }
166.             $resultArray[$oneItemResult;
167.         }
168.  
169.         return join', '$resultArray );
170.     }
171.  
172.     /**
173.      * Returns the SQL for a right join or prepares $fromString for a right join.
174.      * 
175.      * This method could be used in two forms:
176.      *
177.      * <b>rightJoin( 't2', $joinCondition )</b>
178.      * 
179.      * Takes 2 string arguments and returns ezcQuery.
180.      *
181.      * The first parameter is the name of the table to join with. The table to
182.      * which is joined should have been previously set with the from() method.
183.      *
184.      * The second parameter should be a string containing a join condition that
185.      * is returned by an ezcQueryExpression.
186.      *
187.      * Example:
188.      * <code>
189.      * // the following code will produce the SQL
190.      * // SELECT id FROM t1 LEFT JOIN t2 ON t1.id = t2.id
191.      * $q->select( 'id' )->from( 't1' )->rightJoin( 't2', $q->expr->eq('t1.id', 't2.id' ) );
192.      * </code>
193.      *
194.      * <b>rightJoin( 't2', 't1.id', 't2.id' )</b>
195.      * 
196.      * Takes 3 string arguments and returns ezcQuery. This is a simplified form
197.      * of the 2 parameter version.  rightJoin( 't2', 't1.id', 't2.id' ) is
198.      * equal to rightJoin( 't2', $this->expr->eq('t1.id', 't2.id' ) );
199.      *
200.      * The first parameter is the name of the table to join with. The table to
201.      * which is joined should have been previously set with the from() method.
202.      * 
203.      * The second parameter is the name of the column on the table set
204.      * previously with the from() method and the third parameter the name of
205.      * the column to join with on the table that was specified in the first
206.      * parameter.
207.      *
208.      * Example:
209.      * <code>
210.      * // the following code will produce the SQL
211.      * // SELECT id FROM t1 LEFT JOIN t2 ON t1.id = t2.id
212.      * $q->select( 'id' )->from( 't1' )->rightJoin( 't2', 't1.id', 't2.id' );
213.      * </code>
214.      *
215.      * @apichange Remove 4 argument version.
216.      *
217.      * @throws ezcQueryInvalidException if called with inconsistent parameters or if
218.      *          invoked without preceding call to from().
219.      *
220.      * @param string $table2,... The table to join with, followed by either the
221.      *                            two join columns, or a join condition.
222.      * @return ezcQuery 
223.      */
224.     public function rightJoin()
225.     {
226.         $args func_get_args();
227.         $passedArgsCount func_num_args();
228.         if $passedArgsCount || $passedArgsCount )
229.         {
230.             throw new ezcQueryInvalidException'SELECT'"Wrong argument count passed to {$type}Join(): {$passedArgsCount});
231.         }
232.  
233.         // deprecated syntax
234.         if $passedArgsCount == 
235.         {
236.             if is_string$args[0&& is_string$args[1&&
237.                  is_string$args[2&& is_string$args[3
238.                
239.             {
240.                 $table1 $this->getIdentifier$args[0);
241.                 $table2 $this->getIdentifier$args[1);
242.                 $column1 $this->getIdentifier$args[2);
243.                 $column2 $this->getIdentifier$args[3);
244.  
245.                 return "{$table2} LEFT JOIN {$table1} ON {$column1} = {$column2}";
246.             }
247.             else
248.             {
249.                 throw new ezcQueryInvalidException'SELECT''Inconsistent types of arguments passed to rightJoin().' );
250.             }
251.         }
252.  
253.         // using from()->rightJoin() syntax assumed, so check if last call was to from()
254.         if $this->lastInvokedMethod != 'from' )
255.         {
256.             throw new ezcQueryInvalidException'SELECT''Invoking rightJoin() not immediately after from().' );
257.         }
258.  
259.         $table '';
260.         if !is_string$args[0) ) 
261.         {
262.             throw new ezcQueryInvalidException'SELECT'
263.                      'Inconsistent type of first argument passed to rightJoin(). Should be string with name of table.' );
264.         }
265.         $table $this->getIdentifier$args[0);
266.  
267.         $condition '';
268.         if $passedArgsCount == && is_string$args[1) ) 
269.         {
270.             $condition $args[1];
271.         }
272.         else if $passedArgsCount == && is_string$args[1&& is_string$args[2) ) 
273.         {
274.             $arg1 $this->getIdentifier$args[1);
275.             $arg2 $this->getIdentifier$args[2);
276.  
277.             $condition "{$arg1} = {$arg2}";
278.         }
279.  
280.         // If rightJoin info entry is empty than remove last table from
281.         // fromTables list and add it at first place to the list of tables in
282.         // correspondent rightJoin info entry.
283.         // Subsequent calls to rightJoin() without from() will just add one
284.         // table and one condition to the correspondent arrays.
285.  
286.         if end$this->rightJoins === null // fill last rightJoin info entry with table name.
287.         {
288.             $lastTable array_pop $this->fromTables );
289.             array_pop$this->rightJoins );
290.             $this->rightJoins[count$this->rightJoins )]['tables'][$lastTable;
291.         }
292.         
293.         if $table != '' && $condition != '' )
294.         {
295.             $this->rightJoins[count$this->rightJoins 1]['tables'][$table;
296.             $this->rightJoins[count$this->rightJoins 1]['conditions'][$condition;
297.         }
298.          
299.         // build fromString using fromTables and add right joins stuff to te end.
300.         $this->fromString = 'FROM ' join', '$this->fromTables );
301.         $this->fromString .= $this->buildRightJoins();
302.  
303.         return $this;
304.     }
305. }
306. ?>
Last updated: Wed, 18 Jun 2008