Database
[ ]
[ ]
[ ]
[ ]
[ ]
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 = array( null );
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 __construct( PDO $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 = array( null );
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 a pointer to $this
89. */
90. public function from()
91. {
92. $args = func_get_args();
93. $tables = self::arrayFlatten( $args );
94. if ( count( $tables ) < 1 )
95. {
96. throw new ezcQueryVariableParameterException( 'from', count( $args ), 1 );
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 < 2 || $passedArgsCount > 4 )
229. {
230. throw new ezcQueryInvalidException( 'SELECT', "Wrong argument count passed to {$type}Join(): {$passedArgsCount}" );
231. }
232.
233. // deprecated syntax
234. if ( $passedArgsCount == 4 )
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 == 2 && is_string( $args[1] ) )
269. {
270. $condition = $args[1];
271. }
272. else if ( $passedArgsCount == 3 && 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