Passed
Push — master ( 2a2829...d91029 )
by Jonas
06:26
created

compilePivotColumnNullValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 10
ccs 8
cts 8
cp 1
rs 10
cc 1
nc 1
nop 3
crap 1
1
<?php
2
3
namespace Staudenmeir\LaravelAdjacencyList\Query\Grammars\Traits;
4
5
use Illuminate\Database\Query\Builder;
6
use Staudenmeir\LaravelAdjacencyList\Query\Grammars\OrdersByPath;
7
8
trait CompilesMySqlAdjacencyLists
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 322
    public function compileInitialPath($column, $alias)
20
    {
21 322
        return 'cast(' . $this->wrap($column) . ' as char(65535)) as ' . $this->wrap($alias);
0 ignored issues
show
Bug introduced by
It seems like wrap() 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

21
        return 'cast(' . $this->/** @scrutinizer ignore-call */ wrap($column) . ' as char(65535)) as ' . $this->wrap($alias);
Loading history...
22
    }
23
24
    /**
25
     * Compile a recursive path.
26
     *
27
     * @param string $column
28
     * @param string $alias
29
     * @param bool $reverse
30
     * @return string
31
     */
32 386
    public function compileRecursivePath($column, $alias, bool $reverse = false)
33
    {
34 386
        $wrappedColumn = $this->wrap($column);
35 386
        $wrappedAlias = $this->wrap($alias);
36
37 386
        return $reverse ? "concat($wrappedColumn, ?, $wrappedAlias)" : "concat($wrappedAlias, ?, $wrappedColumn)";
38
    }
39
40
    /**
41
     * Get the recursive path bindings.
42
     *
43
     * @param string $separator
44
     * @return array
45
     */
46 386
    public function getRecursivePathBindings($separator)
47
    {
48 386
        return [$separator];
49
    }
50
51
    /**
52
     * Select a concatenated list of paths.
53
     *
54
     * @param \Illuminate\Database\Query\Builder $query
55
     * @param string $expression
56
     * @param string $column
57
     * @param string $pathSeparator
58
     * @param string $listSeparator
59
     * @return \Illuminate\Database\Query\Builder
60
     */
61 34
    public function selectPathList(Builder $query, $expression, $column, $pathSeparator, $listSeparator)
0 ignored issues
show
Unused Code introduced by
The parameter $pathSeparator is not used and could be removed. ( Ignorable by Annotation )

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

61
    public function selectPathList(Builder $query, $expression, $column, /** @scrutinizer ignore-unused */ $pathSeparator, $listSeparator)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
62
    {
63 34
        return $query->selectRaw(
64 34
            'group_concat(' . $this->wrap($column) . " separator '$listSeparator')"
65 34
        )->from($expression);
66
    }
67
68
    /**
69
     * Compile an "order by path" clause.
70
     *
71
     * @return string
72
     */
73 8
    public function compileOrderByPath()
74
    {
75 8
        $column = $this->model->getLocalKeyName();
76
77 8
        $path = $this->wrap(
78 8
            $this->model->getPathName()
79 8
        );
80
81 8
        $pathSeparator = $this->model->getPathSeparator();
82
83 8
        if (!$this->model->isIntegerAttribute($column)) {
84 2
            return "$path asc";
85
        }
86
87 6
        return <<<SQL
88 6
regexp_replace(
89
    regexp_replace(
90 6
        $path,
91 6
        '(^|[$pathSeparator])(\\\\d+)',
92
        '$100000000000000000000$2'
93
    ),
94 6
    '0+(\\\\d\{20\})([$pathSeparator]|$)',
95
    '$1$2'
96
) asc
97 6
SQL;
98
    }
99
100
    /**
101
     * Compile a pivot column null value.
102
     *
103
     * @param string $type
104
     * @param int $precision
105
     * @param int $scale
106
     * @return string
107
     */
108 44
    public function compilePivotColumnNullValue(string $type, int $precision, int $scale): string
109
    {
110 44
        $cast = match ($type) {
111 44
            'bigint', 'boolean', 'integer', 'smallint' => 'signed',
112 44
            'decimal' => "decimal($precision, $scale)",
113 44
            'string' => 'char(65535)',
114 44
            default => $type,
115 44
        };
116
117 44
        return "cast(null as $cast)";
118
    }
119
120
    /**
121
     * Compile a cycle detection clause.
122
     *
123
     * @param string $localKey
124
     * @param string $path
125
     * @return string
126
     */
127 52
    public function compileCycleDetection(string $localKey, string $path): string
128
    {
129 52
        $localKey = $this->wrap($localKey);
130 52
        $path = $this->wrap($path);
131
132 52
        return "instr($path, concat($localKey, ?)) = 1 || instr($path, concat(?, $localKey, ?)) > 1";
133
    }
134
135
    /**
136
     * Get the cycle detection bindings.
137
     *
138
     * @param string $pathSeparator
139
     * @return array
140
     */
141 52
    public function getCycleDetectionBindings(string $pathSeparator): array
142
    {
143 52
        return [$pathSeparator, $pathSeparator, $pathSeparator];
144
    }
145
146
    /**
147
     * Compile the initial select expression for a cycle detection clause.
148
     *
149
     * @param string $column
150
     * @return string
151
     */
152 26
    public function compileCycleDetectionInitialSelect(string $column): string
153
    {
154 26
        return 'false as ' . $this->wrap($column);
155
    }
156
157
    /**
158
     * Compile the recursive select expression for a cycle detection clause.
159
     *
160
     * @param string $sql
161
     * @param string $column
162
     * @return string
163
     */
164 26
    public function compileCycleDetectionRecursiveSelect(string $sql, string $column): string
0 ignored issues
show
Unused Code introduced by
The parameter $column is not used and could be removed. ( Ignorable by Annotation )

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

164
    public function compileCycleDetectionRecursiveSelect(string $sql, /** @scrutinizer ignore-unused */ string $column): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
165
    {
166 26
        return $sql;
167
    }
168
169
    /**
170
     * Compile the stop constraint for a cycle detection clause.
171
     *
172
     * @param string $column
173
     * @return string
174
     */
175 26
    public function compileCycleDetectionStopConstraint(string $column): string
176
    {
177 26
        return 'not ' . $this->wrap($column);
178
    }
179
180
    /**
181
     * Determine whether the database supports the UNION operator in a recursive expression.
182
     *
183
     * @return bool
184
     */
185 40
    public function supportsUnionInRecursiveExpression(): bool
186
    {
187 40
        return true;
188
    }
189
}
190