forked from nuwave/lighthouse
/
SQLOperator.php
123 lines (93 loc) · 3.44 KB
/
SQLOperator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?php
namespace Nuwave\Lighthouse\WhereConditions;
use GraphQL\Error\Error;
class SQLOperator implements Operator
{
public static function missingValueForColumn(string $column): string
{
return "Did not receive a value to match the WhereConditions for column {$column}.";
}
public function enumDefinition(): string
{
return /** @lang GraphQL */ <<<'GRAPHQL'
"The available SQL operators that are used to filter query results."
enum SQLOperator {
"Equal operator (`=`)"
EQ @enum(value: "=")
"Not equal operator (`!=`)"
NEQ @enum(value: "!=")
"Greater than operator (`>`)"
GT @enum(value: ">")
"Greater than or equal operator (`>=`)"
GTE @enum(value: ">=")
"Less than operator (`<`)"
LT @enum(value: "<")
"Less than or equal operator (`<=`)"
LTE @enum(value: "<=")
"Simple pattern matching (`LIKE`)"
LIKE @enum(value: "LIKE")
"Negation of simple pattern matching (`NOT LIKE`)"
NOT_LIKE @enum(value: "NOT_LIKE")
"Whether a value is within a set of values (`IN`)"
IN @enum(value: "In")
"Whether a value is not within a set of values (`NOT IN`)"
NOT_IN @enum(value: "NotIn")
"Whether a value is within a range of values (`BETWEEN`)"
BETWEEN @enum(value: "Between")
"Whether a value is not within a range of values (`NOT BETWEEN`)"
NOT_BETWEEN @enum(value: "NotBetween")
"Whether a value is null (`IS NULL`)"
IS_NULL @enum(value: "Null")
"Whether a value is not null (`IS NOT NULL`)"
IS_NOT_NULL @enum(value: "NotNull")
}
GRAPHQL;
}
public function default(): string
{
return 'EQ';
}
public function applyConditions($builder, array $whereConditions, string $boolean)
{
$column = $whereConditions['column'];
// Laravel's conditions always start off with this prefix
$method = 'where';
// The first argument to conditions methods is always the column name
$args = [$column];
// Some operators require calling Laravel's conditions in different ways
$operator = $whereConditions['operator'];
$arity = $this->operatorArity($operator);
if ($arity === 3) {
// Usually, the operator is passed as the second argument to the condition
// method, e.g. ->where('some_col', '=', $value)
$args[] = $operator;
} else {
// We utilize the fact that the operators are named after Laravel's condition
// methods so we can simply append the name, e.g. whereNull, whereNotBetween
$method .= $operator;
}
if ($arity > 1) {
// The conditions with arity 1 require no args apart from the column name.
// All other arities take a value to query against.
if (! array_key_exists('value', $whereConditions)) {
throw new Error(
self::missingValueForColumn($column)
);
}
$args[] = $whereConditions['value'];
}
// The condition methods always have the `$boolean` arg after the value
$args[] = $boolean;
return $builder->{$method}(...$args);
}
protected function operatorArity(string $operator): int
{
if (in_array($operator, ['Null', 'NotNull'])) {
return 1;
}
if (in_array($operator, ['In', 'NotIn', 'Between', 'NotBetween'])) {
return 2;
}
return 3;
}
}