Completed
Push — master ( e12b56...1fb17f )
by Anton
01:36
created

Compiler::computeFields()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 5
nop 1
dl 0
loc 21
rs 9.9
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 Cycle\Schema\Exception\BuilderException;
15
16
final class Compiler implements ProcessorInterface
17
{
18
    /** @var array */
19
    private $result = [];
20
21
    /**
22
     * Get compiled schema result.
23
     *
24
     * @return array
25
     */
26
    public function getResult(): 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::RELATIONS  => []
46
        ];
47
48
        if ($registry->hasTable($entity)) {
49
            $primaryKeys = $registry->getTableSchema($entity)->getPrimaryKeys();
50
            if (count($primaryKeys) !== 1) {
51
                throw new BuilderException("Entity `{$entity->getRole()}` must define exactly one primary key");
52
            }
53
54
            $schema[Schema::DATABASE] = $registry->getDatabase($entity);
55
            $schema[Schema::TABLE] = $registry->getTable($entity);
56
            $schema[Schema::PRIMARY_KEY] = current($primaryKeys);
57
        }
58
59
        $schema += $this->computeFields($entity);
60
61
        // todo: relations
62
63
        foreach ($registry->getChildren($entity) as $child) {
64
            // alias
65
            $this->result[$child->getClass()] = [Schema::ROLE => $entity->getRole()];
66
            $schema[Schema::CHILDREN][] = $child->getClass();
67
        }
68
69
        ksort($schema);
70
        $this->result[$entity->getRole()] = $schema;
71
    }
72
73
    /**
74
     * @param Entity $entity
75
     * @return array
76
     */
77
    protected function computeFields(Entity $entity): array
78
    {
79
        $schema = [
80
            Schema::COLUMNS      => [],
81
            Schema::TYPECAST     => [],
82
            Schema::FIND_BY_KEYS => []
83
        ];
84
85
        foreach ($entity->getFields() as $name => $field) {
86
            $schema[Schema::COLUMNS][$name] = $field->getColumn();
87
88
            if ($field->hasTypecast()) {
89
                $schema[Schema::TYPECAST][$name] = $field->getTypecast();
90
            }
91
92
            if ($field->isReferenced()) {
93
                $schema[Schema::FIND_BY_KEYS][] = $name;
94
            }
95
        }
96
97
        return $schema;
98
    }
99
}