http://phing.info/

Source Code Coverage

Designed for use with PHPUnit2, Xdebug and Phing.

Methods: 16 LOC: 307 Statements: 67

Source file Statements Methods Total coverage
Query.php 97.0% 100.0% 97.6%
   
1
<?php
2
/**
3
 * Xyster Framework
4
 *
5
 * This source file is subject to the new BSD license that is bundled
6
 * with this package in the file LICENSE.txt.
7
 * It is also available through the world-wide-web at this URL:
8
 * http://www.opensource.org/licenses/bsd-license.php
9
 *
10
 * @category  Xyster
11
 * @package   Xyster_Orm
12
 * @copyright Copyright (c) 2007-2008 Irrational Logic (http://irrationallogic.net)
13
 * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
14
 * @version   $Id: Query.php 220 2008-02-09 18:04:52Z doublecompile $
15
 */
16
/**
17
 * @see Xyster_Data_Sort_Clause
18
 */
19 1
require_once 'Xyster/Data/Sort/Clause.php';
20
/**
21
 * A query object
22
 *
23
 * @category  Xyster
24
 * @package   Xyster_Orm
25
 * @copyright Copyright (c) 2007-2008 Irrational Logic (http://irrationallogic.net)
26
 * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
27
 */
28
class Xyster_Orm_Query
29
{
30
    const WHERE = 'where';
31
    const ORDER = 'order';
32
    const LIMIT = 'limit';
33
    const OFFSET = 'offset';
34
35
    /**
36
     * The entity being queried
37
     *
38
     * @var string
39
     */
40
    protected $_class = '';
41
42
    /**
43
     * The parts of the query
44
     *
45
     * @var array
46
     */
47
    protected $_parts = array();
48
49
    /**
50
     * The parts of the query that can be used in the backend
51
     *
52
     * @var array
53
     */
54
    protected $_backend = array();
55
56
    /**
57
     * The orm manager
58
     *
59
     * @var Xyster_Orm_Manager
60
     */
61
    protected $_manager;
62
63
    /**
64
     * The entity meta
65
     *
66
     * @var Xyster_Orm_Entity_Meta
67
     */
68
    protected $_meta;
69
70
    /**
71
     * The parts of the query that must be used at runtime
72
     *
73
     * @var array
74
     */
75
    protected $_runtime = array();
76
77
    /**
78
     * Creates a new query object
79
     *
80
     * @param string $class  The entity to query
81
     */
82
    public function __construct( $class, Xyster_Orm_Manager $manager )
83
    {
84 51
        $this->_class = $class;
85 51
        $this->_manager = $manager;
86 51
        $this->_initParts();
87 51
        $this->_meta = $manager->getMapperFactory()->getEntityMeta($class);
88
    }
89
90
    /**
91
     * Executes the query
92
     *
93
     * @return Xyster_Orm_Set
94
     */
95
    public function execute()
96
    {
97 5
        $map = $this->_manager->getMapperFactory()->get($this->_class);
98
99
        // execute the query in the backend
100 5
		$set = $this->_manager->executeQuery($this);
101
102
        // apply any runtime filters to the entity set
103 5
		if ( count($this->_runtime[self::WHERE]) ) {
104 1
    		$set->filter(Xyster_Data_Criterion::fromArray('AND', $this->_runtime[self::WHERE]));
105 1
		}
106
107
		// if the query is runtime, enforce the offset and limit
108 5
		if ( ( $this->_parts[self::LIMIT] || $this->_parts[self::OFFSET] )
109 5
		    && $this->isRuntime() ) {
110 1
			$entities = $map->getSet();
111 1
			$offset = 0;
112 1
			foreach( $set as $entity ) {
113 1
				if ( $offset < $this->_parts[self::OFFSET] ) {
114 1
				    $offset++;
115 1
				} else {
116 1
				    $entities->add($entity);
117
				}
118 1
				if ( $this->_parts[self::LIMIT] && count($entities) == $this->_parts[self::LIMIT] ) {
119 1
				    break;
120 0
				}
121 1
			}
122 1
			$set = $entities;
123 1
		}
124
125
		// apply any runtime sort ordering to the entity set
126 5
		if ( $this->_runtime[self::ORDER] ) {
127 1
			$set->sortBy($this->_parts[self::ORDER]);
128 1
		}
129 5
		return $set;
130
    }
131
132
    /**
133
     * Gets the criteria that can be run in the backend
134
     *
135
     * @return array
136
     */
137
    public function getBackendWhere()
138
    {
139 27
        return $this->_backend[self::WHERE];
140
    }
141
142
    /**
143
     * Gets the entity class being queried
144
     *
145
     * @return string the entity class name
146
     */
147
    public function getFrom()
148
    {
149 25
        return $this->_class;
150
    }
151
152
    /**
153
     * Gets the maximum number of results to be returned
154
     *
155
     * @return int the maximum result count
156
     */
157
    public function getLimit()
158
    {
159 14
        return $this->getPart(self::LIMIT);
160
    }
161
162
    /**
163
     * Gets the starting point in the results
164
     *
165
     * @return int the offset starting point
166
     */
167
    public function getOffset()
168
    {
169 10
        return $this->getPart(self::OFFSET);
170
    }
171
172
    /**
173
     * Gets the order clause (an array of {@link Xyster_Data_Sort} objects)
174
     *
175
     * @return Xyster_Data_Sort_Clause
176
     */
177
    public function getOrder()
178
    {
179 28
        return $this->getPart(self::ORDER);
180
    }
181
182
    /**
183
     * Gets a part of the query
184
     *
185
     * @param string $part one of the class constants
186
     * @return mixed
187
     */
188
    public function getPart( $part )
189
    {
190 45
        return ( array_key_exists($part, $this->_parts) ) ?
191 45
            $this->_parts[$part] : null;
192
    }
193
194
    /**
195
     * Gets the where clause (an array of {@link Xyster_Data_Criterion} objects)
196
     *
197
     * @return array
198
     */
199
    public function getWhere()
200
    {
201 7
        return $this->getPart(self::WHERE);
202
    }
203
204
    /**
205
     * Gets whether this query has an order clause that evaluates at runtime
206
     *
207
     * @return boolean
208
     */
209
    public function hasRuntimeOrder()
210
    {
211 37
        return (bool) $this->_runtime[self::ORDER];
212
    }
213
214
    /**
215
     * Gets whether this query has a where clause that evaluates at runtime
216
     *
217
     * @return boolean
218
     */
219
    public function hasRuntimeWhere()
220
    {
221 32
        return count($this->_runtime[self::WHERE]) > 0;
222
    }
223
224
    /**
225
     * Gets whether this query has parts that are evaluated at runtime
226
     *
227
     * @return boolean
228
     */
229
    public function isRuntime()
230
    {
231 37
        return $this->hasRuntimeOrder() || $this->hasRuntimeWhere();
232
    }
233
234
    /**
235
     * Impose a maximum number of records to return and a number to skip
236
     *
237
     * @param int $limit The maximum number of records to return
238
     * @param int $offset The number of records to skip
239
     * @return Xyster_Orm_Query provides a fluent interface
240
     */
241
    public function limit( $limit, $offset=0 )
242
    {
243 15
        $this->_parts[self::LIMIT] = intval($limit);
244 15
        $this->_parts[self::OFFSET] = intval($offset);
245 15
        return $this;
246
    }
247
248
    /**
249
     * Adds a sorting to the results
250
     *
251
     * @param Xyster_Data_Sort $order
252
     * @return Xyster_Orm_Query provides a fluent interface
253
     */
254
    public function order( Xyster_Data_Sort $order )
255
    {
256 17
    	$this->_meta->assertValidField($order->getField());
257 17
        $this->_runtime[self::ORDER] |= $this->_meta->isRuntime($order);
258
259 17
        $this->getOrder()->add($order);
260
261 17
        return $this;
262
    }
263
264
    /**
265
     * Adds a criterion to the selection
266
     *
267
     * @param Xyster_Data_Criterion $where
268
     * @return Xyster_Orm_Query provides a fluent interface
269
     */
270
    public function where( Xyster_Data_Criterion $where )
271
    {
272 30
        foreach( Xyster_Data_Criterion::getFields($where) as $field ) {
273 30
            if ( $field instanceof Xyster_Data_Field_Aggregate ) {
274 2
                require_once 'Xyster/Orm/Query/Exception.php';
275 2
                throw new Xyster_Orm_Query_Exception('Aggregated fields are not allowed in this query');
276 0
            }
277 28
            $this->_meta->assertValidField($field);
278 28
        }
279
280 28
        if ( $this->_meta->isRuntime($where) ) {
281 11
            $this->_runtime[self::WHERE][] = $where;
282 11
        } else {
283 25
            $this->_backend[self::WHERE][] = $where;
284
        }
285
286 28
        $this->_parts[self::WHERE][] = $where;
287
288 28
        return $this;
289
    }
290
291
    /**
292
     * Initializes the parts container
293
     *
294
     */
295
    protected function _initParts()
296
    {
297 51
        $this->_parts[self::LIMIT] = 0;
298 51
        $this->_parts[self::OFFSET] = 0;
299 51
        $this->_parts[self::WHERE] = array();
300 51
        $this->_parts[self::ORDER] = new Xyster_Data_Sort_Clause;
301
302 51
        $this->_runtime[self::WHERE] = array();
303 51
        $this->_runtime[self::ORDER] = false;
304
305 51
        $this->_backend[self::WHERE] = array();
306
    }
307
}


Report generated at 2008-03-05T18:27:43-05:00