Passed
Push — master ( ccfde0...23ae65 )
by Petr
09:08
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
    /**
249
     * @param string|string[]|callable $operation
250
     * @param string $prefix
251
     * @param mixed $value
252
     * @return $this
253
     */
254
    public function raw($operation, string $prefix = '', $value = null): self
255
    {
256
        $this->getQueryBuilder()->addRawCondition(
257
            $operation,
258
            $prefix,
259
            $value
260
        );
261
        return $this;
262
    }
263
264 1
    public function useAnd(): self
265
    {
266 1
        $this->getQueryBuilder()->setRelations(IQueryBuilder::RELATION_AND);
267 1
        return $this;
268
    }
269
270 1
    public function useOr(): self
271
    {
272 1
        $this->getQueryBuilder()->setRelations(IQueryBuilder::RELATION_OR);
273 1
        return $this;
274
    }
275
276 1
    public function limit(?int $limit): self
277
    {
278 1
        $this->getQueryBuilder()->setLimit($limit);
279 1
        return $this;
280
    }
281
282 1
    public function offset(?int $offset): self
283
    {
284 1
        $this->getQueryBuilder()->setOffset($offset);
285 1
        return $this;
286
    }
287
288
    /**
289
     * Add ordering by
290
     * @param string $table
291
     * @param string $column
292
     * @param string $direction
293
     * @throws MapperException
294
     * @return $this
295
     */
296 1
    public function orderBy(string $table, string $column, string $direction = IQueryBuilder::ORDER_ASC): self
297
    {
298 1
        $aTable = $this->correctTable($table);
299 1
        $this->getQueryBuilder()->addOrderBy($aTable, $this->correctColumn($aTable, $column), $direction);
300 1
        return $this;
301
    }
302
303
    /**
304
     * Add grouping by
305
     * @param string $table
306
     * @param string $column
307
     * @throws MapperException
308
     * @return $this
309
     */
310 1
    public function groupBy(string $table, string $column): self
311
    {
312 1
        $aTable = $this->correctTable($table);
313 1
        $this->getQueryBuilder()->addGroupBy($aTable, $this->correctColumn($aTable, $column));
314 1
        return $this;
315
    }
316
317
    /**
318
     * Add child which will be mounted to results
319
     * @param string $childAlias
320
     * @param string $joinType
321
     * @param string $parentAlias
322
     * @param string $customAlias
323
     * @throws MapperException
324
     * @return $this
325
     */
326 9
    public function child(string $childAlias, string $joinType = IQueryBuilder::JOIN_LEFT, string $parentAlias = '', string $customAlias = ''): self
