Skip to content

Commit d09a870

Browse files
committed
fix: compileUpdate er compileSelect
- les jointures lors des updates ne sont supportées que par mysql/mariadb et differement par postgre - dans le compile select, les unions viennent avant orders
1 parent e5ff9bc commit d09a870

4 files changed

Lines changed: 130 additions & 12 deletions

File tree

src/Builder/Compilers/MySQL.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,39 @@
1515

1616
class MySQL extends QueryCompiler
1717
{
18+
/**
19+
* {@inheritDoc}
20+
*/
21+
public function compileUpdate(BaseBuilder $builder): string
22+
{
23+
$table = $this->db->makeTableName($builder->getTable());
24+
25+
$sql = ["UPDATE {$table}"];
26+
27+
if ([] !== $builder->joins) {
28+
$sql[] = $this->compileJoins($builder->joins);
29+
}
30+
31+
$sets = [];
32+
foreach ($builder->values as $column => $value) {
33+
$column = $this->db->escapeIdentifiers($column);
34+
$sets[] = "{$column} = " . $this->wrapValue($value);
35+
}
36+
37+
$sql[] = "SET " . implode(', ', $sets);
38+
39+
if ([] !== $builder->wheres) {
40+
$sql[] = 'WHERE';
41+
$sql[] = $this->compileWheres($builder->wheres);
42+
}
43+
44+
if ('' !== $limit = $this->compileLimit($builder->limit, null)) {
45+
$sql[] = $limit;
46+
}
47+
48+
return implode(' ', array_filter($sql));
49+
}
50+
1851
/**
1952
* {@inheritDoc}
2053
*/

src/Builder/Compilers/Postgre.php

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace BlitzPHP\Database\Builder\Compilers;
1313

1414
use BlitzPHP\Database\Builder\BaseBuilder;
15+
use BlitzPHP\Database\Builder\JoinClause;
1516

1617
class Postgre extends QueryCompiler
1718
{
@@ -61,11 +62,15 @@ public function compileInsertUsing(BaseBuilder $builder): string
6162
*/
6263
public function compileUpdate(BaseBuilder $builder): string
6364
{
64-
$sql = parent::compileUpdate($builder);
65+
if ($builder->joins === []) {
66+
$sql = $this->compileUpdateStandard($builder);
67+
68+
return "{$sql} RETURNING *";
69+
}
6570

66-
return "{$sql} RETURNING *";
71+
return $this->compileUpdateWithFrom($builder);
6772
}
68-
73+
6974
/**
7075
* {@inheritDoc}
7176
*/
@@ -190,4 +195,54 @@ protected function compileAnyAll(string $type, string $column, string $operator,
190195

191196
return "{$column} {$operator} {$type} ({$placeholders})";
192197
}
198+
199+
/**
200+
* Compilation PostgreSQL avec FROM
201+
*/
202+
protected function compileUpdateWithFrom(BaseBuilder $builder): string
203+
{
204+
$table = $this->db->makeTableName($builder->getTable());
205+
206+
$sets = [];
207+
foreach ($builder->values as $column => $value) {
208+
$column = $this->db->escapeIdentifiers($column);
209+
$sets[] = "{$column} = " . $this->wrapValue($value);
210+
}
211+
212+
$sql = ["UPDATE {$table}"];
213+
$sql[] = "SET " . implode(', ', $sets);
214+
215+
// Construction de la clause FROM
216+
$fromTables = [];
217+
$joinConditions = [];
218+
219+
foreach ($builder->joins as $join) {
220+
if ($join instanceof JoinClause) {
221+
$fromTables[] = $join->getTable();
222+
223+
// Convertir les conditions ON en conditions WHERE
224+
foreach ($join->getConditions() as $condition) {
225+
if ($condition['type'] === 'basic') {
226+
$joinConditions[] = $condition['first'] . ' ' .
227+
$condition['operator'] . ' ' .
228+
$condition['second'];
229+
}
230+
}
231+
}
232+
}
233+
234+
if ($fromTables !== []) {
235+
$sql[] = "FROM " . implode(', ', $fromTables);
236+
}
237+
238+
// Fusionner les conditions WHERE originales avec les conditions de jointure
239+
$allConditions = array_merge($joinConditions, $builder->wheres);
240+
241+
if ($allConditions !== []) {
242+
$sql[] = 'WHERE';
243+
$sql[] = $this->compileWheres($allConditions);
244+
}
245+
246+
return implode(' ', array_filter($sql));
247+
}
193248
}

src/Builder/Compilers/QueryCompiler.php

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use BlitzPHP\Database\Builder\BaseBuilder;
1515
use BlitzPHP\Database\Builder\JoinClause;
1616
use BlitzPHP\Database\Connection\BaseConnection;
17+
use BlitzPHP\Database\Exceptions\DatabaseException;
1718
use BlitzPHP\Database\Query\Expression;
1819
use BlitzPHP\Database\Utils;
1920
use InvalidArgumentException;
@@ -78,15 +79,15 @@ public function compileSelect(BaseBuilder $builder): string
7879
$sql[] = $this->compileHavings($builder->havings);
7980
}
8081

