2 /***************************************************************
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
8 * This class is a backport of the corresponding class of FLOW3.
9 * All credits go to the v5 team.
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.
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
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.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
29 * A query in the JCR query object model.
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.
34 * A query consists of:
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
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.
55 * The query object model representation of a query is created by factory methods in the QueryObjectModelFactory.
58 * @subpackage Persistence\QOM
59 * @version $Id: QueryObjectModel.php 1877 2009-02-05 11:29:07Z k-fish $
62 class Tx_Extbase_Persistence_QOM_QueryObjectModel
implements Tx_Extbase_Persistence_QOM_QueryObjectModelInterface
{
65 * @var Tx_Extbase_Persistence_DataMapper
67 protected $dataMapper;
70 * @var Tx_Extbase_Persistence_QOM_SourceInterface
75 * @var Tx_Extbase_Persistence_QOM_ConstraintInterface
77 protected $constraint;
90 * @var Tx_Extbase_Persistence_Storage_BackendInterface
92 protected $storageBackend;
107 protected $boundVariables = array();
111 * @var Tx_Extbase_Persistence_QuerySettingsInterface
113 protected $querySettings;
116 * Constructs this QueryObjectModel instance
118 * @param Tx_Extbase_Persistence_QOM_SourceInterface $selectorOrSource
119 * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint (null if none)
120 * @param array $orderings
121 * @param array $columns
123 public function __construct(Tx_Extbase_Persistence_QOM_SourceInterface
$selectorOrSource, $constraint, array $orderings = array(), array $columns = array()) {
124 $this->source
= $selectorOrSource;
125 $this->constraint
= $constraint;
126 $this->orderings
= $orderings;
127 $this->columns
= $columns;
129 if ($this->constraint
!== NULL) {
130 $this->constraint
->collectBoundVariableNames($this->boundVariables
);
135 * Injects the StorageBackend
137 * @param Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend
140 public function injectStorageBackend(Tx_Extbase_Persistence_Storage_BackendInterface
$storageBackend) {
141 $this->storageBackend
= $storageBackend;
145 * Injects the Data Mapper to map nodes to objects
147 * @param Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper
150 public function injectDataMapper(Tx_Extbase_Persistence_Mapper_DataMapper
$dataMapper) {
151 $this->dataMapper
= $dataMapper;
155 * Sets the Query Settings. These Query settings must match the settings expected by
156 * the specific Storage Backend.
158 * @param Tx_Extbase_Persistence_QuerySettingsInterface $querySettings The Query Settings
161 public function setQuerySettings(Tx_Extbase_Persistence_QuerySettingsInterface
$querySettings) {
162 $this->querySettings
= $querySettings;
166 * Returns the Query Settings.
168 * @return Tx_Extbase_Persistence_QuerySettingsInterface $querySettings The Query Settings
170 public function getQuerySettings() {
171 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);
172 return $this->querySettings
;
176 * Sets the maximum size of the result set to limit.
178 * @param integer $limit
181 public function setLimit($limit) {
182 if ($limit < 1 ||
!is_int($limit)) {
183 throw new InvalidArgumentException('setLimit() accepts only integers greater than 0.', 1217244746);
185 $this->limit
= $limit;
189 * Returns the maximum size of the result set.
193 public function getLimit() {
198 * Sets the start offset of the result set to offset.
200 * @param integer $offset
203 public function setOffset($offset) {
204 if ($offset < 0 ||
!is_int($offset)) {
205 throw new InvalidArgumentException('setOffset() accepts only integers greater than or equal to 0.', 1217245454);
207 $this->offset
= $offset;
211 * Returns the start offset of the result set.
215 public function getOffset() {
216 return $this->offset
;
220 * Returns the class name the query handles
222 * @return string The class name
224 public function getSelectorName() {
225 $this->source
->getSelectorName();
229 * Gets the node-tuple source for this query.
231 * @return Tx_Extbase_Persistence_QOM_SourceInterface the node-tuple source; non-null
233 public function getSource() {
234 return $this->source
;
238 * Gets the constraint for this query.
240 * @return Tx_Extbase_Persistence_QOM_ConstraintInterface the constraint, or null if none
242 public function getConstraint() {
243 return $this->constraint
;
247 * Gets the orderings for this query.
249 * @return array an array of zero or more Tx_Extbase_Persistence_QOM_OrderingInterface; non-null
251 public function getOrderings() {
252 return $this->orderings
;
256 * Gets the columns for this query.
258 * @return array an array of zero or more Tx_Extbase_Persistence_QOM_ColumnInterface; non-null
260 public function getColumns() {
261 return $this->columns
;
265 * Binds the given value to the variable named $varName.
267 * @param string $varName name of variable in query
268 * @param Tx_Extbase_Persistence_ValueInterface $value value to bind
270 * @throws InvalidArgumentException if $varName is not a valid variable in this query.
271 * @throws RepositoryException if an error occurs.
273 public function bindValue($varName, Tx_Extbase_Persistence_ValueInterface
$value) {
274 if (array_key_exists($varName, $this->boundVariables
) === FALSE) {
275 throw new InvalidArgumentException('Invalid variable name "' . $varName . '" given to bindValue.', 1217241834);
277 $this->boundVariables
[$varName] = $value->getString();
281 * Returns the values of all bound variables.
285 public function getBoundVariableValues() {
286 return $this->boundVariables
;
290 * Executes this query and returns a QueryResult object.
292 * @return Tx_Extbase_Persistence_QueryResultInterface A QueryResult object
294 public function execute() {
295 return t3lib_div
::makeInstance('Tx_Extbase_Persistence_QueryResult', $this->storageBackend
->getRows($this));
299 * Returns the statement defined for this query.
300 * If the language of this query is string-based (like JCR-SQL2), this method
301 * will return the statement that was used to create this query.
303 * If the language of this query is JCR-JQOM, this method will return the
304 * JCR-SQL2 equivalent of the JCR-JQOM object tree.
306 * This is the standard serialization of JCR-JQOM and is also the string stored
307 * in the jcr:statement property if the query is persisted. See storeAsNode($absPath).
309 * @return string the query statement.
311 public function getStatement() {
312 $this->storageBackend
->parseQuery($this);