327
    {
328
        // from mapper - children's mapper then there table name
329 9
        if (!empty($parentAlias)) {
330 3
            $parentLookup = $this->recordLookup($parentAlias);
331 3
            if ($parentLookup && $parentLookup->getRecord()) {
332 3
                $parentRecord = $parentLookup->getRecord();
333
            }
334
        } else {
335 8
            $parentRecord = $this->getBasicRecord();
336 8
            $parentAlias = $parentRecord->getMapper()->getAlias();
337
        }
338 9
        if (empty($parentRecord)) {
339 1
            throw new MapperException(sprintf('Unknown record for parent alias *%s*', $parentAlias));
340
        }
341
342
        /** @var array<string|int, ForeignKey> $parentKeys */
343 8
        $parentKeys = $parentRecord->getMapper()->getForeignKeys();
344 8
        if (!isset($parentKeys[$childAlias])) {
345 1
            throw new MapperException(sprintf('Unknown alias *%s* in mapper for parent *%s*', $childAlias, $parentAlias));
346
        }
347
348 8
        $parentKey = $parentKeys[$childAlias];
349 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...
350 8
        if (empty($parentRelations[$parentKey->getLocalEntryKey()])) {
351 1
            throw new MapperException(sprintf('Unknown relation key *%s* in mapper for parent *%s*', $parentKey->getLocalEntryKey(), $parentAlias));
352
        }
353
354 7
        $childTableAlias = empty($customAlias) ? $childAlias : $customAlias;
355 7
        $childLookup = $this->recordLookup($childTableAlias, $childAlias);
356 7
        if (empty($childLookup) || empty($childLookup->getRecord())) {
357
            // might never happens - part already checked, so it must exists
358
            // @codeCoverageIgnoreStart
359
            throw new MapperException(sprintf('Unknown record for child alias *%s*', $childAlias));
360
        }
361
        // @codeCoverageIgnoreEnd
362
363 7
        $childRecord = $childLookup->getRecord();
364 7
        $childRelations = $childRecord->getMapper()->getRelations();
365 7
        if (empty($childRelations[$parentKey->getRemoteEntryKey()])) {
366 1
            throw new MapperException(sprintf('Unknown relation key *%s* in mapper for child *%s*', $parentKey->getRemoteEntryKey(), $childAlias));
367
        }
368
369 6
        if ($parentRecord->getMapper()->getSource() != $childRecord->getMapper()->getSource()) {
370 1
            throw new MapperException(sprintf('Parent *%s* and child *%s* must both have the same source', $parentAlias, $childAlias));
371
        }
372
373 5
        $this->getQueryBuilder()->addJoin(
374 5
            $childAlias,
375 5
            $childRecord->getMapper()->getAlias(),
376 5
            $childRelations[$parentKey->getRemoteEntryKey()],
377
            $parentAlias,
378 5
            $parentRelations[$parentKey->getLocalEntryKey()],
379
            $joinType,
380
            $childTableAlias
381
        );
382
383 4
        return $this;
384
    }
385
386
    /**
387
     * That child is not set for chosen parent
388
     * @param string $childAlias
389
     * @param string $table
390
     * @param string $column
391
     * @param string $parentAlias
392
     * @throws MapperException
393
     * @return $this
394
     */
395 2
    public function childNotExist(string $childAlias, string $table, string $column, string $parentAlias = ''): self
396
    {
397 2
        $this->child($childAlias, IQueryBuilder::JOIN_LEFT_OUTER, $parentAlias);
398 1
        $aTable = $this->correctTable($table);
399 1
        $this->getQueryBuilder()->addCondition(
400 1
            $aTable,
401 1
            $this->correctColumn($aTable, $column),
402 1
            IQueryBuilder::OPERATION_NULL
403
        );
404 1
        return $this;
405
    }
406
407
    /**
408
     * Return count of all records selected by params
409
     * @throws MapperException
410
     * @return int
411
     */
412
    abstract public function getCount(): int;
413
414
    /**
415
     * Return records
416
     * @throws MapperException
417
     * @return ARecord[]
418
     */
419
    abstract public function getResults(): array;
420
421
    /**
422
     * @param string $table
423
     * @throws MapperException
424
     * @return string
425
     */
426 8
    protected function correctTable(string $table): string
427
    {
428 8
        return empty($table) ? $this->getBasicRecord()->getMapper()->getAlias() : $table ;
429
    }
430
431
    /**
432
     * @param string $table
433
     * @param string $column
434
     * @throws MapperException
435
     * @return string|int
436
     */
437 8
    protected function correctColumn(string $table, string $column)
438
    {
439 8
        $record = !empty($table) ? $this->recordLookup($table)->getRecord() : $this->getBasicRecord() ;
440 8
        if (empty($record)) {
441
            // @codeCoverageIgnoreStart
442
            throw new MapperException(sprintf('Unknown relation table *%s*', $table));
443
        }
444
        // @codeCoverageIgnoreEnd
445 8
        $relations = $record->getMapper()->getRelations();
446 8
        if (empty($relations[$column])) {
447 1
            throw new MapperException(sprintf('Unknown relation key *%s* in mapper for table *%s*', $column, $table));
448
        }
449 7
        return $relations[$column];
450
    }
451
452 28
    protected function getQueryBuilder(): Storage\Shared\QueryBuilder
453
    {
454 28
        return $this->queryBuilder;
455
    }
456
457 13
    protected function getBasicRecord(): ARecord
458
    {
459 13
        return $this->basicRecord;
460
    }
461
}
462