Failed Conditions
Pull Request — master (#7143)
by Mike
07:18
created

ClassMetadataFactory::initialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Mapping;
6
7
use Doctrine\Common\EventManager;
8
use Doctrine\DBAL\Connection;
9
use Doctrine\DBAL\Platforms;
10
use Doctrine\DBAL\Platforms\AbstractPlatform;
11
use Doctrine\ORM\Configuration;
12
use Doctrine\ORM\EntityManagerInterface;
0 ignored issues
show
introduced by
Type Doctrine\ORM\EntityManagerInterface is not used in this file.
Loading history...
13
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
0 ignored issues
show
Bug introduced by
The type Doctrine\ORM\Event\LoadClassMetadataEventArgs was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
introduced by
Type Doctrine\ORM\Event\LoadClassMetadataEventArgs is not used in this file.
Loading history...
14
use Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs;
0 ignored issues
show
Bug introduced by
The type Doctrine\ORM\Event\OnCla...tadataNotFoundEventArgs was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
introduced by
Type Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs is not used in this file.
Loading history...
15
use Doctrine\ORM\Events;
0 ignored issues
show
introduced by
Type Doctrine\ORM\Events is not used in this file.
Loading history...
16
use Doctrine\ORM\Mapping\Driver\MappingDriver;
17
use Doctrine\ORM\ORMException;
18
use Doctrine\ORM\Sequencing;
19
use Doctrine\ORM\Sequencing\Planning\AssociationValueGeneratorExecutor;
20
use Doctrine\ORM\Sequencing\Planning\ColumnValueGeneratorExecutor;
21
use Doctrine\ORM\Sequencing\Planning\CompositeValueGenerationPlan;
22
use Doctrine\ORM\Sequencing\Planning\NoopValueGenerationPlan;
23
use Doctrine\ORM\Sequencing\Planning\SingleValueGenerationPlan;
24
use Doctrine\ORM\Sequencing\Planning\ValueGenerationExecutor;
25
use ReflectionException;
26
use function array_map;
27
use function class_exists;
28
use function count;
29
use function end;
30
use function explode;
31
use function is_subclass_of;
32
use function sprintf;
33
use function strpos;
34
use function strtolower;
35
use function var_export;
36
37
/**
38
 * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
39
 * metadata mapping information of a class which describes how a class should be mapped
40
 * to a relational database.
41
 */
42
class ClassMetadataFactory extends AbstractClassMetadataFactory
43
{
0 ignored issues
show
introduced by
There must be exactly 0 empty lines after class opening brace.
Loading history...
44
45
    /** @var AbstractPlatform */
46
    private $targetPlatform;
47
48
    /**
0 ignored issues
show
introduced by
Found multi-line comment for property \Doctrine\ORM\Mapping\ClassMetadataFactory::$configuration with single line content, use one-line comment instead.
Loading history...
49
     * @var Configuration
50
     */
51
    private $configuration;
52
    /**
0 ignored issues
show
introduced by
Found multi-line comment for property \Doctrine\ORM\Mapping\ClassMetadataFactory::$connection with single line content, use one-line comment instead.
Loading history...
53
     * @var Connection
54
     */
55
    private $connection;
56 379
    /**
0 ignored issues
show
introduced by
Found multi-line comment for property \Doctrine\ORM\Mapping\ClassMetadataFactory::$eventManager with single line content, use one-line comment instead.
Loading history...
57
     * @var EventManager
58 379
     */
59
    private $eventManager;
60 360
61
    /**
0 ignored issues
show
introduced by
Found multi-line comment for property \Doctrine\ORM\Mapping\ClassMetadataFactory::$driver with single line content, use one-line comment instead.
Loading history...
62 360
     * @var MappingDriver
63
     */
64
    private $driver;
65 2249
66
    public function __construct(Configuration $configuration, Connection $connection, EventManager $eventManager)
67 2249
    {
68 2249
        $this->configuration = $configuration;
69
        $this->connection = $connection;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
70
        $this->eventManager = $eventManager;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
71
        $this->driver      = $this->configuration->getMetadataDriverImpl();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 6 spaces

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
72
    }
73
74
    /**
75 445
     * {@inheritdoc}
76
     */
77 445
    protected function loadMetadata(string $name, ClassMetadataBuildingContext $metadataBuildingContext) : array
78 445
    {
79 445
        $loaded = parent::loadMetadata($name, $metadataBuildingContext);
80 445
81
        array_map([$this, 'resolveDiscriminatorValue'], $loaded);
82
83
        return $loaded;
84
    }
85 12
86
    /**
87
     * {@inheritdoc}
88
     *
89 12
     * @throws MappingException
90 10
     * @throws ORMException
91
     */
92
    protected function doLoadMetadata(
93 2
        string $className,
94
        ?ClassMetadata $parent,
95 2
        ClassMetadataBuildingContext $metadataBuildingContext
96
    ) : ClassMetadata {
97 2
        $classMetadata = new ClassMetadata($className, $metadataBuildingContext);
98
99
        if ($parent) {
100
            $classMetadata->setParent($parent);
101
102
            foreach ($parent->getDeclaredPropertiesIterator() as $fieldName => $property) {
103
                $classMetadata->addInheritedProperty($property);
104
            }
105
106 367
            $classMetadata->setInheritanceType($parent->inheritanceType);
0 ignored issues
show
Bug introduced by
$parent->inheritanceType of type string is incompatible with the type integer expected by parameter $type of Doctrine\ORM\Mapping\Cla...a::setInheritanceType(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

106
            $classMetadata->setInheritanceType(/** @scrutinizer ignore-type */ $parent->inheritanceType);
Loading history...
107
            $classMetadata->setIdentifier($parent->identifier);
108
109
            if ($parent->discriminatorColumn) {
110
                $classMetadata->setDiscriminatorColumn($parent->discriminatorColumn);
111 367
                $classMetadata->setDiscriminatorMap($parent->discriminatorMap);
112
            }
113 367
114 98
            $classMetadata->setLifecycleCallbacks($parent->lifecycleCallbacks);
115
            $classMetadata->setChangeTrackingPolicy($parent->changeTrackingPolicy);
116 98
117 97
            if ($parent->isMappedSuperclass) {
118
                $classMetadata->setCustomRepositoryClassName($parent->getCustomRepositoryClassName());
119
            }
120 98
        }
121 98
122
        // Invoke driver
123 98
        try {
124 72
            $this->driver->loadMetadataForClass($classMetadata->getClassName(), $classMetadata, $metadataBuildingContext);
125 72
        } catch (ReflectionException $e) {
126
            throw MappingException::reflectionFailure($classMetadata->getClassName(), $e);
127
        }
128 98
129 98
        $this->completeIdentifierGeneratorMappings($classMetadata);
130
131 98
        if ($parent) {
132 28
            if ($parent->getCache()) {
133
                $classMetadata->setCache(clone $parent->getCache());
134
            }
135
136
            if (! empty($parent->entityListeners) && empty($classMetadata->entityListeners)) {
137
                $classMetadata->entityListeners = $parent->entityListeners;
138 367
            }
139 3
        }
140
141
        if (! $classMetadata->discriminatorMap && $classMetadata->inheritanceType !== InheritanceType::NONE && $classMetadata->isRootEntity()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $classMetadata->discriminatorMap of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
142
            $this->addDefaultDiscriminatorMap($classMetadata);
143 364
        }
144
145 364
        $this->completeRuntimeMetadata($classMetadata, $parent);
146 98
147 3
        $this->buildValueGenerationPlan($classMetadata);
148
        $this->validateRuntimeMetadata($classMetadata, $parent);
149
150 98
        return $classMetadata;
151 7
    }
152
153
    protected function completeRuntimeMetadata(ClassMetadata $class, ?ClassMetadata $parent = null) : void
154
    {
155 364
        if (! $parent || ! $parent->isMappedSuperclass) {
156 1
            return;
157
        }
158
159 364
        if ($class->isMappedSuperclass) {
160
            return;
161 364
        }
162 6
163
        $tableName = $class->getTableName();
164 6
165
        // Resolve column table names
166
        foreach ($class->getDeclaredPropertiesIterator() as $property) {
167 363
            if ($property instanceof FieldMetadata) {
168 363
                $property->setTableName($property->getTableName() ?? $tableName);
169
170 361
                continue;
171
            }
172
173 364
            if (! ($property instanceof ToOneAssociationMetadata)) {
174
                continue;
175 364
            }
176 364
177
            // Resolve association join column table names
178
            foreach ($property->getJoinColumns() as $joinColumn) {
179 28
                /** @var JoinColumnMetadata $joinColumn */
180 1
                $joinColumn->setTableName($joinColumn->getTableName() ?? $tableName);
181
            }
182
        }
183 28
    }
184
185
    /**
186 28
     * Validate runtime metadata is correctly defined.
187 28
     *
188 28
     * @throws MappingException
189
     */
190 28
    protected function validateRuntimeMetadata(ClassMetadata $class, ?ClassMetadata $parent = null) : void
191
    {
192
        if (! $class->getReflectionClass()) {
193 12
            // only validate if there is a reflection class instance
194 12
            return;
195
        }
196
197
        $class->validateIdentifier();
198 9
        $class->validateAssociations();
199
        $class->validateLifecycleCallbacks($this->getReflectionService());
200 9
201
        // verify inheritance
202
        if (! $class->isMappedSuperclass && $class->inheritanceType !== InheritanceType::NONE) {
203 28
            if (! $parent) {
204
                if (! $class->discriminatorMap) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $class->discriminatorMap of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
205
                    throw MappingException::missingDiscriminatorMap($class->getClassName());
206
                }
207
208
                if (! $class->discriminatorColumn) {
209
                    throw MappingException::missingDiscriminatorColumn($class->getClassName());
210 363
                }
211
            }
212 363
        } elseif (($class->discriminatorMap || $class->discriminatorColumn) && $class->isMappedSuperclass && $class->isRootEntity()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $class->discriminatorMap of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
213
            // second condition is necessary for mapped superclasses in the middle of an inheritance hierarchy
214
            throw MappingException::noInheritanceOnMappedSuperClass($class->getClassName());
215
        }
216
    }
217 363
218 361
    /**
219 361
     * {@inheritdoc}
220
     */
221
    protected function newClassMetadataBuildingContext() : ClassMetadataBuildingContext
222 361
    {
223 75
        return new ClassMetadataBuildingContext(
224 74
            $this,
225
            $this->getReflectionService(),
226
            $this->configuration->getNamingStrategy()
227
        );
228 74
    }
229 75
230
    /**
231
     * Populates the discriminator value of the given metadata (if not set) by iterating over discriminator
232 325
     * map classes and looking for a fitting one.
233
     *
234
     * @throws \InvalidArgumentException
235
     * @throws \ReflectionException
236 361
     * @throws MappingException
237
     */
238
    private function resolveDiscriminatorValue(ClassMetadata $metadata) : void
239
    {
240
        if ($metadata->discriminatorValue || ! $metadata->discriminatorMap || $metadata->isMappedSuperclass ||
0 ignored issues
show
Bug Best Practice introduced by
The expression $metadata->discriminatorMap of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
241 1951
            ! $metadata->getReflectionClass() || $metadata->getReflectionClass()->isAbstract()) {
242
            return;
243 1951
        }
244 1951
245 1951
        // minor optimization: avoid loading related metadata when not needed
246 1951
        foreach ($metadata->discriminatorMap as $discriminatorValue => $discriminatorClass) {
247
            if ($discriminatorClass === $metadata->getClassName()) {
248
                $metadata->discriminatorValue = $discriminatorValue;
249
250
                return;
251
            }
252
        }
253
254
        // iterate over discriminator mappings and resolve actual referenced classes according to existing metadata
255
        foreach ($metadata->discriminatorMap as $discriminatorValue => $discriminatorClass) {
256
            if ($metadata->getClassName() === $this->getMetadataFor($discriminatorClass)->getClassName()) {
257
                $metadata->discriminatorValue = $discriminatorValue;
258 360
259
                return;
260 360
            }
261 360
        }
262 360
263
        throw MappingException::mappedClassNotPartOfDiscriminatorMap($metadata->getClassName(), $metadata->getRootClassName());
264
    }
265
266 4
    /**
267 4
     * Adds a default discriminator map if no one is given
268 3
     *
269
     * If an entity is of any inheritance type and does not contain a
270 4
     * discriminator map, then the map is generated automatically. This process
271
     * is expensive computation wise.
272
     *
273
     * The automatically generated discriminator map contains the lowercase short name of
274
     * each class as key.
275 1
     *
276 1
     * @throws MappingException
277
     */
278
    private function addDefaultDiscriminatorMap(ClassMetadata $class) : void
279 1
    {
280
        $allClasses = $this->driver->getAllClassNames();
281
        $fqcn       = $class->getClassName();
282
        $map        = [$this->getShortName($fqcn) => $fqcn];
283 1
        $duplicates = [];
284
285
        foreach ($allClasses as $subClassCandidate) {
286
            if (is_subclass_of($subClassCandidate, $fqcn)) {
287
                $shortName = $this->getShortName($subClassCandidate);
288
289
                if (isset($map[$shortName])) {
290
                    $duplicates[] = $shortName;
291
                }
292
293
                $map[$shortName] = $subClassCandidate;
294
            }
295
        }
296
297
        if ($duplicates) {
298 1
            throw MappingException::duplicateDiscriminatorEntry($class->getClassName(), $duplicates, $map);
299
        }
300 1
301 1
        $class->setDiscriminatorMap($map);
302 1
    }
303 1
304
    /**
305 1
     * Gets the lower-case short name of a class.
306 1
     *
307 1
     * @param string $className
308
     */
309 1
    private function getShortName($className) : string
310
    {
311
        if (strpos($className, '\\') === false) {
312
            return strtolower($className);
313 1
        }
314
315
        $parts = explode('\\', $className);
316
317 1
        return strtolower(end($parts));
318
    }
319
320
    /**
321 1
     * Completes the ID generator mapping. If "auto" is specified we choose the generator
322 1
     * most appropriate for the targeted database platform.
323
     *
324
     * @throws ORMException
325
     */
326
    private function completeIdentifierGeneratorMappings(ClassMetadata $class) : void
327
    {
328
        foreach ($class->getDeclaredPropertiesIterator() as $property) {
329 1
            if (! $property instanceof FieldMetadata /*&& ! $property instanceof AssocationMetadata*/) {
330
                continue;
331 1
            }
332
333
            $this->completeFieldIdentifierGeneratorMapping($property);
334
        }
335 1
    }
336
337 1
    private function completeFieldIdentifierGeneratorMapping(FieldMetadata $field)
338
    {
339
        if (! $field->hasValueGenerator()) {
340
            return;
341
        }
342
343
        $platform  = $this->getTargetPlatform();
344
        $class     = $field->getDeclaringClass();
0 ignored issues
show
Unused Code introduced by
The assignment to $class is dead and can be removed.
Loading history...
345
        $generator = $field->getValueGenerator();
346 364
347
        if ($generator->getType() === GeneratorType::AUTO) {
348 364
            $generator = new ValueGeneratorMetadata(
349 362
                $platform->prefersSequences()
350 251
                    ? GeneratorType::SEQUENCE
351
                    : ($platform->prefersIdentityColumns()
352
                        ? GeneratorType::IDENTITY
353 360
                        : GeneratorType::TABLE
354
                ),
355 364
                $field->getValueGenerator()->getDefinition()
356
            );
357 360
            $field->setValueGenerator($generator);
358
        }
359 360
360 280
        // Validate generator definition and set defaults where needed
361
        switch ($generator->getType()) {
362
            case GeneratorType::SEQUENCE:
363 288
                // If there is no sequence definition yet, create a default definition
364 288
                if ($generator->getDefinition()) {
365 288
                    break;
366
                }
367 288
368 278
                // @todo guilhermeblanco Move sequence generation to DBAL
369 278
                $sequencePrefix = $platform->getSequencePrefix($field->getTableName(), $field->getSchemaName());
0 ignored issues
show
Bug introduced by
The method getSchemaName() does not exist on Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

369
                $sequencePrefix = $platform->getSequencePrefix($field->getTableName(), $field->/** @scrutinizer ignore-call */ getSchemaName());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
370
                $idSequenceName = sprintf('%s_%s_seq', $sequencePrefix, $field->getColumnName());
371 278
                $sequenceName   = $platform->fixSchemaElementName($idSequenceName);
372 278
373 278
                $field->setValueGenerator(
374
                    new ValueGeneratorMetadata(
375 278
                        $generator->getType(),
376
                        [
377 278
                            'sequenceName'   => $sequenceName,
378
                            'allocationSize' => 1,
379
                        ]
380
                    )
381 288
                );
382 288
383
                break;
384 6
385 6
            case GeneratorType::TABLE:
386
                throw new ORMException('TableGenerator not yet implemented.');
387
                break;
388
389
            case GeneratorType::CUSTOM:
390
                $definition = $generator->getDefinition();
391
                if (! isset($definition['class'])) {
392
                    throw new ORMException(sprintf('Cannot instantiate custom generator, no class has been defined'));
393
                }
394
                if (! class_exists($definition['class'])) {
395
                    throw new ORMException(sprintf('Cannot instantiate custom generator : %s', var_export($definition, true))); //$definition['class']));
396
                }
397
398
                break;
399
400
            case GeneratorType::IDENTITY:
401
            case GeneratorType::NONE:
402
            case GeneratorType::UUID:
403
                break;
404
405 282
            default:
406
                throw new ORMException('Unknown generator type: ' . $generator->getType());
407
        }
408
    }
409 282
410 1
    /**
411 1
     * {@inheritDoc}
412
     */
413
    protected function getDriver() : Driver\MappingDriver
414 1
    {
415
        return $this->driver;
416
    }
417
418 1
    /**
419
     * {@inheritDoc}
420 281
     */
421
    protected function isEntity(ClassMetadata $class) : bool
422
    {
423 281
        return isset($class->isMappedSuperclass) && $class->isMappedSuperclass === false;
424
    }
425
426
    private function getTargetPlatform() : Platforms\AbstractPlatform
427
    {
428 288
        if (! $this->targetPlatform) {
429
            $this->targetPlatform = $this->connection->getDatabasePlatform();
430
        }
431
432
        return $this->targetPlatform;
433 198
    }
434
435 198
    private function buildValueGenerationPlan(ClassMetadata $class) : void
436
    {
437
        $executors = $this->buildValueGenerationExecutorList($class);
438
439
        switch (count($executors)) {
440
            case 0:
441
                $class->setValueGenerationPlan(new NoopValueGenerationPlan());
442
                break;
443
444
            case 1:
445
                $class->setValueGenerationPlan(new SingleValueGenerationPlan($class, $executors[0]));
446 288
                break;
447
448 288
            default:
449 288
                $class->setValueGenerationPlan(new CompositeValueGenerationPlan($class, $executors));
450
                break;
451
        }
452 288
    }
453
454
    /**
455 363
     * @return ValueGenerationExecutor[]
456
     */
457 363
    private function buildValueGenerationExecutorList(ClassMetadata $class) : array
458
    {
459 363
        $executors = [];
460 363
461 91
        foreach ($class->getDeclaredPropertiesIterator() as $property) {
462 91
            $executor = $this->buildValueGenerationExecutorForProperty($class, $property);
463
464 303
            if ($executor instanceof ValueGenerationExecutor) {
465 298
                $executors[] = $executor;
466 298
            }
467
        }
468
469 18
        return $executors;
470 18
    }
471
472 363
    private function buildValueGenerationExecutorForProperty(
473
        ClassMetadata $class,
474
        Property $property
475
    ) : ?ValueGenerationExecutor {
476
        if ($property instanceof LocalColumnMetadata && $property->hasValueGenerator()) {
477 363
            return new ColumnValueGeneratorExecutor($property, $this->createPropertyValueGenerator($class, $property));
478
        }
479 363
480
        if ($property instanceof ToOneAssociationMetadata && $property->isPrimaryKey()) {
481 363
            return new AssociationValueGeneratorExecutor();
482 361
        }
483
484 361
        return null;
485 361
    }
486
487
    private function createPropertyValueGenerator(
488
        ClassMetadata $class,
489 363
        LocalColumnMetadata $property
490
    ) : Sequencing\Generator {
491
        $platform = $this->getTargetPlatform();
492 361
493
        switch ($property->getValueGenerator()->getType()) {
494
            case GeneratorType::IDENTITY:
495
                $sequenceName = null;
496 361
497 287
                // Platforms that do not have native IDENTITY support need a sequence to emulate this behaviour.
498
                if ($platform->usesSequenceEmulatedIdentityColumns()) {
499
                    $sequencePrefix = $platform->getSequencePrefix($class->getTableName(), $class->getSchemaName());
500 331
                    $idSequenceName = $platform->getIdentitySequenceName($sequencePrefix, $property->getColumnName());
501 41
                    $sequenceName   = $platform->quoteIdentifier($platform->fixSchemaElementName($idSequenceName));
502
                }
503
504 327
                return $property->getTypeName() === 'bigint'
505
                    ? new Sequencing\BigIntegerIdentityGenerator($sequenceName)
506
                    : new Sequencing\IdentityGenerator($sequenceName);
507 287
508
            case GeneratorType::SEQUENCE:
509
                $definition = $property->getValueGenerator()->getDefinition();
510
                return new Sequencing\SequenceGenerator(
511 287
                    $platform->quoteIdentifier($definition['sequenceName']),
512
                    $definition['allocationSize']
513 287
                );
514 287
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
515 280
516
            case GeneratorType::UUID:
517
                return new Sequencing\UuidGenerator();
518 280
                break;
519
520
            case GeneratorType::CUSTOM:
521
                $class = $property->getValueGenerator()->getDefinition()['class'];
522
                return new $class();
523
                break;
524 280
        }
525 1
    }
526
}
527