Passed
Push — master ( 02118d...11fb63 )
by Petr
03:00
created

TReadDatabase::countRecord()   B

Complexity

Conditions 8
Paths 18

Size

Total Lines 57
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 8.0021

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 33
c 1
b 0
f 0
nc 18
nop 1
dl 0
loc 57
ccs 30
cts 31
cp 0.9677
crap 8.0021
rs 8.1475

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace kalanis\kw_mapper\Mappers\Database;
4
5
6
use kalanis\kw_mapper\Interfaces\IQueryBuilder;
7
use kalanis\kw_mapper\MapperException;
8
use kalanis\kw_mapper\Mappers\Shared\TEntityChanged;
9
use kalanis\kw_mapper\Records\ARecord;
10
use kalanis\kw_mapper\Records\TFill;
11
use kalanis\kw_mapper\Storage\Database;
12
13
14
/**
15
 * Trait TReadDatabase
16
 * @package kalanis\kw_mapper\Mappers\Database
17
 * Separated read DB entry without need to reload mapper
18
 *
19
 * Contains only operations for reading from DB
20
 */
21
trait TReadDatabase
22
{
23
    use TEntityChanged;
24
    use TFill;
25
26
    /** @var string */
27
    protected $readSource = '';
28
    /** @var Database\ASQL */
29
    protected $readDatabase = null;
30
    /** @var Database\Dialects\ADialect */
31
    protected $readDialect = null;
32
    /** @var Database\QueryBuilder */
33
    protected $readQueryBuilder = null;
34
35
    /**
36
     * @throws MapperException
37
     */
38 16
    protected function initTReadDatabase(): void
39
    {
40 16
        $this->readDatabase = $this->getReadDatabase();
41 16
        $this->readDialect = $this->getReadDialect($this->readDatabase);
42 16
        $this->readQueryBuilder = $this->getReadQueryBuilder($this->readDialect);
43 16
    }
44
45 4
    protected function setReadSource(string $readSource): void
46
    {
47 4
        $this->readSource = $readSource;
48 4
    }
49
50 4
    protected function getReadSource(): string
51
    {
52 4
        return $this->readSource;
53
    }
54
55
    /**
56
     * @throws MapperException
57
     * @return Database\ADatabase
58
     */
59 16
    protected function getReadDatabase(): Database\ADatabase
60
    {
61 16
        return Database\DatabaseSingleton::getInstance()->getDatabase(
62 16
            Database\ConfigStorage::getInstance()->getConfig($this->getReadSource())
63
        );
64
    }
65
66
    /**
67
     * @param Database\ADatabase $database
68
     * @throws MapperException
69
     * @return Database\Dialects\ADialect
70
     */
71 16
    protected function getReadDialect(Database\ADatabase $database): Database\Dialects\ADialect
72
    {
73 16
        return Database\Dialects\Factory::getInstance()->getDialectClass($database->languageDialect());
74
    }
75
76 16
    protected function getReadQueryBuilder(Database\Dialects\ADialect $dialect): Database\QueryBuilder
77
    {
78 16
        return new Database\QueryBuilder($dialect);
79
    }
80
81
    /**
82
     * @param ARecord $record
83
     * @throws MapperException
84
     * @return bool
85
     */
86 6
    protected function loadRecord(ARecord $record): bool
87
    {
88 6
        if ($this->loadRecordByPk($record)) {
89 3
            return true;
90
        }
91
92 6
        $this->readQueryBuilder->clear();
93 6
        $this->readQueryBuilder->setBaseTable($record->getMapper()->getAlias());
94 6
        $relations = $record->getMapper()->getRelations();
95
96
        // conditions - must be equal
97 6
        foreach ($record as $key => $item) {
98 6
            if (isset($relations[$key]) && $this->ifEntryChanged($record->getEntry($key))) {
99 5
                $this->readQueryBuilder->addCondition(
100 5
                    $record->getMapper()->getAlias(),
101 5
                    $relations[$key],
102 5
                    IQueryBuilder::OPERATION_EQ,
103
                    $item
104
                );
105
            }
106
        }
107
108
        // relations - what to get
109 6
        foreach ($relations as $localAlias => $remoteColumn) {
110 6
            $this->readQueryBuilder->addColumn($record->getMapper()->getAlias(), $remoteColumn, $localAlias);
111
        }
112 6
        $this->readQueryBuilder->setLimits(0,1);
113
114
        // query itself
115 6
        $lines = $this->readDatabase->query(
116 6
            strval($this->readDialect->select($this->readQueryBuilder)),
117 6
            $this->readQueryBuilder->getParams()
118
        );
119 6
        if (empty($lines)) {
120 3
            return false;
121
        }
122
123
        // fill entries in record
124 3
        $line = reset($lines);
125 3
        foreach ($line as $index => $item) {
126 3
            $entry = $record->getEntry($index);
127 3
            $entry->setData($this->typedFillSelection($entry, $item), true);
128
        }
129 3
        return true;
130
    }
131
132
    /**
133
     * @param ARecord $record
134
     * @throws MapperException
135
     * @return bool
136
     */
137 10
    protected function loadRecordByPk(ARecord $record): bool
138
    {
139 10
        if (empty($record->getMapper()->getPrimaryKeys())) {
140 3
            return false;
141
        }
142
143 8
        $this->readQueryBuilder->clear();
144 8
        $this->readQueryBuilder->setBaseTable($record->getMapper()->getAlias());
145 8
        $relations = $record->getMapper()->getRelations();
146
147
        // conditions - everything must be equal
148 8
        foreach ($record->getMapper()->getPrimaryKeys() as $key) {
149
            try {
150 8
                if (isset($relations[$key]) && $this->ifEntryChanged($record->getEntry($key))) {
151 5
                    $this->readQueryBuilder->addCondition(
152 5
                        $record->getMapper()->getAlias(),
153 5
                        $relations[$key],
154 5
                        IQueryBuilder::OPERATION_EQ,
155 6
                        $record->offsetGet($key)
156
                    );
157
                }
158 3
            } catch (MapperException $ex) {
159 3
                return false;
160
            }
161
        }
162
163 6
        if (empty($this->readQueryBuilder->getConditions())) { // no conditions, nothing in PKs - back to normal system
164 3
            return false;
165
        }
166
167
        // relations - what to get
168 5
        foreach ($relations as $localAlias => $remoteColumn) {
169 5
            $this->readQueryBuilder->addColumn($record->getMapper()->getAlias(), $remoteColumn, $localAlias);
170
        }
171
172
        // query itself
173 5
        $this->readQueryBuilder->setLimits(0,1);
174 5
        $lines = $this->readDatabase->query(
175 5
            strval($this->readDialect->select($this->readQueryBuilder)),
176 5
            $this->readQueryBuilder->getParams()
177
        );
178 5
        if (empty($lines)) {
179 2
            return false;
180
        }
181
182
        // fill entries in record
183 3
        $line = reset($lines);
184 3
        foreach ($line as $index => $item) {
185 3
            $entry = $record->getEntry($index);
186 3
            $entry->setData($this->typedFillSelection($entry, $item), true);
187
        }
188 3
        return true;
189
    }
190
191
    /**
192
     * @param ARecord $record
193
     * @throws MapperException
194
     * @return int
195
     */
196 4
    public function countRecord(ARecord $record): int
197
    {
198 4
        $this->readQueryBuilder->clear();
199 4
        $this->readQueryBuilder->setBaseTable($record->getMapper()->getAlias());
200 4
        $relations = $record->getMapper()->getRelations();
201
202 4
        foreach ($record as $key => $item) {
203 4
            if (isset($relations[$key]) && $this->ifEntryChanged($record->getEntry($key))) {
204 4
                $this->readQueryBuilder->addCondition(
205 4
                    $record->getMapper()->getAlias(),
206 4
                    $relations[$key],
207 4
                    IQueryBuilder::OPERATION_EQ,
208
                    $item
209
                );
210
            }
211
        }
212
213 4
        if (empty($record->getMapper()->getPrimaryKeys())) {
214 2
            $relation = reset($relations);
215 2
            if (false !== $relation) {
216 2
                $this->readQueryBuilder->addColumn(
217 2
                    $record->getMapper()->getAlias(),
218
                    $relation,
219 2
                    'count',
220 2
                    IQueryBuilder::AGGREGATE_COUNT
221
                );
222
            }
223
        } else {
224
//            foreach ($record->getMapper()->getPrimaryKeys() as $primaryKey) {
225
//                $this->readQueryBuilder->addColumn(
226
//                    $record->getMapper()->getAlias(),
227
//                    $primaryKey,
228
//                    '',
229
//                    IQueryBuilder::AGGREGATE_COUNT
230
//                );
231
//            }
232 3
            $pks = $record->getMapper()->getPrimaryKeys();
233 3
            $key = reset($pks);
234 3
            $this->readQueryBuilder->addColumn(
235 3
                $record->getMapper()->getAlias(),
236 3
                $relations[$key],
237 3
                'count',
238 3
                IQueryBuilder::AGGREGATE_COUNT
239
            );
240
        }
241
242 4
        $lines = $this->readDatabase->query(
243 4
            strval($this->readDialect->select($this->readQueryBuilder)),
244 4
            $this->readQueryBuilder->getParams()
245
        );
246 4
        if (empty($lines) || !is_iterable($lines)) {
247
            // @codeCoverageIgnoreStart
248
            return 0;
249
        }
250
        // @codeCoverageIgnoreEnd
251 4
        $line = reset($lines);
252 4
        return intval(reset($line));
253
    }
254
255
    /**
256
     * @param ARecord $record
257
     * @throws MapperException
258
     * @return ARecord[]
259
     */
260 5
    public function loadMultiple(ARecord $record): array
261
    {
262 5
        $this->readQueryBuilder->clear();
263 5
        $this->readQueryBuilder->setBaseTable($record->getMapper()->getAlias());
264 5
        $relations = $record->getMapper()->getRelations();
265
266 5
        foreach ($record as $key => $item) {
267 5
            if (isset($relations[$key]) && $this->ifEntryChanged($record->getEntry($key))) {
268 5
                $this->readQueryBuilder->addCondition(
269 5
                    $record->getMapper()->getAlias(),
270 5
                    $relations[$key],
271 5
                    IQueryBuilder::OPERATION_EQ,
272
                    $item
273
                );
274
            }
275
        }
276
277
        // relations - what to get
278 5
        foreach ($relations as $localAlias => $remoteColumn) {
279 5
            $this->readQueryBuilder->addColumn($record->getMapper()->getAlias(), $remoteColumn, $localAlias);
280
        }
281
282
        // query itself
283 5
        $lines = $this->readDatabase->query(
284 5
            strval($this->readDialect->select($this->readQueryBuilder)),
285 5
            $this->readQueryBuilder->getParams()
286
        );
287 5
        if (empty($lines)) {
288 2
            return [];
289
        }
290
291 3
        $result = [];
292 3
        foreach ($lines as $line) {
293 3
            $rec = clone $record;
294 3
            foreach ($line as $index => $item) {
295 3
                $entry = $rec->getEntry($index);
296 3
                $entry->setData($this->typedFillSelection($entry, $item), true);
297
            }
298 3
            $result[] = $rec;
299
        }
300 3
        return $result;
301
    }
302
}
303