TableCollection::count()   A
last analyzed

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
use Traversable;
9
10
/**
11
 * Collection of tables used in select-query
12
 * @author Smoren <[email protected]>
13
 * @implements IteratorAggregate<Table>
14
 */
15
class TableCollection implements Countable, IteratorAggregate
16
{
17
    /**
18
     * @var Table|null main table object
19
     */
20
    protected ?Table $mainTable = null;
21
22
    /**
23
     * @var Table[] map of tables indexed by table alias in query
24
     */
25
    protected array $mapByAlias = [];
26
27
    /**
28
     * Adds table object to the collection
29
     * @param Table $table table used in query
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
     * Returns main table of the query
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
     * Returns table object by it's alias in query
60
     * @param string $alias table alias in query
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
     * Returns chain of the primary key's fields of all the joined tables till given by alias
71
     * @param string $tableAlias table alias
72
     * @param JoinConditionCollection $joinConditions collection of join conditions
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
     * Returns chain of aliases of all the joined tables till given by alias
94
     * @param string $tableAlias table alias
95
     * @param JoinConditionCollection $joinConditions collection of join conditions
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 Traversable<Table>
118
     */
119
    public function getIterator(): Traversable
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
     * Adds table object to map
136
     * @param string $mapName name of the property stored the target map
137
     * @param string $key key to add by
138
     * @param Table $table table object to add
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
     * Returns table object from map
154
     * @param string $mapName name of the property stored the source map
155
     * @param string $key key to get by
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