Embedded::compute()   B
last analyzed

Complexity

Conditions 6
Paths 8

Size

Total Lines 41
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 6

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 6
eloc 23
nc 8
nop 1
dl 0
loc 41
ccs 18
cts 18
cp 1
crap 6
rs 8.9297
c 3
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\Schema\Relation;
6
7
use Cycle\ORM\Relation;
8
use Cycle\Schema\Exception\FieldException\EmbeddedPrimaryKeyException;
9
use Cycle\Schema\Registry;
10
use Cycle\Schema\Relation\Traits\ForeignKeyTrait;
11
12
final class Embedded extends RelationSchema
13
{
14
    use ForeignKeyTrait;
15
16
    // internal relation type
17
    protected const RELATION_TYPE = Relation::EMBEDDED;
18
19
    // relation schema options
20
    protected const RELATION_SCHEMA = [
21
        Relation::LOAD => Relation::LOAD_EAGER,
22
        self::EMBEDDED_PREFIX => '',
23
    ];
24
25
    public function compute(Registry $registry): void
26
    {
27
        $source = $registry->getEntity($this->source);
28 56
        $target = $registry->getEntity($this->target);
29
30 56
        $targetRole = $target->getRole();
31 56
        $sourceRole = $source->getRole();
32
        \assert($targetRole !== null && $sourceRole !== null);
33
34 56
        // each embedded entity must isolated
35 56
        $target = clone $target;
36
        $target->setRole($sourceRole . ':' . $targetRole . ':' . $this->name);
37
        $targetRole = $target->getRole();
38 56
        \assert($targetRole !== null);
39 56
40
        // embedded entity must point to the same table as parent entity
41
        $registry->register($target);
42 56
        $registry->linkTable($target, $registry->getDatabase($source), $registry->getTable($source));
43
44 56
        // isolated
45
        $this->target = $targetRole;
46 56
47 56
        $prefix = $this->getOptions()->get(self::EMBEDDED_PREFIX);
48
        assert(\is_string($prefix));
49
        foreach ($target->getFields() as $field) {
50 56
            /** @var non-empty-string $columnName */
51 56
            $columnName = $prefix . $field->getColumn();
52
            $field->setColumn($columnName);
53 48
        }
54 8
55
        foreach ($source->getFields() as $name => $field) {
56 40
            if ($field->isPrimary()) {
57
                // sync primary keys
58
                if ($target->getFields()->has($name)) {
59
                    throw new EmbeddedPrimaryKeyException($target, $name);
60 48
                }
61 40
                $target->getFields()->set($name, $field);
62
            }
63
        }
64
65
        parent::compute($registry);
66 16
    }
67
68
    public function render(Registry $registry): void
69 16
    {
70
        // relation does not require any column rendering besides actual tables
71
    }
72
}
73