Passed
Push — master ( 46953a...077925 )
by Anton
01:33
created

Compiler::getPrimary()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
namespace Cycle\Schema;
11
12
use Cycle\ORM\Schema;
13
use Cycle\Schema\Definition\Entity;
14
use Spiral\Database\Exception\CompilerException;
15
16
final class Compiler implements GeneratorInterface
17
{
18
    /** @var array */
19
    private $result = [];
20
21
    /**
22
     * Get compiled schema result.
23
     *
24
     * @return array
25
     */
26
    public function getSchema(): array
27
    {
28
        return $this->result;
29
    }
30
31
    /**
32
     * Compile entity and relation definitions into packed ORM schema.
33
     *
34
     * @param Registry $registry
35
     * @param Entity   $entity
36
     */
37
    public function compute(Registry $registry, Entity $entity)
38
    {
39
        $schema = [
40
            Schema::ENTITY       => $entity->getClass(),
41
            Schema::SOURCE       => $entity->getSource(),
42
            Schema::MAPPER       => $entity->getMapper(),
43
            Schema::REPOSITORY   => $entity->getRepository(),
44
            Schema::CONSTRAIN    => $entity->getConstrain(),
45
            Schema::PRIMARY_KEY  => $this->getPrimary($entity),
46
            Schema::COLUMNS      => $this->renderColumns($entity),
47
            Schema::FIND_BY_KEYS => $this->renderReferences($entity),
48
            Schema::TYPECAST     => $this->renderTypecast($entity),
49
            Schema::RELATIONS    => $this->renderRelations($registry, $entity),
50
            Schema::SCHEMA       => $entity->getSchema()
51
        ];
52
53
        if ($registry->hasTable($entity)) {
54
            $schema[Schema::DATABASE] = $registry->getDatabase($entity);
55
            $schema[Schema::TABLE] = $registry->getTable($entity);
56
        }
57
58
        // table inheritance
59
        foreach ($registry->getChildren($entity) as $child) {
60
            $this->result[$child->getClass()] = [Schema::ROLE => $entity->getRole()];
61
            $schema[Schema::CHILDREN][] = $child->getClass();
62
        }
63
64
        ksort($schema);
65
        $this->result[$entity->getRole()] = $schema;
66
    }
67
68
    /**
69
     * @param Entity $entity
70
     * @return array
71
     */
72
    protected function renderColumns(Entity $entity): array
73
    {
74
        $schema = [];
75
        foreach ($entity->getFields() as $name => $field) {
76
            $schema[$name] = $field->getColumn();
77
        }
78
79
        return $schema;
80
    }
81
82
    /**
83
     * @param Entity $entity
84
     * @return array
85
     */
86
    protected function renderTypecast(Entity $entity): array
87
    {
88
        $schema = [];
89
        foreach ($entity->getFields() as $name => $field) {
90
            if ($field->hasTypecast()) {
91
                $schema[$name] = $field->getTypecast();
92
            }
93
        }
94
95
        return $schema;
96
    }
97
98
    /**
99
     * @param Entity $entity
100
     * @return array
101
     */
102
    protected function renderReferences(Entity $entity): array
103
    {
104
        $schema = [];
105
        foreach ($entity->getFields() as $name => $field) {
106
            if ($field->isReferenced()) {
107
                $schema[] = $name;
108
            }
109
        }
110
111
        return $schema;
112
    }
113
114
    /**
115
     * @param Registry $registry
116
     * @param Entity   $entity
117
     * @return array
118
     */
119
    protected function renderRelations(Registry $registry, Entity $entity): array
120
    {
121
        $result = [];
122
        foreach ($registry->getRelations($entity) as $name => $relation) {
123
            $result[$name] = $relation->packSchema();
124
        }
125
126
        return $result;
127
    }
128
129
    /**
130
     * @param Entity $entity
131
     * @return string
132
     *
133
     * @throws CompilerException
134
     */
135
    protected function getPrimary(Entity $entity): string
136
    {
137
        foreach ($entity->getFields() as $name => $field) {
138
            if ($field->isPrimary()) {
139
                return $name;
140
            }
141
        }
142
143
        throw new CompilerException("Entity `{$entity->getRole()}` must have defined primary key");
144
    }
145
}