Passed
Push — master ( 300fb2...9a33a3 )
by Smoren
01:41
created

TableCollection::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Smoren\QueryRelationManager\Base\Structs;
4
5
use Countable;
6
use IteratorAggregate;
7
use Smoren\QueryRelationManager\Base\QueryRelationManagerException;
8
9
/**
10
 * Class TableCollection
11
 * Класс-коллекция объектов таблиц, участвующих в запросе
12
 * @author Smoren <[email protected]>
13
 * @implements IteratorAggregate<Table>
14
 */
15
class TableCollection implements Countable, IteratorAggregate
16
{
17
    /**
18
     * @var Table|null объект главной таблицы запроса
19
     */
20
    protected ?Table $mainTable = null;
21
22
    /**
23
     * @var Table[] карта объектов таблиц по псевдониму таблицы в запросе
24
     */
25
    protected array $mapByAlias = [];
26
27
    /**
28
     * Добавление объекта таблицы в коллецию
29
     * @param Table $table таблица, участвующая в запросе
30
     * @return $this
31
     * @throws QueryRelationManagerException
32
     */
33
    public function add(Table $table): self
34
    {
35
        if($this->mainTable === null) {
36
            $this->mainTable = $table;
37
        }
38
39
        $this->addToMap('mapByAlias', 'alias', $table);
40
41
        return $this;
42
    }
43
44
    /**
45
     * Получение объекта главной таблицы запроса
46
     * @return Table
47
     * @throws QueryRelationManagerException
48
     */
49
    public function getMainTable(): Table
50
    {
51
        if($this->mainTable === null) {
52
            throw new QueryRelationManagerException('no main table found in TableManager');
53
        }
54
55
        return $this->mainTable;
56
    }
57
58
    /**
59
     * Получение объекта таблицы по ее псевдониму в запросе
60
     * @param string $alias псевдоним таблицы в запросе
61
     * @return Table
62
     * @throws QueryRelationManagerException
63
     */
64
    public function byAlias(string $alias): Table
65
    {
66
        return $this->getFromMap('mapByAlias', $alias);
67
    }
68
69
    /**
70
     * Получение цепочки первичных ключей присоединяемых таблиц до данной
71
     * @param string $tableAlias
72
     * @param JoinConditionCollection $joinConditions
73
     * @return array<string>
74
     * @throws QueryRelationManagerException
75
     */
76
    public function getPkFieldChain(string $tableAlias, JoinConditionCollection $joinConditions): array
77
    {
78
        $tableAliasChain = $this->getTableAliasChain($tableAlias, $joinConditions);
79
        $result = [];
80
81
        foreach($tableAliasChain as $alias) {
82
            $table = $this->byAlias($alias);
83
84
            foreach($table->primaryKey as $field) {
85
                $result[] = "{$alias}_{$field}";
86
            }
87
        }
88
89
        return $result;
90
    }
91
92
    /**
93
     * Получение цепочки псеводнимов присоединяемых таблиц до данной
94
     * @param string $tableAlias
95
     * @param JoinConditionCollection $joinConditions
96
     * @return array<string>
97
     */
98
    public function getTableAliasChain(string $tableAlias, JoinConditionCollection $joinConditions): array
99
    {
100
        $result = [];
101
102
        while(true) {
103
            $result[] = $tableAlias;
104
105
            if(!$joinConditions->issetByJoinAs($tableAlias)) {
106
                break;
107
            }
108
109
            $tableAlias = $joinConditions->byJoinAs($tableAlias)->joinTo->alias;
110
        }
111
112
        return array_reverse($result);
113
    }
114
115
    /**
116
     * @inheritDoc
117
     * @return iterable<Table>
118
     */
119
    public function getIterator(): iterable
120
    {
121
        foreach($this->mapByAlias as $table) {
122
            yield $table;
123
        }
124
    }
125
126
    /**
127
     * @inheritDoc
128
     */
129
    public function count(): int
130
    {
131
        return count($this->mapByAlias);
132
    }
133
134
    /**
135
     * Добавление объекта таблицы в карту
136
     * @param string $mapName имя члена класса-карты
137
     * @param string $key ключ в карте
138
     * @param Table $table объект таблицы
139
     * @return $this
140
     * @throws QueryRelationManagerException
141
     */
142
    protected function addToMap(string $mapName, string $key, Table $table): self
143
    {
144
        if(isset($this->{$mapName}[$table->{$key}])) {
145
            throw new QueryRelationManagerException("duplicate key '{$key}' in map '{$mapName}' of TableManager");
146
        }
147
        $this->{$mapName}[$table->{$key}] = $table;
148
149
        return $this;
150
    }
151
152
    /**
153
     * Получение объекта таблицы из карты
154
     * @param string $mapName имя члена класса-карты
155
     * @param string $key ключ в карте
156
     * @return Table
157
     * @throws QueryRelationManagerException
158
     */
159
    protected function getFromMap(string $mapName, string $key): Table
160
    {
161
        if(!isset($this->{$mapName}[$key])) {
162
            throw new QueryRelationManagerException("key '{$key}' not found in map '{$mapName}' of TableManager");
163
        }
164
165
        return $this->{$mapName}[$key];
166
    }
167
}
168