82+
if ([] !== $builder->unions) {
83+
$sql[] = $this->compileUnions($builder->unions);
84+
}
85+
8186
if ([] !== $builder->orders) {
8287
$sql[] = 'ORDER BY';
8388
$sql[] = $this->compileOrders($builder->orders);
8489
}
8590

86-
if ([] !== $builder->unions) {
87-
$sql[] = $this->compileUnions($builder->unions);
88-
}
89-
9091
if ('' !== $limit = $this->compileLimit($builder->limit, $builder->offset)) {
9192
$sql[] = $limit;
9293
}
@@ -144,20 +145,33 @@ public function compileInsertUsing(BaseBuilder $builder): string
144145
*/
145146
public function compileUpdate(BaseBuilder $builder): string
146147
{
147-
$table = $this->db->escapeIdentifiers($builder->getTable());
148+
return $this->compileUpdateStandard($builder);
149+
}
150+
151+
/**
152+
* Compilation standard sans jointure
153+
*/
154+
protected function compileUpdateStandard(BaseBuilder $builder): string
155+
{
156+
$table = $this->db->makeTableName($builder->getTable());
157+
158+
$sql = ["UPDATE {$table}"];
148159

149160
$sets = [];
150161
foreach ($builder->values as $column => $value) {
151162
$column = $this->db->escapeIdentifiers($column);
152163
$sets[] = "{$column} = " . $this->wrapValue($value);
153164
}
154-
155-
$sql = ["UPDATE {$table} SET " . implode(', ', $sets)];
156-
165+
157166
if ([] !== $builder->joins) {
158-
$sql[] = $this->compileJoins($builder->joins);
167+
// Si des jointures sont présentes mais non supportées, on lève une exception.
168+
throw new DatabaseException(
169+
"Les jointures dans UPDATE ne sont pas supportées par " . $this->db->getDriver()
170+
);
159171
}
160172

173+
$sql[] = "SET " . implode(', ', $sets);
174+
161175
if ([] !== $builder->wheres) {
162176
$sql[] = 'WHERE';
163177
$sql[] = $this->compileWheres($builder->wheres);

src/Builder/Compilers/SQLite.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,25 @@
1212
namespace BlitzPHP\Database\Builder\Compilers;
1313

1414
use BlitzPHP\Database\Builder\BaseBuilder;
15+
use BlitzPHP\Database\Exceptions\DatabaseException;
1516

1617
class SQLite extends QueryCompiler
1718
{
19+
/**
20+
* {@inheritDoc}
21+
*/
22+
public function compileUpdate(BaseBuilder $builder): string
23+
{
24+
if ($builder->joins !== []) {
25+
throw new DatabaseException(
26+
"SQLite ne supporte pas les jointures dans les requêtes UPDATE. " .
27+
"Utilisez des sous-requêtes à la place."
28+
);
29+
}
30+
31+
return $this->compileUpdateStandard($builder);
32+
}
33+
1834
/**
1935
* {@inheritDoc}
2036
*/

0 commit comments

Comments
 (0)