Passed
Push — master ( c9b334...7badbc )
by Ryosuke
12:43 queued 02:43
created

MySqlGrammar   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 4
eloc 38
c 1
b 0
f 0
dl 0
loc 68
ccs 35
cts 35
cp 1
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
A compileLegacyGroupLimit() 0 56 4
1
<?php
2
3
namespace Mpyw\ComposhipsEagerLimit\Database\Query\Grammar;
4
5
use Illuminate\Database\Query\Builder;
6
use Staudenmeir\EloquentEagerLimit\Grammars\MySqlGrammar as EagerLimitMySqlGrammar;
7
8
class MySqlGrammar extends EagerLimitMySqlGrammar
9
{
10
    use Concerns\CompilesGroupLimitByMultipleColumnPartition;
11
12
    /**
13
     * Compile a group limit clause for MySQL < 8.0.
14
     *
15
     * Derived from https://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/.
16
     *
17
     * @param  \Illuminate\Database\Query\Builder|\Mpyw\ComposhipsEagerLimit\Database\Query\Builder $query
18
     * @return string
19
     */
20 8
    protected function compileLegacyGroupLimit(Builder $query)
21
    {
22 8
        $limit = (int)$query->groupLimit['value'] + (int)$query->offset;
23 8
        $offset = $query->offset;
24
25 8
        $query->offset = null;
26 8
        $query->orders = (array)$query->orders;
27
28 8
        $partitionExpressions = [];
29 8
        $partitionAssignments = [];
30 8
        $partitionInitializations = [];
31 8
        $partitionOrders = [];
32
33 8
        if (is_array($query->groupLimit['column'])) {
34 5
            foreach ($query->groupLimit['column'] as $i => $column) {
35 5
                $wrappedColumn = $this->wrap(last(explode('.', $column)));
36
37 5
                $partitionExpressions[] = "@laravel_partition_$i = $wrappedColumn";
38 5
                $partitionAssignments[] = "@laravel_partition_$i := $wrappedColumn";
39 5
                $partitionInitializations[] = "@laravel_partition_$i := 0";
40 5
                $partitionOrders[] = ['column' => $column, 'direction' => 'asc'];
41
            }
42
        } else {
43 8
            $wrappedColumn = $this->wrap(last(explode('.', $query->groupLimit['column'])));
44
45 8
            $partitionExpressions[] = "@laravel_partition = $wrappedColumn";
46 8
            $partitionAssignments[] = "@laravel_partition := $wrappedColumn";
47 8
            $partitionInitializations[] = '@laravel_partition := 0';
48 8
            $partitionOrders[] = ['column' => $query->groupLimit['column'], 'direction' => 'asc'];
49
        }
50
51 8
        $partition = sprintf(
52 8
            ', @laravel_row := if(%s, @laravel_row + 1, 1) as laravel_row, %s',
53 8
            implode(' and ', $partitionExpressions),
54 8
            implode(', ', $partitionAssignments)
55
        );
56
57 8
        array_splice($query->orders, 0, 0, $partitionOrders);
58
59 8
        $components = $this->compileComponents($query);
60
61 8
        $sql = $this->concatenate($components);
62
63 8
        $from = sprintf(
64 8
            '(select @laravel_row := 0, %s) as laravel_vars, (%s) as laravel_table',
65 8
            implode(', ', $partitionInitializations),
66
            $sql
67
        );
68
69 8
        $sql = 'select laravel_table.*' . $partition . ' from ' . $from . ' having laravel_row <= ' . $limit;
70
71 8
        if ($offset !== null) {
0 ignored issues
show
introduced by
The condition $offset !== null is always true.
Loading history...
72 3
            $sql .= ' and laravel_row > ' . (int)$offset;
73
        }
74
75 8
        return $sql . ' order by laravel_row';
76
    }
77
}
78