Passed
Push — next ( bea07e...b4e6e6 )
by Bas
05:12 queued 01:45
created

CompilesUnions::compileUnions()   B

Complexity

Conditions 7
Paths 25

Size

Total Lines 39
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 7.0061

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 19
nc 25
nop 2
dl 0
loc 39
ccs 19
cts 20
cp 0.95
crap 7.0061
rs 8.8333
c 2
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LaravelFreelancerNL\Aranguent\Query\Concerns;
6
7
use Illuminate\Database\Query\Builder as IlluminateBuilder;
8
use LaravelFreelancerNL\Aranguent\Query\Builder;
9
10
trait CompilesUnions
11
{
12
    /**
13
     * Compile the "union" queries attached to the main query.
14
     *
15
     * @param Builder $query
16
     * @param string $firstQuery
17
     * @return string
18
     */
19 5
    protected function compileUnions(IlluminateBuilder $query, $firstQuery = '')
20
    {
21 5
        if (!is_array($query->unions)) {
22
            return '';
23
        }
24
25 5
        $unionResultsId = 'union' . $query->getQueryId() . 'Results';
26 5
        $unionDocId = 'union' . $query->getQueryId() . 'Result';
27
28 5
        $query->registerTableAlias($unionResultsId, $unionDocId);
29
30 5
        $firstQuery = $this->wrapSubquery($firstQuery);
0 ignored issues
show
Bug introduced by
It seems like wrapSubquery() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

30
        /** @scrutinizer ignore-call */ 
31
        $firstQuery = $this->wrapSubquery($firstQuery);
Loading history...
31
32 5
        $unions = '';
33
34 5
        foreach ($query->unions as $union) {
35 5
            $prefix = ($unions !== '') ? $unions : $firstQuery;
36 5
            $unions = $this->compileUnion($union, $prefix);
37
        }
38
39 5
        $aql = 'LET ' . $unionResultsId . ' = ' . $unions
40 5
            . ' FOR ' . $unionDocId . ' IN ' . $unionResultsId;
41
42
        // Union groups
43
44 5
        if (!empty($query->unionOrders)) {
45 2
            $aql .= ' ' . $this->compileOrders($query, $query->unionOrders, $unionResultsId);
0 ignored issues
show
Bug introduced by
It seems like compileOrders() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

45
            $aql .= ' ' . $this->/** @scrutinizer ignore-call */ compileOrders($query, $query->unionOrders, $unionResultsId);
Loading history...
46
        }
47
48 5
        if ($query->unionOffset) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $query->unionOffset of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
49 1
            $aql .= ' ' . $this->compileOffset($query, $query->unionOffset);
0 ignored issues
show
Bug introduced by
It seems like compileOffset() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

49
            $aql .= ' ' . $this->/** @scrutinizer ignore-call */ compileOffset($query, $query->unionOffset);
Loading history...
50
        }
51
52 5
        if ($query->unionLimit) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $query->unionLimit of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
53 1
            $aql .= ' ' . $this->compileLimit($query, $query->unionLimit);
0 ignored issues
show
Bug introduced by
The method compileLimit() does not exist on LaravelFreelancerNL\Aran...Concerns\CompilesUnions. Did you maybe mean compileUnion()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

53
            $aql .= ' ' . $this->/** @scrutinizer ignore-call */ compileLimit($query, $query->unionLimit);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
54
        }
55
56
        // Union aggregates?
57 5
        return $aql . ' RETURN ' . $unionDocId;
58
    }
59
60
    /**
61
     * Compile a single union statement.
62
     *
63
     * @param array<mixed> $union
64
     * @param string $aql
65
     * @return string
66
     */
67 5
    protected function compileUnion(array $union, string $aql = '')
68
    {
69 5
        $unionType = $union['all'] ? 'UNION' : 'UNION_DISTINCT';
70
71 5
        return $unionType . '(' . $aql . ', ' . $this->wrapSubquery($union['query']->toSql()) . ')';
72
    }
73
}
74