Skip to content

Commit bb3ed74

Browse files
authored
Merge pull request #13 from gear4s/feature/valid-null-sql-generation
Add support for valid NULL queries
2 parents 24892ac + 86c68f9 commit bb3ed74

File tree

3 files changed

+58
-15
lines changed

3 files changed

+58
-15
lines changed

src/Query/CaseBuilder.php

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,30 @@ public function when($column, $operator = null, $value = null): self
8282
func_num_args() === 2
8383
);
8484

85-
if ($value) {
86-
$this->whens[] = $this->grammar->wrapColumn($column) . ' ' . $operator . ' ?';
87-
85+
if (isset($value)) {
8886
$this->addBinding($value, 'when');
89-
} elseif ($operator) {
90-
$this->whens[] = $this->grammar->wrapColumn($column) . ' ?';
9187

88+
$this->whens[] = [
89+
'query' => $this->grammar->wrapColumn($column) . ' ' . $operator . ' ?',
90+
'binding' => count($this->bindings['when']) - 1,
91+
];
92+
} elseif (is_null($value)) {
93+
$operator = $operator === '=' ? 'IS' : 'IS NOT';
94+
95+
$this->whens[] = [
96+
'query' => $this->grammar->wrapColumn($column) . ' ' . $operator . ' NULL',
97+
];
98+
} elseif ($operator) {
9299
$this->addBinding($operator, 'when');
100+
101+
$this->whens[] = [
102+
'query' => $this->grammar->wrapColumn($column) . ' ?',
103+
'binding' => count($this->bindings['when']) - 1,
104+
];
93105
} else {
94-
$this->whens[] = $column;
106+
$this->whens[] = [
107+
'query' => $column,
108+
];
95109
}
96110

97111
return $this;
@@ -107,10 +121,13 @@ public function whenRaw(string $expression, $bindings = []): self
107121
CaseBuilderException::wrongWhenPosition()
108122
);
109123

110-
$this->whens[] = $expression;
111-
112124
$this->addBinding($bindings, 'when');
113125

126+
$this->whens[] = [
127+
'query' => $expression,
128+
'binding' => count($this->bindings['when']) - 1,
129+
];
130+
114131
return $this;
115132
}
116133

@@ -124,10 +141,10 @@ public function then($value): self
124141
CaseBuilderException::thenCannotBeBeforeWhen()
125142
);
126143

127-
$this->thens[] = '?';
128-
129144
$this->addBinding($value, 'then');
130145

146+
$this->thens[] = '?';
147+
131148
return $this;
132149
}
133150

@@ -256,10 +273,12 @@ public function getBindings(): array
256273
* Flattening here is to handle raw cases with multiple bindings.
257274
*/
258275
foreach ($this->whens as $i => $when) {
259-
if (is_array($this->bindings['when'][$i])) {
260-
$bindings = array_merge($bindings, $this->bindings['when'][$i]);
261-
} else {
262-
$bindings[] = $this->bindings['when'][$i];
276+
if (array_key_exists('binding', $when)) {
277+
if (is_array($this->bindings['when'][$when['binding']])) {
278+
$bindings = array_merge($bindings, $this->bindings['when'][$when['binding']]);
279+
} else {
280+
$bindings[] = $this->bindings['when'][$when['binding']];
281+
}
263282
}
264283

265284
if (is_array($this->bindings['then'][$i])) {

src/Query/Grammar.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function compile(CaseBuilder $caseBuilder): string
1717

1818
foreach ($caseBuilder->whens as $i => $when) {
1919
$components[] = 'when';
20-
$components[] = $when;
20+
$components[] = $when['query'];
2121
$components[] = 'then';
2222
$components[] = $caseBuilder->thens[$i];
2323
}

tests/CaseBuilderTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,30 @@ public function testCanGenerateComplexQuery()
5252
$this->assertCount(7, $caseQuery->getBindings());
5353
$this->assertEquals('case when `payment_status` = 1 then "Paid" when `payment_status` = 2 then "Due" when `payment_status` <= 5 then "Canceled" else "Unknown" end', $caseQuery->toRaw());
5454
}
55+
56+
public function testCanGenerateComplexQueryWithNullishTypes()
57+
{
58+
/**
59+
* @var QueryCaseBuilder $caseQuery
60+
*/
61+
$caseQuery = CaseBuilder::when('payment_date', '>', 0)
62+
->then('Paid')
63+
->when('payment_date', 0)
64+
->then('Due')
65+
->when('payment_date', null)
66+
->then('Canceled')
67+
->else('Unknown');
68+
69+
$this->assertCount(3, $caseQuery->whens);
70+
$this->assertCount(3, $caseQuery->thens);
71+
$this->assertSameSize($caseQuery->whens, $caseQuery->thens);
72+
$this->assertNotEmpty($caseQuery->else);
73+
74+
$this->assertEquals('case when `payment_date` > ? then ? when `payment_date` = ? then ? when `payment_date` IS NULL then ? else ? end', $caseQuery->toSql());
75+
$this->assertEquals([ 0, "Paid", 0, "Due", "Canceled", "Unknown" ], $caseQuery->getBindings());
76+
$this->assertCount(6, $caseQuery->getBindings());
77+
$this->assertEquals('case when `payment_date` > 0 then "Paid" when `payment_date` = 0 then "Due" when `payment_date` IS NULL then "Canceled" else "Unknown" end', $caseQuery->toRaw());
78+
}
5579

5680
public function testCanGenerateComplexQueryWithDotSeparatedColumns()
5781
{

0 commit comments

Comments
 (0)