Failed Conditions
Push — master ( fa7802...d60694 )
by Guilherme
09:27
created

ValueGeneratorMetadataBuilder::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Mapping\Builder;
6
7
use Doctrine\DBAL\Types\Type;
8
use Doctrine\ORM\Annotation;
9
use Doctrine\ORM\Mapping;
10
use Doctrine\ORM\Mapping\Exception\TableGeneratorNotImplementedYet;
11
use Doctrine\ORM\Mapping\Exception\UnknownGeneratorType;
12
use Doctrine\ORM\Mapping\GeneratorType;
13
use Doctrine\ORM\Sequencing\Generator;
14
use ReflectionClass;
15
use ReflectionException;
16
use function assert;
17
use function constant;
18
use function in_array;
19
use function sprintf;
20
use function strtoupper;
21
22
class ValueGeneratorMetadataBuilder
23
{
24
    /** @var Mapping\ClassMetadataBuildingContext */
25
    private $metadataBuildingContext;
26
27
    /** @var Mapping\ClassMetadata */
28
    private $componentMetadata;
29
30
    /** @var string */
31
    private $fieldName;
32
33
    /** @var Type */
34
    private $fieldType;
35
36
    /** @var Annotation\GeneratedValue|null */
37
    private $generatedValueAnnotation;
38
39
    /** @var Annotation\SequenceGenerator|null */
40
    private $sequenceGeneratorAnnotation;
41
42
    /** @var Annotation\CustomIdGenerator|null */
43
    private $customIdGeneratorAnnotation;
44
45 401
    public function __construct(Mapping\ClassMetadataBuildingContext $metadataBuildingContext)
46
    {
47 401
        $this->metadataBuildingContext = $metadataBuildingContext;
48 401
    }
49
50 391
    public function withComponentMetadata(Mapping\ClassMetadata $componentMetadata) : ValueGeneratorMetadataBuilder
51
    {
52 391
        $this->componentMetadata = $componentMetadata;
53
54 391
        return $this;
55
    }
56
57 391
    public function withFieldName(string $fieldName) : ValueGeneratorMetadataBuilder
58
    {
59 391
        $this->fieldName = $fieldName;
60
61 391
        return $this;
62
    }
63
64 391
    public function withFieldType(Type $fieldType) : ValueGeneratorMetadataBuilder
65
    {
66 391
        $this->fieldType = $fieldType;
67
68 391
        return $this;
69
    }
70
71 391
    public function withGeneratedValueAnnotation(
72
        ?Annotation\GeneratedValue $generatedValueAnnotation
73
    ) : ValueGeneratorMetadataBuilder {
74 391
        $this->generatedValueAnnotation = $generatedValueAnnotation;
75
76 391
        return $this;
77
    }
78
79 391
    public function withSequenceGeneratorAnnotation(
80
        ?Annotation\SequenceGenerator $sequenceGeneratorAnnotation
81
    ) : ValueGeneratorMetadataBuilder {
82 391
        $this->sequenceGeneratorAnnotation = $sequenceGeneratorAnnotation;
83
84 391
        return $this;
85
    }
86
87 391
    public function withCustomIdGeneratorAnnotation(
88
        ?Annotation\CustomIdGenerator $customIdGeneratorAnnotation
89
    ) : ValueGeneratorMetadataBuilder {
90 391
        $this->customIdGeneratorAnnotation = $customIdGeneratorAnnotation;
91
92 391
        return $this;
93
    }
94
95 391
    public function build() : ?Mapping\ValueGeneratorMetadata
96
    {
97
        // Validate required fields
98 391
        assert($this->componentMetadata !== null);
99 391
        assert($this->fieldName !== null);
100 391
        assert($this->fieldType !== null);
101
102 391
        if (! $this->generatedValueAnnotation) {
103 74
            return null;
104
        }
105
106 338
        $platform      = $this->metadataBuildingContext->getTargetPlatform();
107 338
        $strategy      = strtoupper($this->generatedValueAnnotation->strategy);
108 338
        $generatorType = constant(sprintf('%s::%s', Mapping\GeneratorType::class, $strategy));
109
110 338
        if (in_array($generatorType, [Mapping\GeneratorType::AUTO, Mapping\GeneratorType::IDENTITY], true)) {
111 300
            $generatorType = $platform->prefersSequences() || $platform->usesSequenceEmulatedIdentityColumns()
112 15
                ? Mapping\GeneratorType::SEQUENCE
113 300
                : ($platform->prefersIdentityColumns() ? Mapping\GeneratorType::IDENTITY : Mapping\GeneratorType::TABLE);
114
        }
115
116
        switch ($generatorType) {
117 338
            case Mapping\GeneratorType::IDENTITY:
118 285
                $generator = $this->fieldType->getName() === 'bigint'
119 1
                    ? new Generator\BigIntegerIdentityGenerator()
120 285
                    : new Generator\IdentityGenerator();
121
122 285
                return new Mapping\ValueGeneratorMetadata($generatorType, $generator);
123
124
                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...
125
126 56
            case Mapping\GeneratorType::SEQUENCE:
127 21
                $sequenceName   = null;
128 21
                $allocationSize = 1;
129
130 21
                if ($this->sequenceGeneratorAnnotation) {
131 12
                    $sequenceName   = $this->sequenceGeneratorAnnotation->sequenceName ?? null;
132 12
                    $allocationSize = $this->sequenceGeneratorAnnotation->allocationSize ?? 1;
133
                }
134
135 21
                if (empty($sequenceName)) {
136 9
                    $sequenceName = $platform->fixSchemaElementName(
137 9
                        sprintf(
138 9
                            '%s_%s_seq',
139 9
                            $platform->getSequencePrefix(
140 9
                                $this->componentMetadata->getTableName(),
141 9
                                $this->componentMetadata->getSchemaName()
142
                            ),
143 9
                            $this->fieldName
144
                        )
145
                    );
146
                }
147
148 21
                $generator = new Generator\SequenceGenerator($sequenceName, $allocationSize);
149
150 21
                return new Mapping\ValueGeneratorMetadata($generatorType, $generator);
151
152
                break;
153
154 35
            case Mapping\GeneratorType::CUSTOM:
155 5
                assert($this->customIdGeneratorAnnotation !== null);
156
157 5
                if (empty($this->customIdGeneratorAnnotation->class)) {
158
                    $message = 'Cannot instantiate custom generator, no class has been defined';
159
160
                    throw new Mapping\MappingException($message);
161
                }
162
163
                try {
164 5
                    $reflectionClass = new ReflectionClass($this->customIdGeneratorAnnotation->class);
165 5
                    $generator       = $reflectionClass->newInstanceArgs($this->customIdGeneratorAnnotation->arguments);
166
167 5
                    return new Mapping\ValueGeneratorMetadata($generatorType, $generator);
168
                } catch (ReflectionException $exception) {
169
                    $message = sprintf(
170
                        'Cannot instantiate custom generator : %s',
171
                        $this->customIdGeneratorAnnotation->class
172
                    );
173
174
                    throw new Mapping\MappingException($message);
175
                }
176
177
                break;
178
179 30
            case GeneratorType::TABLE:
180
                throw TableGeneratorNotImplementedYet::create();
181
182 30
            case null: // Function constant() returns null if it is not defined in class.
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $generatorType of type mixed|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
183
                throw UnknownGeneratorType::create($strategy);
184
185 30
            case Mapping\GeneratorType::NONE:
186
            default:
187 30
                return null;
188
        }
189
    }
190
}
191