|
1 <?php |
|
2 /* |
|
3 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
4 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
5 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
6 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
7 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
8 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
9 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
10 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
11 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
12 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
13 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
14 * |
|
15 * This software consists of voluntary contributions made by many individuals |
|
16 * and is licensed under the LGPL. For more information, see |
|
17 * <http://www.doctrine-project.org>. |
|
18 */ |
|
19 |
|
20 namespace Doctrine\ORM\Query; |
|
21 |
|
22 /** |
|
23 * A ResultSetMapping describes how a result set of an SQL query maps to a Doctrine result. |
|
24 * |
|
25 * IMPORTANT NOTE: |
|
26 * The properties of this class are only public for fast internal READ access and to (drastically) |
|
27 * reduce the size of serialized instances for more effective caching due to better (un-)serialization |
|
28 * performance. |
|
29 * |
|
30 * <b>Users should use the public methods.</b> |
|
31 * |
|
32 * @author Roman Borschel <roman@code-factory.org> |
|
33 * @since 2.0 |
|
34 * @todo Think about whether the number of lookup maps can be reduced. |
|
35 */ |
|
36 class ResultSetMapping |
|
37 { |
|
38 /** |
|
39 * Whether the result is mixed (contains scalar values together with field values). |
|
40 * |
|
41 * @ignore |
|
42 * @var boolean |
|
43 */ |
|
44 public $isMixed = false; |
|
45 /** |
|
46 * Maps alias names to class names. |
|
47 * |
|
48 * @ignore |
|
49 * @var array |
|
50 */ |
|
51 public $aliasMap = array(); |
|
52 /** |
|
53 * Maps alias names to related association field names. |
|
54 * |
|
55 * @ignore |
|
56 * @var array |
|
57 */ |
|
58 public $relationMap = array(); |
|
59 /** |
|
60 * Maps alias names to parent alias names. |
|
61 * |
|
62 * @ignore |
|
63 * @var array |
|
64 */ |
|
65 public $parentAliasMap = array(); |
|
66 /** |
|
67 * Maps column names in the result set to field names for each class. |
|
68 * |
|
69 * @ignore |
|
70 * @var array |
|
71 */ |
|
72 public $fieldMappings = array(); |
|
73 /** |
|
74 * Maps column names in the result set to the alias/field name to use in the mapped result. |
|
75 * |
|
76 * @ignore |
|
77 * @var array |
|
78 */ |
|
79 public $scalarMappings = array(); |
|
80 /** |
|
81 * Maps column names of meta columns (foreign keys, discriminator columns, ...) to field names. |
|
82 * |
|
83 * @ignore |
|
84 * @var array |
|
85 */ |
|
86 public $metaMappings = array(); |
|
87 /** |
|
88 * Maps column names in the result set to the alias they belong to. |
|
89 * |
|
90 * @ignore |
|
91 * @var array |
|
92 */ |
|
93 public $columnOwnerMap = array(); |
|
94 /** |
|
95 * List of columns in the result set that are used as discriminator columns. |
|
96 * |
|
97 * @ignore |
|
98 * @var array |
|
99 */ |
|
100 public $discriminatorColumns = array(); |
|
101 /** |
|
102 * Maps alias names to field names that should be used for indexing. |
|
103 * |
|
104 * @ignore |
|
105 * @var array |
|
106 */ |
|
107 public $indexByMap = array(); |
|
108 /** |
|
109 * Map from column names to class names that declare the field the column is mapped to. |
|
110 * |
|
111 * @ignore |
|
112 * @var array |
|
113 */ |
|
114 public $declaringClasses = array(); |
|
115 |
|
116 /** |
|
117 * This is necessary to hydrate derivate foreign keys correctly. |
|
118 * |
|
119 * @var array |
|
120 */ |
|
121 public $isIdentifierColumn = array(); |
|
122 |
|
123 /** |
|
124 * Adds an entity result to this ResultSetMapping. |
|
125 * |
|
126 * @param string $class The class name of the entity. |
|
127 * @param string $alias The alias for the class. The alias must be unique among all entity |
|
128 * results or joined entity results within this ResultSetMapping. |
|
129 * @todo Rename: addRootEntity |
|
130 */ |
|
131 public function addEntityResult($class, $alias) |
|
132 { |
|
133 $this->aliasMap[$alias] = $class; |
|
134 } |
|
135 |
|
136 /** |
|
137 * Sets a discriminator column for an entity result or joined entity result. |
|
138 * The discriminator column will be used to determine the concrete class name to |
|
139 * instantiate. |
|
140 * |
|
141 * @param string $alias The alias of the entity result or joined entity result the discriminator |
|
142 * column should be used for. |
|
143 * @param string $discrColumn The name of the discriminator column in the SQL result set. |
|
144 * @todo Rename: addDiscriminatorColumn |
|
145 */ |
|
146 public function setDiscriminatorColumn($alias, $discrColumn) |
|
147 { |
|
148 $this->discriminatorColumns[$alias] = $discrColumn; |
|
149 $this->columnOwnerMap[$discrColumn] = $alias; |
|
150 } |
|
151 |
|
152 /** |
|
153 * Sets a field to use for indexing an entity result or joined entity result. |
|
154 * |
|
155 * @param string $alias The alias of an entity result or joined entity result. |
|
156 * @param string $fieldName The name of the field to use for indexing. |
|
157 */ |
|
158 public function addIndexBy($alias, $fieldName) |
|
159 { |
|
160 $this->indexByMap[$alias] = $fieldName; |
|
161 } |
|
162 |
|
163 /** |
|
164 * Checks whether an entity result or joined entity result with a given alias has |
|
165 * a field set for indexing. |
|
166 * |
|
167 * @param string $alias |
|
168 * @return boolean |
|
169 * @todo Rename: isIndexed($alias) |
|
170 */ |
|
171 public function hasIndexBy($alias) |
|
172 { |
|
173 return isset($this->indexByMap[$alias]); |
|
174 } |
|
175 |
|
176 /** |
|
177 * Checks whether the column with the given name is mapped as a field result |
|
178 * as part of an entity result or joined entity result. |
|
179 * |
|
180 * @param string $columnName The name of the column in the SQL result set. |
|
181 * @return boolean |
|
182 * @todo Rename: isField |
|
183 */ |
|
184 public function isFieldResult($columnName) |
|
185 { |
|
186 return isset($this->fieldMappings[$columnName]); |
|
187 } |
|
188 |
|
189 /** |
|
190 * Adds a field to the result that belongs to an entity or joined entity. |
|
191 * |
|
192 * @param string $alias The alias of the root entity or joined entity to which the field belongs. |
|
193 * @param string $columnName The name of the column in the SQL result set. |
|
194 * @param string $fieldName The name of the field on the declaring class. |
|
195 * @param string $declaringClass The name of the class that declares/owns the specified field. |
|
196 * When $alias refers to a superclass in a mapped hierarchy but |
|
197 * the field $fieldName is defined on a subclass, specify that here. |
|
198 * If not specified, the field is assumed to belong to the class |
|
199 * designated by $alias. |
|
200 * @todo Rename: addField |
|
201 */ |
|
202 public function addFieldResult($alias, $columnName, $fieldName, $declaringClass = null) |
|
203 { |
|
204 // column name (in result set) => field name |
|
205 $this->fieldMappings[$columnName] = $fieldName; |
|
206 // column name => alias of owner |
|
207 $this->columnOwnerMap[$columnName] = $alias; |
|
208 // field name => class name of declaring class |
|
209 $this->declaringClasses[$columnName] = $declaringClass ?: $this->aliasMap[$alias]; |
|
210 if ( ! $this->isMixed && $this->scalarMappings) { |
|
211 $this->isMixed = true; |
|
212 } |
|
213 } |
|
214 |
|
215 /** |
|
216 * Adds a joined entity result. |
|
217 * |
|
218 * @param string $class The class name of the joined entity. |
|
219 * @param string $alias The unique alias to use for the joined entity. |
|
220 * @param string $parentAlias The alias of the entity result that is the parent of this joined result. |
|
221 * @param object $relation The association field that connects the parent entity result with the joined entity result. |
|
222 * @todo Rename: addJoinedEntity |
|
223 */ |
|
224 public function addJoinedEntityResult($class, $alias, $parentAlias, $relation) |
|
225 { |
|
226 $this->aliasMap[$alias] = $class; |
|
227 $this->parentAliasMap[$alias] = $parentAlias; |
|
228 $this->relationMap[$alias] = $relation; |
|
229 } |
|
230 |
|
231 /** |
|
232 * Adds a scalar result mapping. |
|
233 * |
|
234 * @param string $columnName The name of the column in the SQL result set. |
|
235 * @param string $alias The result alias with which the scalar result should be placed in the result structure. |
|
236 * @todo Rename: addScalar |
|
237 */ |
|
238 public function addScalarResult($columnName, $alias) |
|
239 { |
|
240 $this->scalarMappings[$columnName] = $alias; |
|
241 if ( ! $this->isMixed && $this->fieldMappings) { |
|
242 $this->isMixed = true; |
|
243 } |
|
244 } |
|
245 |
|
246 /** |
|
247 * Checks whether a column with a given name is mapped as a scalar result. |
|
248 * |
|
249 * @param string $columName The name of the column in the SQL result set. |
|
250 * @return boolean |
|
251 * @todo Rename: isScalar |
|
252 */ |
|
253 public function isScalarResult($columnName) |
|
254 { |
|
255 return isset($this->scalarMappings[$columnName]); |
|
256 } |
|
257 |
|
258 /** |
|
259 * Gets the name of the class of an entity result or joined entity result, |
|
260 * identified by the given unique alias. |
|
261 * |
|
262 * @param string $alias |
|
263 * @return string |
|
264 */ |
|
265 public function getClassName($alias) |
|
266 { |
|
267 return $this->aliasMap[$alias]; |
|
268 } |
|
269 |
|
270 /** |
|
271 * Gets the field alias for a column that is mapped as a scalar value. |
|
272 * |
|
273 * @param string $columnName The name of the column in the SQL result set. |
|
274 * @return string |
|
275 */ |
|
276 public function getScalarAlias($columnName) |
|
277 { |
|
278 return $this->scalarMappings[$columnName]; |
|
279 } |
|
280 |
|
281 /** |
|
282 * Gets the name of the class that owns a field mapping for the specified column. |
|
283 * |
|
284 * @param string $columnName |
|
285 * @return string |
|
286 */ |
|
287 public function getDeclaringClass($columnName) |
|
288 { |
|
289 return $this->declaringClasses[$columnName]; |
|
290 } |
|
291 |
|
292 /** |
|
293 * |
|
294 * @param string $alias |
|
295 * @return AssociationMapping |
|
296 */ |
|
297 public function getRelation($alias) |
|
298 { |
|
299 return $this->relationMap[$alias]; |
|
300 } |
|
301 |
|
302 /** |
|
303 * |
|
304 * @param string $alias |
|
305 * @return boolean |
|
306 */ |
|
307 public function isRelation($alias) |
|
308 { |
|
309 return isset($this->relationMap[$alias]); |
|
310 } |
|
311 |
|
312 /** |
|
313 * Gets the alias of the class that owns a field mapping for the specified column. |
|
314 * |
|
315 * @param string $columnName |
|
316 * @return string |
|
317 */ |
|
318 public function getEntityAlias($columnName) |
|
319 { |
|
320 return $this->columnOwnerMap[$columnName]; |
|
321 } |
|
322 |
|
323 /** |
|
324 * Gets the parent alias of the given alias. |
|
325 * |
|
326 * @param string $alias |
|
327 * @return string |
|
328 */ |
|
329 public function getParentAlias($alias) |
|
330 { |
|
331 return $this->parentAliasMap[$alias]; |
|
332 } |
|
333 |
|
334 /** |
|
335 * Checks whether the given alias has a parent alias. |
|
336 * |
|
337 * @param string $alias |
|
338 * @return boolean |
|
339 */ |
|
340 public function hasParentAlias($alias) |
|
341 { |
|
342 return isset($this->parentAliasMap[$alias]); |
|
343 } |
|
344 |
|
345 /** |
|
346 * Gets the field name for a column name. |
|
347 * |
|
348 * @param string $columnName |
|
349 * @return string |
|
350 */ |
|
351 public function getFieldName($columnName) |
|
352 { |
|
353 return $this->fieldMappings[$columnName]; |
|
354 } |
|
355 |
|
356 /** |
|
357 * |
|
358 * @return array |
|
359 */ |
|
360 public function getAliasMap() |
|
361 { |
|
362 return $this->aliasMap; |
|
363 } |
|
364 |
|
365 /** |
|
366 * Gets the number of different entities that appear in the mapped result. |
|
367 * |
|
368 * @return integer |
|
369 */ |
|
370 public function getEntityResultCount() |
|
371 { |
|
372 return count($this->aliasMap); |
|
373 } |
|
374 |
|
375 /** |
|
376 * Checks whether this ResultSetMapping defines a mixed result. |
|
377 * Mixed results can only occur in object and array (graph) hydration. In such a |
|
378 * case a mixed result means that scalar values are mixed with objects/array in |
|
379 * the result. |
|
380 * |
|
381 * @return boolean |
|
382 */ |
|
383 public function isMixedResult() |
|
384 { |
|
385 return $this->isMixed; |
|
386 } |
|
387 |
|
388 /** |
|
389 * Adds a meta column (foreign key or discriminator column) to the result set. |
|
390 * |
|
391 * @param string $alias |
|
392 * @param string $columnName |
|
393 * @param string $fieldName |
|
394 * @param bool |
|
395 */ |
|
396 public function addMetaResult($alias, $columnName, $fieldName, $isIdentifierColumn = false) |
|
397 { |
|
398 $this->metaMappings[$columnName] = $fieldName; |
|
399 $this->columnOwnerMap[$columnName] = $alias; |
|
400 if ($isIdentifierColumn) { |
|
401 $this->isIdentifierColumn[$alias][$columnName] = true; |
|
402 } |
|
403 } |
|
404 } |