CompilesUnions::compileUnions()   B
last analyzed

Complexity

Conditions 8
Paths 49

Size

Total Lines 47
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 8.0036

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 8
eloc 25
nc 49
nop 2
dl 0
loc 47
ccs 25
cts 26
cp 0.9615
crap 8.0036
rs 8.4444
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 10
    protected function compileUnions(IlluminateBuilder $query, $firstQuery = '')
20
    {
21 10
        if (!is_array($query->unions)) {
22
            return '';
23
        }
24
25 10
        $unionResultsId = 'union' . $query->getQueryId() . 'Results';
26 10
        $unionDocId = 'union' . $query->getQueryId() . 'Result';
27
28 10
        $query->registerTableAlias($unionResultsId, $unionDocId);
29
30 10
        $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 10
        $unions = '';
33
34 10
        foreach ($query->unions as $union) {
35 10
            $prefix = ($unions !== '') ? $unions : $firstQuery;
36 10
            $unions = $this->compileUnion($union, $prefix);
37
        }
38
39 10
        $aql = 'LET ' . $unionResultsId . ' = ' . $unions
40 10
            . ' FOR ' . $unionDocId . ' IN ' . $unionResultsId;
41
42 10
        if (!empty($query->unionOrders)) {
43 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

43
            $aql .= ' ' . $this->/** @scrutinizer ignore-call */ compileOrders($query, $query->unionOrders, $unionResultsId);
Loading history...
44
        }
45
46 10
        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...
47 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

47
            $aql .= ' ' . $this->/** @scrutinizer ignore-call */ compileOffset($query, $query->unionOffset);
Loading history...
48
        }
49
50 10
        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...
51 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

51
            $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...
52
        }
53
54 10
        if ($query->aggregate !== null) {
55 5
            $originalFrom = $query->from;
56 5
            $query->from = $unionResultsId;
57
58 5
            $aql .= ' ' . $this->compileAggregate($query, $query->aggregate);
0 ignored issues
show
Bug introduced by
It seems like compileAggregate() 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

58
            $aql .= ' ' . $this->/** @scrutinizer ignore-call */ compileAggregate($query, $query->aggregate);
Loading history...
59
60 5
            $query->from = $originalFrom;
61
62 5
            return $aql . ' RETURN { `aggregate`: aggregateResult }';
63
        }
64
65 5
        return $aql . ' RETURN ' . $unionDocId;
66
    }
67
68
    /**
69
     * Compile a single union statement.
70
     *
71
     * @param array<mixed> $union
72
     * @param string $aql
73
     * @return string
74
     */
75 10
    protected function compileUnion(array $union, string $aql = '')
76
    {
77 10
        $unionType = $union['all'] ? 'UNION' : 'UNION_DISTINCT';
78
79 10
        return $unionType . '(' . $aql . ', ' . $this->wrapSubquery($union['query']->toSql()) . ')';
80
    }
81
}
82