Passed
Pull Request — 2.x (#66)
by Maxim
12:40
created

Embedded::compute()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 39
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 6

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 6
eloc 21
nc 8
nop 1
dl 0
loc 39
ccs 19
cts 19
cp 1
crap 6
rs 8.9617
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
    /**
26
     * @param Registry $registry
27
     */
28 56
    public function compute(Registry $registry): void
29
    {
30 56
        $source = $registry->getEntity($this->source);
31 56
        $target = $registry->getEntity($this->target);
32
33
        $targetRole = $target->getRole();
34 56
        $sourceRole = $source->getRole();
35 56
        \assert($targetRole !== null && $sourceRole !== null);
36
37
        // each embedded entity must isolated
38 56
        $target = clone $target;
39 56
        $target->setRole($sourceRole . ':' . $targetRole . ':' . $this->name);
40
41
        // embedded entity must point to the same table as parent entity
42 56
        $registry->register($target);
43
        $registry->linkTable($target, $registry->getDatabase($source), $registry->getTable($source));
44 56
45
        // isolated
46 56
        $this->target = $targetRole;
47 56
48
        $prefix = $this->getOptions()->get(self::EMBEDDED_PREFIX);
49
        assert(\is_string($prefix));
50 56
        foreach ($target->getFields() as $field) {
51 56
            /** @var non-empty-string $columnName */
52
            $columnName = $prefix . $field->getColumn();
53 48
            $field->setColumn($columnName);
54 8
        }
55
56 40
        foreach ($source->getFields() as $name => $field) {
57
            if ($field->isPrimary()) {
58
                // sync primary keys
59
                if ($target->getFields()->has($name)) {
60 48
                    throw new EmbeddedPrimaryKeyException($target, $name);
61 40
                }
62
                $target->getFields()->set($name, $field);
63
            }
64
        }
65
66 16
        parent::compute($registry);
67
    }
68
69 16
    /**
70
     * @param Registry $registry
71
     */
72
    public function render(Registry $registry): void
73
    {
74
        // relation does not require any column rendering besides actual tables
75
    }
76
}
77