summaryrefslogtreecommitdiff
path: root/vendor/doctrine/orm/src/Query/ResultSetMapping.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/doctrine/orm/src/Query/ResultSetMapping.php')
-rw-r--r--vendor/doctrine/orm/src/Query/ResultSetMapping.php547
1 files changed, 547 insertions, 0 deletions
diff --git a/vendor/doctrine/orm/src/Query/ResultSetMapping.php b/vendor/doctrine/orm/src/Query/ResultSetMapping.php
new file mode 100644
index 0000000..612474d
--- /dev/null
+++ b/vendor/doctrine/orm/src/Query/ResultSetMapping.php
@@ -0,0 +1,547 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\ORM\Query;
6
7use function count;
8
9/**
10 * A ResultSetMapping describes how a result set of an SQL query maps to a Doctrine result.
11 *
12 * IMPORTANT NOTE:
13 * The properties of this class are only public for fast internal READ access and to (drastically)
14 * reduce the size of serialized instances for more effective caching due to better (un-)serialization
15 * performance.
16 *
17 * <b>Users should use the public methods.</b>
18 *
19 * @todo Think about whether the number of lookup maps can be reduced.
20 */
21class ResultSetMapping
22{
23 /**
24 * Whether the result is mixed (contains scalar values together with field values).
25 *
26 * @ignore
27 */
28 public bool $isMixed = false;
29
30 /**
31 * Whether the result is a select statement.
32 *
33 * @ignore
34 */
35 public bool $isSelect = true;
36
37 /**
38 * Maps alias names to class names.
39 *
40 * @ignore
41 * @psalm-var array<string, class-string>
42 */
43 public array $aliasMap = [];
44
45 /**
46 * Maps alias names to related association field names.
47 *
48 * @ignore
49 * @psalm-var array<string, string>
50 */
51 public array $relationMap = [];
52
53 /**
54 * Maps alias names to parent alias names.
55 *
56 * @ignore
57 * @psalm-var array<string, string>
58 */
59 public array $parentAliasMap = [];
60
61 /**
62 * Maps column names in the result set to field names for each class.
63 *
64 * @ignore
65 * @psalm-var array<string, string>
66 */
67 public array $fieldMappings = [];
68
69 /**
70 * Maps column names in the result set to the alias/field name to use in the mapped result.
71 *
72 * @ignore
73 * @psalm-var array<string, string|int>
74 */
75 public array $scalarMappings = [];
76
77 /**
78 * Maps scalar columns to enums
79 *
80 * @ignore
81 * @psalm-var array<string, string>
82 */
83 public $enumMappings = [];
84
85 /**
86 * Maps column names in the result set to the alias/field type to use in the mapped result.
87 *
88 * @ignore
89 * @psalm-var array<string, string>
90 */
91 public array $typeMappings = [];
92
93 /**
94 * Maps entities in the result set to the alias name to use in the mapped result.
95 *
96 * @ignore
97 * @psalm-var array<string, string|null>
98 */
99 public array $entityMappings = [];
100
101 /**
102 * Maps column names of meta columns (foreign keys, discriminator columns, ...) to field names.
103 *
104 * @ignore
105 * @psalm-var array<string, string>
106 */
107 public array $metaMappings = [];
108
109 /**
110 * Maps column names in the result set to the alias they belong to.
111 *
112 * @ignore
113 * @psalm-var array<string, string>
114 */
115 public array $columnOwnerMap = [];
116
117 /**
118 * List of columns in the result set that are used as discriminator columns.
119 *
120 * @ignore
121 * @psalm-var array<string, string>
122 */
123 public array $discriminatorColumns = [];
124
125 /**
126 * Maps alias names to field names that should be used for indexing.
127 *
128 * @ignore
129 * @psalm-var array<string, string>
130 */
131 public array $indexByMap = [];
132
133 /**
134 * Map from column names to class names that declare the field the column is mapped to.
135 *
136 * @ignore
137 * @psalm-var array<string, class-string>
138 */
139 public array $declaringClasses = [];
140
141 /**
142 * This is necessary to hydrate derivate foreign keys correctly.
143 *
144 * @psalm-var array<string, array<string, bool>>
145 */
146 public array $isIdentifierColumn = [];
147
148 /**
149 * Maps column names in the result set to field names for each new object expression.
150 *
151 * @psalm-var array<string, array<string, mixed>>
152 */
153 public array $newObjectMappings = [];
154
155 /**
156 * Maps metadata parameter names to the metadata attribute.
157 *
158 * @psalm-var array<int|string, string>
159 */
160 public array $metadataParameterMapping = [];
161
162 /**
163 * Contains query parameter names to be resolved as discriminator values
164 *
165 * @psalm-var array<string, string>
166 */
167 public array $discriminatorParameters = [];
168
169 /**
170 * Adds an entity result to this ResultSetMapping.
171 *
172 * @param string $class The class name of the entity.
173 * @param string $alias The alias for the class. The alias must be unique among all entity
174 * results or joined entity results within this ResultSetMapping.
175 * @param string|null $resultAlias The result alias with which the entity result should be
176 * placed in the result structure.
177 * @psalm-param class-string $class
178 *
179 * @return $this
180 *
181 * @todo Rename: addRootEntity
182 */
183 public function addEntityResult(string $class, string $alias, string|null $resultAlias = null): static
184 {
185 $this->aliasMap[$alias] = $class;
186 $this->entityMappings[$alias] = $resultAlias;
187
188 if ($resultAlias !== null) {
189 $this->isMixed = true;
190 }
191
192 return $this;
193 }
194
195 /**
196 * Sets a discriminator column for an entity result or joined entity result.
197 * The discriminator column will be used to determine the concrete class name to
198 * instantiate.
199 *
200 * @param string $alias The alias of the entity result or joined entity result the discriminator
201 * column should be used for.
202 * @param string $discrColumn The name of the discriminator column in the SQL result set.
203 *
204 * @return $this
205 *
206 * @todo Rename: addDiscriminatorColumn
207 */
208 public function setDiscriminatorColumn(string $alias, string $discrColumn): static
209 {
210 $this->discriminatorColumns[$alias] = $discrColumn;
211 $this->columnOwnerMap[$discrColumn] = $alias;
212
213 return $this;
214 }
215
216 /**
217 * Sets a field to use for indexing an entity result or joined entity result.
218 *
219 * @param string $alias The alias of an entity result or joined entity result.
220 * @param string $fieldName The name of the field to use for indexing.
221 *
222 * @return $this
223 */
224 public function addIndexBy(string $alias, string $fieldName): static
225 {
226 $found = false;
227
228 foreach ([...$this->metaMappings, ...$this->fieldMappings] as $columnName => $columnFieldName) {
229 if (! ($columnFieldName === $fieldName && $this->columnOwnerMap[$columnName] === $alias)) {
230 continue;
231 }
232
233 $this->addIndexByColumn($alias, $columnName);
234 $found = true;
235
236 break;
237 }
238
239 /* TODO: check if this exception can be put back, for now it's gone because of assumptions made by some ORM internals
240 if ( ! $found) {
241 $message = sprintf(
242 'Cannot add index by for DQL alias %s and field %s without calling addFieldResult() for them before.',
243 $alias,
244 $fieldName
245 );
246
247 throw new \LogicException($message);
248 }
249 */
250
251 return $this;
252 }
253
254 /**
255 * Sets to index by a scalar result column name.
256 *
257 * @return $this
258 */
259 public function addIndexByScalar(string $resultColumnName): static
260 {
261 $this->indexByMap['scalars'] = $resultColumnName;
262
263 return $this;
264 }
265
266 /**
267 * Sets a column to use for indexing an entity or joined entity result by the given alias name.
268 *
269 * @return $this
270 */
271 public function addIndexByColumn(string $alias, string $resultColumnName): static
272 {
273 $this->indexByMap[$alias] = $resultColumnName;
274
275 return $this;
276 }
277
278 /**
279 * Checks whether an entity result or joined entity result with a given alias has
280 * a field set for indexing.
281 *
282 * @todo Rename: isIndexed($alias)
283 */
284 public function hasIndexBy(string $alias): bool
285 {
286 return isset($this->indexByMap[$alias]);
287 }
288
289 /**
290 * Checks whether the column with the given name is mapped as a field result
291 * as part of an entity result or joined entity result.
292 *
293 * @param string $columnName The name of the column in the SQL result set.
294 *
295 * @todo Rename: isField
296 */
297 public function isFieldResult(string $columnName): bool
298 {
299 return isset($this->fieldMappings[$columnName]);
300 }
301
302 /**
303 * Adds a field to the result that belongs to an entity or joined entity.
304 *
305 * @param string $alias The alias of the root entity or joined entity to which the field belongs.
306 * @param string $columnName The name of the column in the SQL result set.
307 * @param string $fieldName The name of the field on the declaring class.
308 * @param string|null $declaringClass The name of the class that declares/owns the specified field.
309 * When $alias refers to a superclass in a mapped hierarchy but
310 * the field $fieldName is defined on a subclass, specify that here.
311 * If not specified, the field is assumed to belong to the class
312 * designated by $alias.
313 * @psalm-param class-string|null $declaringClass
314 *
315 * @return $this
316 *
317 * @todo Rename: addField
318 */
319 public function addFieldResult(string $alias, string $columnName, string $fieldName, string|null $declaringClass = null): static
320 {
321 // column name (in result set) => field name
322 $this->fieldMappings[$columnName] = $fieldName;
323 // column name => alias of owner
324 $this->columnOwnerMap[$columnName] = $alias;
325 // field name => class name of declaring class
326 $this->declaringClasses[$columnName] = $declaringClass ?: $this->aliasMap[$alias];
327
328 if (! $this->isMixed && $this->scalarMappings) {
329 $this->isMixed = true;
330 }
331
332 return $this;
333 }
334
335 /**
336 * Adds a joined entity result.
337 *
338 * @param string $class The class name of the joined entity.
339 * @param string $alias The unique alias to use for the joined entity.
340 * @param string $parentAlias The alias of the entity result that is the parent of this joined result.
341 * @param string $relation The association field that connects the parent entity result
342 * with the joined entity result.
343 * @psalm-param class-string $class
344 *
345 * @return $this
346 *
347 * @todo Rename: addJoinedEntity
348 */
349 public function addJoinedEntityResult(string $class, string $alias, string $parentAlias, string $relation): static
350 {
351 $this->aliasMap[$alias] = $class;
352 $this->parentAliasMap[$alias] = $parentAlias;
353 $this->relationMap[$alias] = $relation;
354
355 return $this;
356 }
357
358 /**
359 * Adds a scalar result mapping.
360 *
361 * @param string $columnName The name of the column in the SQL result set.
362 * @param string|int $alias The result alias with which the scalar result should be placed in the result structure.
363 * @param string $type The column type
364 *
365 * @return $this
366 *
367 * @todo Rename: addScalar
368 */
369 public function addScalarResult(string $columnName, string|int $alias, string $type = 'string'): static
370 {
371 $this->scalarMappings[$columnName] = $alias;
372 $this->typeMappings[$columnName] = $type;
373
374 if (! $this->isMixed && $this->fieldMappings) {
375 $this->isMixed = true;
376 }
377
378 return $this;
379 }
380
381 /**
382 * Adds a scalar result mapping.
383 *
384 * @param string $columnName The name of the column in the SQL result set.
385 * @param string $enumType The enum type
386 *
387 * @return $this
388 */
389 public function addEnumResult(string $columnName, string $enumType): static
390 {
391 $this->enumMappings[$columnName] = $enumType;
392
393 return $this;
394 }
395
396 /**
397 * Adds a metadata parameter mappings.
398 */
399 public function addMetadataParameterMapping(string|int $parameter, string $attribute): void
400 {
401 $this->metadataParameterMapping[$parameter] = $attribute;
402 }
403
404 /**
405 * Checks whether a column with a given name is mapped as a scalar result.
406 *
407 * @todo Rename: isScalar
408 */
409 public function isScalarResult(string $columnName): bool
410 {
411 return isset($this->scalarMappings[$columnName]);
412 }
413
414 /**
415 * Gets the name of the class of an entity result or joined entity result,
416 * identified by the given unique alias.
417 *
418 * @psalm-return class-string
419 */
420 public function getClassName(string $alias): string
421 {
422 return $this->aliasMap[$alias];
423 }
424
425 /**
426 * Gets the field alias for a column that is mapped as a scalar value.
427 *
428 * @param string $columnName The name of the column in the SQL result set.
429 */
430 public function getScalarAlias(string $columnName): string|int
431 {
432 return $this->scalarMappings[$columnName];
433 }
434
435 /**
436 * Gets the name of the class that owns a field mapping for the specified column.
437 *
438 * @psalm-return class-string
439 */
440 public function getDeclaringClass(string $columnName): string
441 {
442 return $this->declaringClasses[$columnName];
443 }
444
445 public function getRelation(string $alias): string
446 {
447 return $this->relationMap[$alias];
448 }
449
450 public function isRelation(string $alias): bool
451 {
452 return isset($this->relationMap[$alias]);
453 }
454
455 /**
456 * Gets the alias of the class that owns a field mapping for the specified column.
457 */
458 public function getEntityAlias(string $columnName): string
459 {
460 return $this->columnOwnerMap[$columnName];
461 }
462
463 /**
464 * Gets the parent alias of the given alias.
465 */
466 public function getParentAlias(string $alias): string
467 {
468 return $this->parentAliasMap[$alias];
469 }
470
471 /**
472 * Checks whether the given alias has a parent alias.
473 */
474 public function hasParentAlias(string $alias): bool
475 {
476 return isset($this->parentAliasMap[$alias]);
477 }
478
479 /**
480 * Gets the field name for a column name.
481 */
482 public function getFieldName(string $columnName): string
483 {
484 return $this->fieldMappings[$columnName];
485 }
486
487 /** @psalm-return array<string, class-string> */
488 public function getAliasMap(): array
489 {
490 return $this->aliasMap;
491 }
492
493 /**
494 * Gets the number of different entities that appear in the mapped result.
495 *
496 * @psalm-return 0|positive-int
497 */
498 public function getEntityResultCount(): int
499 {
500 return count($this->aliasMap);
501 }
502
503 /**
504 * Checks whether this ResultSetMapping defines a mixed result.
505 *
506 * Mixed results can only occur in object and array (graph) hydration. In such a
507 * case a mixed result means that scalar values are mixed with objects/array in
508 * the result.
509 */
510 public function isMixedResult(): bool
511 {
512 return $this->isMixed;
513 }
514
515 /**
516 * Adds a meta column (foreign key or discriminator column) to the result set.
517 *
518 * @param string $alias The result alias with which the meta result should be placed in the result structure.
519 * @param string $columnName The name of the column in the SQL result set.
520 * @param string $fieldName The name of the field on the declaring class.
521 * @param string|null $type The column type
522 *
523 * @return $this
524 *
525 * @todo Make all methods of this class require all parameters and not infer anything
526 */
527 public function addMetaResult(
528 string $alias,
529 string $columnName,
530 string $fieldName,
531 bool $isIdentifierColumn = false,
532 string|null $type = null,
533 ): static {
534 $this->metaMappings[$columnName] = $fieldName;
535 $this->columnOwnerMap[$columnName] = $alias;
536
537 if ($isIdentifierColumn) {
538 $this->isIdentifierColumn[$alias][$columnName] = true;
539 }
540
541 if ($type) {
542 $this->typeMappings[$columnName] = $type;
543 }
544
545 return $this;
546 }
547}