Passed
Push — master ( 5a82e5...fe024b )
by Jonas
03:43
created

MySqlGrammar::compilePivotColumnNullValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Staudenmeir\LaravelAdjacencyList\Query\Grammars;
4
5
use Illuminate\Database\Query\Builder;
6
use Illuminate\Database\Query\Grammars\MySqlGrammar as Base;
7
8
class MySqlGrammar extends Base implements ExpressionGrammar
9
{
10
    use OrdersByPath;
11
12
    /**
13
     * Compile an initial path.
14
     *
15
     * @param string $column
16
     * @param string $alias
17
     * @return string
18
     */
19 236
    public function compileInitialPath($column, $alias)
20
    {
21 236
        return 'cast(' . $this->wrap($column) . ' as char(65535)) as ' . $this->wrap($alias);
22
    }
23
24
    /**
25
     * Compile a recursive path.
26
     *
27
     * @param string $column
28
     * @param string $alias
29
     * @return string
30
     */
31 236
    public function compileRecursivePath($column, $alias)
32
    {
33 236
        return 'concat(' . $this->wrap($alias) . ', ?, ' . $this->wrap($column) . ')';
34
    }
35
36
    /**
37
     * Get the recursive path bindings.
38
     *
39
     * @param string $separator
40
     * @return array
41
     */
42 236
    public function getRecursivePathBindings($separator)
43
    {
44 236
        return [$separator];
45
    }
46
47
    /**
48
     * Select a concatenated list of paths.
49
     *
50
     * @param \Illuminate\Database\Query\Builder $query
51
     * @param string $expression
52
     * @param string $column
53
     * @param string $pathSeparator
54
     * @param string $listSeparator
55
     * @return \Illuminate\Database\Query\Builder
56
     */
57 32
    public function selectPathList(Builder $query, $expression, $column, $pathSeparator, $listSeparator)
58
    {
59 32
        return $query->selectRaw(
60 32
            'group_concat(' . $this->wrap($column) . " separator '$listSeparator')"
61 32
        )->from($expression);
62
    }
63
64
    /**
65
     * Compile an "order by path" clause.
66
     *
67
     * @return string
68
     */
69 5
    public function compileOrderByPath()
70
    {
71 5
        $column = $this->model->getLocalKeyName();
72
73 5
        $path = $this->wrap(
74 5
            $this->model->getPathName()
75
        );
76
77 5
        $pathSeparator = $this->model->getPathSeparator();
78
79 5
        if (!$this->model->isIntegerAttribute($column)) {
80 1
            return "$path asc";
81
        }
82
83
        return <<<SQL
84
regexp_replace(
85
    regexp_replace(
86
        $path,
87
        '(^|[$pathSeparator])(\\\\d+)',
88
        '$100000000000000000000$2'
89
    ),
90
    '0+(\\\\d\{20\})([$pathSeparator]|$)',
91
    '$1$2'
92
) asc
93
SQL;
94
    }
95
96
    /**
97
     * Compile a pivot column null value.
98
     *
99
     * @param string $type
100
     * @return string
101
     */
102 44
    public function compilePivotColumnNullValue(string $type): string
103
    {
104 44
        $cast = match ($type) {
105 44
            'bigint', 'boolean', 'integer', 'smallint' => 'signed',
106 44
            'string' => 'char(65535)',
107 44
            default => $type,
108
        };
109
110 44
        return "cast(null as $cast)";
111
    }
112
113
    /**
114
     * Compile a cycle detection clause.
115
     *
116
     * @param string $localKey
117
     * @param string $path
118
     * @return string
119
     */
120 36
    public function compileCycleDetection(string $localKey, string $path): string
121
    {
122 36
        $localKey = $this->wrap($localKey);
123 36
        $path = $this->wrap($path);
124
125 36
        return "instr($path, concat($localKey, ?)) = 1 || instr($path, concat(?, $localKey, ?)) > 1";
126
    }
127
128
    /**
129
     * Get the cycle detection bindings.
130
     *
131
     * @param string $pathSeparator
132
     * @return array
133
     */
134 36
    public function getCycleDetectionBindings(string $pathSeparator): array
135
    {
136 36
        return [$pathSeparator, $pathSeparator, $pathSeparator];
137
    }
138
}
139