CompilesJoins::compileInnerJoin()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 2
b 0
f 0
nc 2
nop 2
dl 0
loc 14
ccs 7
cts 7
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LaravelFreelancerNL\Aranguent\Query\Concerns;
6
7
use Illuminate\Database\Query\Builder as IlluminateQueryBuilder;
8
use Illuminate\Database\Query\Expression;
9
use LaravelFreelancerNL\Aranguent\Query\Builder;
10
use LaravelFreelancerNL\Aranguent\Query\JoinClause;
11
12
trait CompilesJoins
13
{
14
    /**
15
     * @param JoinClause $join
16
     * @param Builder $query
17
     * @return array<string>
18
     */
19 26
    public function extractTableAndAlias(Builder $query, $join): array
20
    {
21 26
        if ($join->table instanceof Expression) {
22 5
            $tableParts = [];
23
24 5
            if (preg_match("/(^.*) as (.*?)$/", (string) $join->table->getValue($query->grammar), $tableParts)) {
25 5
                $table = $tableParts[1];
26 5
                $alias = $tableParts[2];
27
28 5
                $query->registerTableAlias($join->table, $alias);
29
30 5
                return [$table, $alias];
31
            }
32
33
        }
34
35 21
        $table = (string) $this->wrapTable($join->table);
0 ignored issues
show
Bug introduced by
It seems like wrapTable() 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

35
        $table = (string) $this->/** @scrutinizer ignore-call */ wrapTable($join->table);
Loading history...
36 21
        $alias = $query->generateTableAlias($join->table);
37 21
        $query->registerTableAlias($join->table, $alias);
38
39 21
        return [$table, $alias];
40
    }
41
42
    /**
43
     * Compile the "join" portions of the query.
44
     *
45
     * @param IlluminateQueryBuilder $query
46
     * @param  array<mixed>  $joins
47
     * @return string
48
     */
49 27
    protected function compileJoins(IlluminateQueryBuilder $query, $joins)
50
    {
51 27
        return collect($joins)->map(function ($join) use ($query) {
0 ignored issues
show
Bug introduced by
$joins of type array<mixed,mixed> is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

51
        return collect(/** @scrutinizer ignore-type */ $joins)->map(function ($join) use ($query) {
Loading history...
52 27
            return match ($join->type) {
53 1
                'cross' => $this->compileCrossJoin($query, $join),
54 3
                'left' => $this->compileLeftJoin($query, $join),
55 27
                default => $this->compileInnerJoin($query, $join),
56 27
            };
57 27
        })->implode(' ');
58
    }
59
60
    /**
61
     * @param IlluminateQueryBuilder $query
62
     * @param JoinClause $join
63
     * @return string
64
     */
65 1
    protected function compileCrossJoin(IlluminateQueryBuilder $query, $join)
66
    {
67
        assert($query instanceof Builder);
68
69 1
        $table = $this->wrapTable($join->table);
70 1
        $alias = $query->generateTableAlias($join->table);
71 1
        $query->registerTableAlias($join->table, $alias);
72
73 1
        return 'FOR ' . $alias . ' IN ' . $table;
74
    }
75
76
    /**
77
     * @param IlluminateQueryBuilder $query
78
     * @param JoinClause $join
79
     * @return string
80
     */
81 23
    protected function compileInnerJoin(IlluminateQueryBuilder $query, $join)
82
    {
83
        assert($query instanceof Builder);
84
85 23
        list($table, $alias) = $this->extractTableAndAlias($query, $join);
86
87 23
        $filter = $this->compileWheres($join);
0 ignored issues
show
Bug introduced by
It seems like compileWheres() 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

87
        /** @scrutinizer ignore-call */ 
88
        $filter = $this->compileWheres($join);
Loading history...
88
89 23
        $aql = 'FOR ' . $alias . ' IN ' . $table;
90 23
        if ($filter) {
91 21
            $aql .= ' ' . $filter;
92
        }
93
94 23
        return $aql;
95
    }
96
97
    /**
98
     * @param IlluminateQueryBuilder $query
99
     * @param JoinClause $join
100
     * @return string
101
     */
102 3
    protected function compileLeftJoin(IlluminateQueryBuilder $query, $join)
103
    {
104
        assert($query instanceof Builder);
105
106 3
        list($table, $alias) = $this->extractTableAndAlias($query, $join);
107
108 3
        $filter = $this->compileWheres($join);
109
110 3
        $resultsToJoin = 'FOR ' . $alias . ' IN ' . $table;
111 3
        if ($filter) {
112 3
            $resultsToJoin .= ' ' . $filter;
113
        }
114 3
        $resultsToJoin .= ' RETURN ' . $alias;
115
116 3
        $aql = 'LET ' . $alias . 'List = (' . $resultsToJoin . ')';
117 3
        $aql .= ' FOR ' . $alias . ' IN (LENGTH(' . $alias . 'List) > 0) ? ' . $alias . 'List : [{}]';
118
119 3
        return $aql;
120
    }
121
}
122