Passed
Push — master ( 6139d1...678a4c )
by Petr
13:22 queued 10:27
created

AConnector::child()   C

Complexity

Conditions 12
Paths 33

Size

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