Passed
Push — master ( c90fcd...a1da5a )
by Petr
09:07
created

AConnector::child()   C

Complexity

Conditions 12
Paths 33

Size

Total Lines 58
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 12.0043

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 35
c 1
b 0
f 0
nc 33
nop 4
dl 0
loc 58
ccs 31
cts 32
cp 0.9688
crap 12.0043
rs 6.9666

How to fix   Long Method    Complexity   

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\Search\Connector;
4
5
6
use kalanis\kw_mapper\Interfaces\IQueryBuilder;
7
use kalanis\kw_mapper\MapperException;
8
use kalanis\kw_mapper\Mappers\Shared\ForeignKey;
9
use kalanis\kw_mapper\Records\ARecord;
10
use kalanis\kw_mapper\Storage;
11
12
13
/**
14
 * Class AConnector
15
 * @package kalanis\kw_mapper\Search
16
 * Connect real sources into search engine
17
 */
18
abstract class AConnector
19
{
20
    use Database\TRecordsInJoins;
21
22
    protected ARecord $basicRecord;
23
    protected Storage\Shared\QueryBuilder $queryBuilder;
24
25
    /**
26
     * @param string $table
27
     * @param string $column
28
     * @param string|float|int $value
29
     * @throws MapperException
30
     * @return $this
31
     */
32 1
    public function notExact(string $table, string $column, $value): self
33
    {
34 1
        $aTable = $this->correctTable($table);
35 1
        $this->getQueryBuilder()->addCondition(
36 1
            $aTable,
37 1
            $this->correctColumn($aTable, $column),
38 1
            IQueryBuilder::OPERATION_NEQ,
39
            $value
40
        );
41 1
        return $this;
42
    }
43
44
    /**
45
     * @param string $table
46
     * @param string $column
47
     * @param string|float|int $value
48
     * @throws MapperException
49
     * @return $this
50
     */
51 8
    public function exact(string $table, string $column, $value): self
52
    {
53 8
        $aTable = $this->correctTable($table);
54 8
        $this->getQueryBuilder()->addCondition(
55 8
            $aTable,
56 8
            $this->correctColumn($aTable, $column),
57 7
            IQueryBuilder::OPERATION_EQ,
58
            $value
59
        );
60 7
        return $this;
61
    }
62
63
    /**
64
     * @param string $table
65
     * @param string $column
66
     * @param string|float|int $value
67
     * @param bool $equals
68
     * @throws MapperException
69
     * @return $this
70
     */
71 1
    public function from(string $table, string $column, $value, bool $equals = true): self
72
    {
73 1
        $aTable = $this->correctTable($table);
74 1
        $this->getQueryBuilder()->addCondition(
75 1
            $aTable,
76 1
            $this->correctColumn($aTable, $column),
77 1
            $equals ? IQueryBuilder::OPERATION_GTE : IQueryBuilder::OPERATION_GT,
78
            $value
79
        );
80 1
        return $this;
81
    }
82
83
    /**
84
     * @param string $table
85
     * @param string $column
86
     * @param string|float|int $value
87
     * @param bool $equals
88
     * @throws MapperException
89
     * @return $this
90
     */
91 1
    public function to(string $table, string $column, $value, bool $equals = true): self
92
    {
93 1
        $aTable = $this->correctTable($table);
94 1
        $this->getQueryBuilder()->addCondition(
95 1
            $aTable,
96 1
            $this->correctColumn($aTable, $column),
97 1
            $equals ? IQueryBuilder::OPERATION_LTE : IQueryBuilder::OPERATION_LT,
98
            $value
99
        );
100 1
        return $this;
101
    }
102
103
    /**
104
     * @param string $table
105
     * @param string $column
106
     * @param string $value
107
     * @throws MapperException
108
     * @return $this
109
     */
110 7
    public function like(string $table, string $column, $value): self
111
    {
112 7
        $aTable = $this->correctTable($table);
113 7
        $this->getQueryBuilder()->addCondition(
114 7
            $aTable,
115 7
            $this->correctColumn($aTable, $column),
116 6
            IQueryBuilder::OPERATION_LIKE,
117
            $value
118
        );
119 6
        return $this;
120
    }
121
122
    /**
123
     * @param string $table
124
     * @param string $column
125
     * @param string $value
126
     * @throws MapperException
127
     * @return $this
128
     */
129 2
    public function notLike(string $table, string $column, $value): self
130
    {
131 2
        $aTable = $this->correctTable($table);
132 2
        $this->getQueryBuilder()->addCondition(
133 2
            $aTable,
134 2
            $this->correctColumn($aTable, $column),
135 2
            IQueryBuilder::OPERATION_NLIKE,
136
            $value
137
        );
138 2
        return $this;
139
    }
140
141
    /**
142
     * @param string $table
143
     * @param string $column
144
     * @param string $pattern
145
     * @throws MapperException
146
     * @return $this
147
     */
148 1
    public function regexp(string $table, string $column, string $pattern): self
149
    {
150 1
        $aTable = $this->correctTable($table);
151 1
        $this->getQueryBuilder()->addCondition(
152 1
            $aTable,
153 1
            $this->correctColumn($aTable, $column),
154 1
            IQueryBuilder::OPERATION_REXP,
155
            $pattern
156
        );
157 1
        return $this;
158
    }
159
160
    /**
161
     * @param string $table
162
     * @param string $column
163
     * @param string $min
164
     * @param string $max
165
     * @throws MapperException
166
     * @return $this
167
     */
168 1
    public function between(string $table, string $column, $min, $max): self
169
    {
170 1
        $aTable = $this->correctTable($table);
171 1
        $this->getQueryBuilder()->addCondition($aTable, $this->correctColumn($aTable, $column), IQueryBuilder::OPERATION_GTE, $min);
172 1
        $this->getQueryBuilder()->addCondition($aTable, $this->correctColumn($aTable, $column), IQueryBuilder::OPERATION_LTE, $max);
173 1
        return $this;
174
    }
175
176
    /**
177
     * @param string $table
178
     * @param string $column
179
     * @throws MapperException
180
     * @return $this
181
     */
182 1
    public function null(string $table, string $column): self
183
    {
184 1
        $aTable = $this->correctTable($table);
185 1
        $this->getQueryBuilder()->addCondition(
186 1
            $aTable,
187 1
            $this->correctColumn($aTable, $column),
188 1
            IQueryBuilder::OPERATION_NULL
189
        );
190 1
        return $this;
191
    }
192
193
    /**
194
     * @param string $table
195
     * @param string $column
196
     * @throws MapperException
197
     * @return $this
198
     */
199 1
    public function notNull(string $table, string $column): self
200
    {
201 1
        $aTable = $this->correctTable($table);
202 1
        $this->getQueryBuilder()->addCondition(
203 1
            $aTable,
204 1
            $this->correctColumn($aTable, $column),
205 1
            IQueryBuilder::OPERATION_NNULL
206
        );
207 1
        return $this;
208
    }
209
210
    /**
211
     * @param string $table
212
     * @param string $column
213
     * @param array<string|int|float> $values
214
     * @throws MapperException
215
     * @return $this
216
     */
217 1
    public function in(string $table, string $column, array $values): self
218
    {
219 1
        $aTable = $this->correctTable($table);
220 1
        $this->getQueryBuilder()->addCondition(
221 1
            $aTable,
222 1
            $this->correctColumn($aTable, $column),
223 1
            IQueryBuilder::OPERATION_IN,
224
            $values
225
        );
226 1
        return $this;
227
    }
228
229
    /**
230
     * @param string $table
231
     * @param string $column
232
     * @param array<string|int|float> $values
233
     * @throws MapperException
234
     * @return $this
235
     */
236 1
    public function notIn(string $table, string $column, array $values): self
237
    {
238 1
        $aTable = $this->correctTable($table);
239 1
        $this->getQueryBuilder()->addCondition(
240 1
            $aTable,
241 1
            $this->correctColumn($aTable, $column),
242 1
            IQueryBuilder::OPERATION_NIN,
243
            $values
244
        );
245 1
        return $this;
246
    }
247
248 1
    public function useAnd(): self
249
    {
250 1
        $this->getQueryBuilder()->setRelations(IQueryBuilder::RELATION_AND);
251 1
        return $this;
252
    }
253
254 1
    public function useOr(): self
255
    {
256 1
        $this->getQueryBuilder()->setRelations(IQueryBuilder::RELATION_OR);
257 1
        return $this;
258
    }
259
260 1
    public function limit(?int $limit): self
261
    {
262 1
        $this->getQueryBuilder()->setLimit($limit);
263 1
        return $this;
264
    }
265
266 1
    public function offset(?int $offset): self
267
    {
268 1
        $this->getQueryBuilder()->setOffset($offset);
269 1
        return $this;
270
    }
271
272
    /**
273
     * Add ordering by
274
     * @param string $table
275
     * @param string $column
276
     * @param string $direction
277
     * @throws MapperException
278
     * @return $this
279
     */
280 1
    public function orderBy(string $table, string $column, string $direction = IQueryBuilder::ORDER_ASC): self
281
    {
282 1
        $aTable = $this->correctTable($table);
283 1
        $this->getQueryBuilder()->addOrderBy($aTable, $this->correctColumn($aTable, $column), $direction);
284 1
        return $this;
285
    }
286
287
    /**
288
     * Add grouping by
289
     * @param string $table
290
     * @param string $column
291
     * @throws MapperException
292
     * @return $this
293
     */
294 1
    public function groupBy(string $table, string $column): self
295
    {
296 1
        $aTable = $this->correctTable($table);
297 1
        $this->getQueryBuilder()->addGroupBy($aTable, $this->correctColumn($aTable, $column));
298 1
        return $this;
299
    }
300
301
    /**
302
     * Add child which will be mounted to results
303
     * @param string $childAlias
304
     * @param string $joinType
305
     * @param string $parentAlias
306
     * @param string $customAlias
307
     * @throws MapperException
308
     * @return $this
309
     */
310 9
    public function child(string $childAlias, string $joinType = IQueryBuilder::JOIN_LEFT, string $parentAlias = '', string $customAlias = ''): self
311
    {
312
        // from mapper - children's mapper then there table name
313 9
        if (!empty($parentAlias)) {
314 3
            $parentLookup = $this->recordLookup($parentAlias);
315 3
            if ($parentLookup && $parentLookup->getRecord()) {
316 3
                $parentRecord = $parentLookup->getRecord();
317
            }
318
        } else {
319 8
            $parentRecord = $this->getBasicRecord();
320 8
            $parentAlias = $parentRecord->getMapper()->getAlias();
321
        }
322 9
        if (empty($parentRecord)) {
323 1
            throw new MapperException(sprintf('Unknown record for parent alias *%s*', $parentAlias));
324
        }
325
326
        /** @var array<string|int, ForeignKey> $parentKeys */
327 8
        $parentKeys = $parentRecord->getMapper()->getForeignKeys();
328 8
        if (!isset($parentKeys[$childAlias])) {
329 1
            throw new MapperException(sprintf('Unknown alias *%s* in mapper for parent *%s*', $childAlias, $parentAlias));
330
        }
331
332 8
        $parentKey = $parentKeys[$childAlias];
333 8
        $parentRelations = $parentRecord->getMapper()->getRelations();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $parentRecord does not seem to be defined for all execution paths leading up to this point.
Loading history...
334 8
        if (empty($parentRelations[$parentKey->getLocalEntryKey()])) {
335 1
            throw new MapperException(sprintf('Unknown relation key *%s* in mapper for parent *%s*', $parentKey->getLocalEntryKey(), $parentAlias));
336
        }
337
338 7
        $childTableAlias = empty($customAlias) ? $childAlias : $customAlias;
339 7
        $childLookup = $this->recordLookup($childTableAlias, $childAlias);
340 7
        if (empty($childLookup) || empty($childLookup->getRecord())) {
341
            // might never happens - part already checked, so it must exists
342
            // @codeCoverageIgnoreStart
343
            throw new MapperException(sprintf('Unknown record for child alias *%s*', $childAlias));
344
        }
345
        // @codeCoverageIgnoreEnd
346
347 7
        $childRecord = $childLookup->getRecord();
348 7
        $childRelations = $childRecord->getMapper()->getRelations();
349 7
        if (empty($childRelations[$parentKey->getRemoteEntryKey()])) {
350 1
            throw new MapperException(sprintf('Unknown relation key *%s* in mapper for child *%s*', $parentKey->getRemoteEntryKey(), $childAlias));
351
        }
352
353 6
        if ($parentRecord->getMapper()->getSource() != $childRecord->getMapper()->getSource()) {
354 1
            throw new MapperException(sprintf('Parent *%s* and child *%s* must both have the same source', $parentAlias, $childAlias));
355
        }
356
357 5
        $this->getQueryBuilder()->addJoin(
358 5
            $childAlias,
359 5
            $childRecord->getMapper()->getAlias(),
360 5
            $childRelations[$parentKey->getRemoteEntryKey()],
361
            $parentAlias,
362 5
            $parentRelations[$parentKey->getLocalEntryKey()],
363
            $joinType,
364
            $childTableAlias
365
        );
366
367 4
        return $this;
368
    }
369
370
    /**
371
     * That child is not set for chosen parent
372
     * @param string $childAlias
373
     * @param string $table
374
     * @param string $column
375
     * @param string $parentAlias
376
     * @throws MapperException
377
     * @return $this
378
     */
379 2
    public function childNotExist(string $childAlias, string $table, string $column, string $parentAlias = ''): self
380
    {
381 2
        $this->child($childAlias, IQueryBuilder::JOIN_LEFT_OUTER, $parentAlias);
382 1
        $aTable = $this->correctTable($table);
383 1
        $this->getQueryBuilder()->addCondition(
384 1
            $aTable,
385 1
            $this->correctColumn($aTable, $column),
386 1
            IQueryBuilder::OPERATION_NULL
387
        );
388 1
        return $this;
389
    }
390
391
    /**
392
     * Return count of all records selected by params
393
     * @throws MapperException
394
     * @return int
395
     */
396
    abstract public function getCount(): int;
397
398
    /**
399
     * Return records
400
     * @throws MapperException
401
     * @return ARecord[]
402
     */
403
    abstract public function getResults(): array;
404
405
    /**
406
     * @param string $table
407
     * @throws MapperException
408
     * @return string
409
     */
410 8
    protected function correctTable(string $table): string
411
    {
412 8
        return empty($table) ? $this->getBasicRecord()->getMapper()->getAlias() : $table ;
413
    }
414
415
    /**
416
     * @param string $table
417
     * @param string $column
418
     * @throws MapperException
419
     * @return string|int
420
     */
421 8
    protected function correctColumn(string $table, string $column)
422
    {
423 8
        $record = !empty($table) ? $this->recordLookup($table)->getRecord() : $this->getBasicRecord() ;
424 8
        if (empty($record)) {
425
            // @codeCoverageIgnoreStart
426
            throw new MapperException(sprintf('Unknown relation table *%s*', $table));
427
        }
428
        // @codeCoverageIgnoreEnd
429 8
        $relations = $record->getMapper()->getRelations();
430 8
        if (empty($relations[$column])) {
431 1
            throw new MapperException(sprintf('Unknown relation key *%s* in mapper for table *%s*', $column, $table));
432
        }
433 7
        return $relations[$column];
434
    }
435
436 28
    private function getQueryBuilder(): Storage\Shared\QueryBuilder
437
    {
438 28
        return $this->queryBuilder;
439
    }
440
441 13
    private function getBasicRecord(): ARecord
442
    {
443 13
        return $this->basicRecord;
444
    }
445
}
446