Completed
Push — 2.x ( 1b5841...50a2d2 )
by Aleksei
22s queued 16s
created

RootLoader::getPrimaryFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\ORM\Select;
6
7
use Cycle\Database\Query\SelectQuery;
8
use Cycle\Database\StatementInterface;
9
use Cycle\ORM\FactoryInterface;
10
use Cycle\ORM\Parser\AbstractNode;
11
use Cycle\ORM\Parser\RootNode;
12
use Cycle\ORM\Service\SourceProviderInterface;
13
use Cycle\ORM\SchemaInterface;
14
use Cycle\ORM\Select\Traits\ColumnsTrait;
15
use Cycle\ORM\Select\Traits\ScopeTrait;
16
17
/**
18
 * Primary ORM loader. Loader wraps at top of select query in order to modify it's conditions, joins
19
 * and etc based on nested loaders.
20
 *
21
 * Root load does not load constrain from ORM by default.
22
 *
23
 * @method RootNode createNode()
24
 *
25
 * @internal
26
 */
27
final class RootLoader extends AbstractLoader
28
{
29
    use ColumnsTrait;
30
    use ScopeTrait;
31
32
    /** @var array */
33
    protected array $options = [
34
        'load' => true,
35
        'scope' => true,
36
    ];
37
38
    private SelectQuery $query;
39
40 6834
    public function __construct(
41
        SchemaInterface $ormSchema,
42
        SourceProviderInterface $sourceProvider,
43
        FactoryInterface $factory,
44
        string $target
45
    ) {
46 6834
        parent::__construct($ormSchema, $sourceProvider, $factory, $target);
47 6834
        $this->query = $this->source->getDatabase()->select()->from(
48 6834
            sprintf('%s AS %s', $this->source->getTable(), $this->getAlias())
49
        );
50 6834
        $this->columns = $this->normalizeColumns($this->define(SchemaInterface::COLUMNS));
51
52 6834
        foreach ($this->getEagerLoaders() as $relation) {
53 1288
            $this->loadRelation($relation, [], false, true);
54
        }
55
    }
56
57
    /**
58
     * Clone the underlying query.
59
     */
60 3232
    public function __clone()
61
    {
62 3232
        $this->query = clone $this->query;
63 3232
        parent::__clone();
64
    }
65
66 6834
    public function getAlias(): string
67
    {
68 6834
        return $this->target;
69
    }
70
71
    /**
72
     * Primary column name list with table name like `table.column`.
73
     *
74
     * @return string|string[]
75
     */
76 2152
    public function getPK(): array|string
77
    {
78 2152
        $pk = $this->define(SchemaInterface::PRIMARY_KEY);
79 2152
        if (\is_array($pk)) {
80 400
            $result = [];
81 400
            foreach ($pk as $key) {
82 400
                $result[] = $this->getAlias() . '.' . $this->fieldAlias($key);
83
            }
84 400
            return $result;
85
        }
86
87 1752
        return $this->getAlias() . '.' . $this->fieldAlias($pk);
88
    }
89
90
    /**
91
     * Get list of primary fields.
92
     *
93 6834
     * @return list<non-empty-string>
0 ignored issues
show
Bug introduced by
The type Cycle\ORM\Select\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
94
     */
95 6834
    public function getPrimaryFields(): array
96
    {
97
        return (array)$this->define(SchemaInterface::PRIMARY_KEY);
0 ignored issues
show
Bug Best Practice introduced by
The expression return (array)$this->def...Interface::PRIMARY_KEY) returns the type array which is incompatible with the documented return type Cycle\ORM\Select\list.
Loading history...
98
    }
99
100
    /**
101 6494
     * Return base query associated with the loader.
102
     */
103 6494
    public function getQuery(): SelectQuery
104
    {
105
        return $this->query;
106 6382
    }
107
108 6382
    /**
109
     * Compile query with all needed conditions, columns and etc.
110 6334
     */
111 6286
    public function buildQuery(): SelectQuery
112
    {
113
        return $this->configureQuery(clone $this->query);
114 6334
    }
115
116
    public function loadData(AbstractNode $node, bool $includeRole = false): void
117 6334
    {
118 3154
        $statement = $this->buildQuery()->run();
119
120
        foreach ($statement->fetchAll(StatementInterface::FETCH_NUM) as $row) {
121 6334
            $node->parseRow(0, $row);
122
        }
123
124 232
        $statement->close();
125
126
        // loading child datasets
127 232
        foreach ($this->load as $relation => $loader) {
128
            $loader->loadData($node->getNode($relation), $includeRole);
129
        }
130 6494
131
        $this->loadHierarchy($node, $includeRole);
132 6494
    }
133 6494
134
    public function isLoaded(): bool
135
    {
136
        // root loader is always loaded
137 6382
        return true;
138
    }
139 6382
140
    protected function configureQuery(SelectQuery $query): SelectQuery
141
    {
142
        return parent::configureQuery(
143
            $this->mountColumns($query, true, '', true)
144
        );
145
    }
146
147
    protected function initNode(): RootNode
148
    {
149
        return new RootNode($this->columnNames(), (array)$this->define(SchemaInterface::PRIMARY_KEY));
150
    }
151
}
152