Passed
Push — master ( 0a4fc8...34ac19 )
by Anton
04:11
created

EmbeddedLoader::getAlias()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
declare(strict_types=1);
9
10
namespace Cycle\ORM\Select\Loader;
11
12
use Cycle\ORM\ORMInterface;
13
use Cycle\ORM\Parser\AbstractNode;
14
use Cycle\ORM\Parser\EmbeddedNode;
15
use Cycle\ORM\Parser\Typecast;
16
use Cycle\ORM\Schema;
17
use Cycle\ORM\Select\JoinableInterface;
18
use Cycle\ORM\Select\LoaderInterface;
19
use Cycle\ORM\Select\Traits\ColumnsTrait;
20
use Spiral\Database\Query\SelectQuery;
21
22
/**
23
 * Loads object sub-section (column subset).
24
 */
25
final class EmbeddedLoader implements JoinableInterface
26
{
27
    use ColumnsTrait;
28
29
    /** @var ORMInterface */
30
    private $orm;
31
32
    /** @var string */
33
    private $target;
34
35
    /** @var LoaderInterface */
36
    private $parent;
37
38
    /** @var array */
39
    private $options = ['load' => false, 'minify' => true];
40
41
    /** @var array */
42
    private $columns = [];
43
44
    /**
45
     * @param ORMInterface $orm
46
     * @param string       $target
47
     */
48
    public function __construct(ORMInterface $orm, string $target)
49
    {
50
        $this->orm = $orm;
51
        $this->target = $target;
52
53
        // never duplicate primary key in data selection
54
        $primaryKey = $this->define(Schema::PRIMARY_KEY);
55
        foreach ($this->define(Schema::COLUMNS) as $internal => $external) {
56
            if ($internal !== $primaryKey && $external !== $primaryKey) {
57
                $this->columns[$internal] = $external;
58
            }
59
        }
60
    }
61
62
    /**
63
     * @inheritDoc
64
     */
65
    public function getAlias(): string
66
    {
67
        // always fallback to parent table name
68
        return $this->parent->getAlias();
69
    }
70
71
    /**
72
     * @inheritDoc
73
     */
74
    public function getTarget(): string
75
    {
76
        return $this->target;
77
    }
78
79
    /**
80
     * @inheritDoc
81
     */
82
    public function withContext(LoaderInterface $parent, array $options = []): LoaderInterface
83
    {
84
        $loader = clone $this;
85
        $loader->parent = $parent;
86
        $loader->options = $options + $this->options;
87
88
        return $loader;
89
    }
90
91
    /**
92
     * @inheritDoc
93
     */
94
    public function isJoined(): bool
95
    {
96
        return true;
97
    }
98
99
    /**
100
     * Indication that loader want to load data.
101
     *
102
     * @return bool
103
     */
104
    public function isLoaded(): bool
105
    {
106
        return $this->options['load'] ?? false;
107
    }
108
109
    /**
110
     * @inheritDoc
111
     */
112
    public function configureQuery(SelectQuery $query, array $outerKeys = []): SelectQuery
113
    {
114
        if ($this->isLoaded()) {
115
            $this->mountColumns($query, $this->options['minify'] ?? true);
116
        }
117
118
        return $query;
119
    }
120
121
    /**
122
     * @inheritDoc
123
     */
124
    public function createNode(): AbstractNode
125
    {
126
        $node = new EmbeddedNode(
127
            $this->columnNames(),
128
            $this->orm->getSchema()->define($this->parent->getTarget(), Schema::PRIMARY_KEY)
129
        );
130
131
        $typecast = $this->define(Schema::TYPECAST);
132
        if ($typecast !== null) {
133
            $node->setTypecast(new Typecast(
134
                $typecast,
135
                $this->orm->getSource($this->parent->getTarget())->getDatabase()
136
            ));
137
        }
138
139
        return $node;
140
    }
141
142
    /**
143
     * @inheritDoc
144
     */
145
    public function loadData(AbstractNode $node)
146
    {
147
        // embedded entities does not support inner loaders... for now!
148
    }
149
150
    /**
151
     * Ensure state of every nested loader.
152
     */
153
    public function __clone()
154
    {
155
        $this->parent = null;
156
    }
157
158
    /**
159
     * Destruct loader.
160
     */
161
    final public function __destruct()
162
    {
163
        $this->parent = null;
164
    }
165
166
    /**
167
     * @return array
168
     */
169
    protected function getColumns(): array
170
    {
171
        return $this->columns;
172
    }
173
174
    /**
175
     * Define schema option associated with the entity.
176
     *
177
     * @param int $property
178
     * @return mixed
179
     */
180
    protected function define(int $property)
181
    {
182
        return $this->orm->getSchema()->define($this->target, $property);
183
    }
184
}