92d0ca1ed45be2e6df091527c1fbf9ccb1c2fd8b
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / QOM / QueryObjectModel.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
6 * All rights reserved
7 *
8 * This class is a backport of the corresponding class of FLOW3.
9 * All credits go to the v5 team.
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 /**
29 * A query in the JCR query object model.
30 *
31 * The JCR query object model describes the queries that can be evaluated by a JCR
32 * repository independent of any particular query language, such as SQL.
33 *
34 * A query consists of:
35 *
36 * a source. When the query is evaluated, the source evaluates its selectors and
37 * the joins between them to produce a (possibly empty) set of node-tuples. This
38 * is a set of 1-tuples if the query has one selector (and therefore no joins), a
39 * set of 2-tuples if the query has two selectors (and therefore one join), a set
40 * of 3-tuples if the query has three selectors (two joins), and so forth.
41 * an optional constraint. When the query is evaluated, the constraint filters the
42 * set of node-tuples.
43 * a list of zero or more orderings. The orderings specify the order in which the
44 * node-tuples appear in the query results. The relative order of two node-tuples
45 * is determined by evaluating the specified orderings, in list order, until
46 * encountering an ordering for which one node-tuple precedes the other. If no
47 * orderings are specified, or if for none of the specified orderings does one
48 * node-tuple precede the other, then the relative order of the node-tuples is
49 * implementation determined (and may be arbitrary).
50 * a list of zero or more columns to include in the tabular view of the query
51 * results. If no columns are specified, the columns available in the tabular view
52 * are implementation determined, but minimally include, for each selector, a column
53 * for each single-valued non-residual property of the selector's node type.
54 *
55 * The query object model representation of a query is created by factory methods in the QueryObjectModelFactory.
56 *
57 * @package Extbase
58 * @subpackage Persistence\QOM
59 * @version $Id$
60 * @scope prototype
61 */
62 class Tx_Extbase_Persistence_QOM_QueryObjectModel implements Tx_Extbase_Persistence_QOM_QueryObjectModelInterface {
63
64 /**
65 * @var Tx_Extbase_Persistence_QOM_SourceInterface
66 */
67 protected $source;
68
69 /**
70 * @var Tx_Extbase_Persistence_QOM_ConstraintInterface
71 */
72 protected $constraint;
73
74 /**
75 * @var array
76 */
77 protected $orderings;
78
79 /**
80 * @var array
81 */
82 protected $columns;
83
84 /**
85 * @var Tx_Extbase_Persistence_Storage_BackendInterface
86 */
87 protected $storageBackend;
88
89 /**
90 * var integer
91 */
92 protected $limit;
93
94 /**
95 * integer
96 */
97 protected $offset;
98
99 /**
100 * @var array
101 */
102 protected $boundVariables = array();
103
104 /**
105 * The query settings
106 * @var Tx_Extbase_Persistence_QuerySettingsInterface
107 */
108 protected $querySettings;
109
110 /**
111 * Constructs this QueryObjectModel instance
112 *
113 * @param Tx_Extbase_Persistence_QOM_SourceInterface $selectorOrSource
114 * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint (null if none)
115 * @param array $orderings
116 * @param array $columns
117 */
118 public function __construct(Tx_Extbase_Persistence_QOM_SourceInterface $selectorOrSource, $constraint, array $orderings = array(), array $columns = array()) {
119 $this->source = $selectorOrSource;
120 $this->constraint = $constraint;
121 $this->orderings = $orderings;
122 $this->columns = $columns;
123
124 if ($this->constraint !== NULL) {
125 $this->constraint->collectBoundVariableNames($this->boundVariables);
126 }
127 }
128
129 /**
130 * Injects the StorageBackend
131 *
132 * @param Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend
133 * @return void
134 */
135 public function injectStorageBackend(Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend) {
136 $this->storageBackend = $storageBackend;
137 }
138
139 /**
140 * Sets the Query Settings. These Query settings must match the settings expected by
141 * the specific Storage Backend.
142 *
143 * @param Tx_Extbase_Persistence_QuerySettingsInterface $querySettings The Query Settings
144 * @return void
145 */
146 public function setQuerySettings(Tx_Extbase_Persistence_QuerySettingsInterface $querySettings) {
147 $this->querySettings = $querySettings;
148 }
149
150 /**
151 * Returns the Query Settings.
152 *
153 * @return Tx_Extbase_Persistence_QuerySettingsInterface $querySettings The Query Settings
154 */
155 public function getQuerySettings() {
156 if (!($this->querySettings instanceof Tx_Extbase_Persistence_QuerySettingsInterface)) throw new Tx_Extbase_Persistence_Exception('Tried to get the query settings without seting them before.', 1248689115);
157 return $this->querySettings;
158 }
159
160 /**
161 * Sets the maximum size of the result set to limit.
162 *
163 * @param integer $limit
164 * @return void
165 */
166 public function setLimit($limit) {
167 if ($limit < 1 || !is_int($limit)) {
168 throw new InvalidArgumentException('setLimit() accepts only integers greater than 0.', 1217244746);
169 }
170 $this->limit = $limit;
171 }
172
173 /**
174 * Returns the maximum size of the result set.
175 *
176 * @return integer
177 */
178 public function getLimit() {
179 return $this->limit;
180 }
181
182 /**
183 * Sets the start offset of the result set to offset.
184 *
185 * @param integer $offset
186 * @return void
187 */
188 public function setOffset($offset) {
189 if ($offset < 0 || !is_int($offset)) {
190 throw new InvalidArgumentException('setOffset() accepts only integers greater than or equal to 0.', 1217245454);
191 }
192 $this->offset = $offset;
193 }
194
195 /**
196 * Returns the start offset of the result set.
197 *
198 * @return integer
199 */
200 public function getOffset() {
201 return $this->offset;
202 }
203
204 /**
205 * Returns the class name the query handles
206 *
207 * @return string The class name
208 */
209 public function getSelectorName() {
210 $this->source->getSelectorName();
211 }
212
213 /**
214 * Gets the node-tuple source for this query.
215 *
216 * @return Tx_Extbase_Persistence_QOM_SourceInterface the node-tuple source; non-null
217 */
218 public function getSource() {
219 return $this->source;
220 }
221
222 /**
223 * Gets the constraint for this query.
224 *
225 * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint, or null if none
226 */
227 public function getConstraint() {
228 return $this->constraint;
229 }
230
231 /**
232 * Gets the orderings for this query.
233 *
234 * @return array an array of zero or more Tx_Extbase_Persistence_QOM_OrderingInterface; non-null
235 */
236 public function getOrderings() {
237 return $this->orderings;
238 }
239
240 /**
241 * Gets the columns for this query.
242 *
243 * @return array an array of zero or more Tx_Extbase_Persistence_QOM_ColumnInterface; non-null
244 */
245 public function getColumns() {
246 return $this->columns;
247 }
248
249 /**
250 * Binds the given value to the variable named $varName.
251 *
252 * @param string $varName name of variable in query
253 * @param Tx_Extbase_Persistence_ValueInterface $value value to bind
254 * @return void
255 * @throws InvalidArgumentException if $varName is not a valid variable in this query.
256 * @throws RepositoryException if an error occurs.
257 */
258 public function bindValue($varName, Tx_Extbase_Persistence_ValueInterface $value) {
259 if (array_key_exists($varName, $this->boundVariables) === FALSE) {
260 throw new InvalidArgumentException('Invalid variable name "' . $varName . '" given to bindValue.', 1217241834);
261 }
262 $this->boundVariables[$varName] = $value->getString();
263 }
264
265 /**
266 * Returns the values of all bound variables.
267 *
268 * @return array()
269 */
270 public function getBoundVariableValues() {
271 return $this->boundVariables;
272 }
273
274 /**
275 * Executes this query and returns a QueryResult object.
276 *
277 * @return Tx_Extbase_Persistence_QueryResultInterface A QueryResult object
278 */
279 public function execute() {
280 return t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryResult', $this->storageBackend->getRows($this));
281 }
282
283 /**
284 * Executes this query and returns the number of tuples matching the query.
285 *
286 * @return int The number of tuples matching the query
287 */
288 public function count() {
289 return $this->storageBackend->countRows($this);
290 }
291
292 /**
293 * Returns the statement defined for this query.
294 * If the language of this query is string-based (like JCR-SQL2), this method
295 * will return the statement that was used to create this query.
296 *
297 * If the language of this query is JCR-JQOM, this method will return the
298 * JCR-SQL2 equivalent of the JCR-JQOM object tree.
299 *
300 * This is the standard serialization of JCR-JQOM and is also the string stored
301 * in the jcr:statement property if the query is persisted. See storeAsNode($absPath).
302 *
303 * @return string the query statement.
304 */
305 public function getStatement() {
306 $this->storageBackend->getStatement($this);
307 }
308
309 }
310 ?>