Skip to content

Commit ff85d3d

Browse files
committed
refactor(database): use dialect-aware quoteIdentifier across all statements
Add DatabaseDialect::quoteIdentifier() that returns backticks for MySQL/SQLite and double quotes for PostgreSQL. Update all 20+ QueryStatement compile() methods to use it instead of hardcoded backticks. Query::compile() safety net remains for __toString() paths that lack dialect context. include UpdateStatement in quoteIdentifier refactor
1 parent 0fe5025 commit ff85d3d

34 files changed

Lines changed: 149 additions & 120 deletions

packages/database/src/Config/DatabaseDialect.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ public function tableNotFoundCode(): string
2121
};
2222
}
2323

24+
public function quoteIdentifier(string $identifier): string
25+
{
26+
return match ($this) {
27+
self::MYSQL, self::SQLITE => sprintf('`%s`', $identifier),
28+
self::POSTGRESQL => sprintf('"%s"', $identifier),
29+
};
30+
}
31+
2432
public function isTableNotFoundError(QueryWasInvalid $queryWasInvalid): bool
2533
{
2634
$pdoException = $queryWasInvalid->pdoException;

packages/database/src/QueryStatements/AlterTableStatement.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Tempest\Database\QueryStatements;
66

7-
use Tempest\Database\Builder\TableDefinition;
87
use Tempest\Database\Config\DatabaseDialect;
98
use Tempest\Database\HasTrailingStatements;
109
use Tempest\Database\QueryStatement;
@@ -92,7 +91,7 @@ public function compile(DatabaseDialect $dialect): string
9291
if ($this->statements !== []) {
9392
return sprintf(
9493
'ALTER TABLE %s %s;',
95-
new TableDefinition($this->tableName),
94+
$dialect->quoteIdentifier($this->tableName),
9695
arr($this->statements)
9796
->map(fn (QueryStatement $queryStatement) => str($queryStatement->compile($dialect))->trim()->replace(' ', ' '))
9897
->filter(fn (ImmutableString $line) => $line->isNotEmpty())

packages/database/src/QueryStatements/BooleanStatement.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ public function compile(DatabaseDialect $dialect): string
2727
}
2828

2929
return sprintf(
30-
'`%s` BOOLEAN %s %s',
31-
$this->name,
30+
'%s BOOLEAN %s %s',
31+
$dialect->quoteIdentifier($this->name),
3232
$default !== null ? "DEFAULT {$default}" : '',
3333
$this->nullable ? '' : 'NOT NULL',
3434
);

packages/database/src/QueryStatements/CharStatement.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ public function __construct(
1818
public function compile(DatabaseDialect $dialect): string
1919
{
2020
return sprintf(
21-
'`%s` CHAR %s %s',
22-
$this->name,
21+
'%s CHAR %s %s',
22+
$dialect->quoteIdentifier($this->name),
2323
$this->default !== null ? "DEFAULT '{$this->default}'" : '',
2424
$this->nullable ? '' : 'NOT NULL',
2525
);

packages/database/src/QueryStatements/CountStatement.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function compile(DatabaseDialect $dialect): string
3333

3434
$query = arr([
3535
sprintf('SELECT %s', $countField->compile($dialect)),
36-
sprintf('FROM `%s`', $this->table->name),
36+
sprintf('FROM %s', $dialect->quoteIdentifier($this->table->name)),
3737
]);
3838

3939
if ($this->joins->isNotEmpty()) {

packages/database/src/QueryStatements/CreateTableStatement.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace Tempest\Database\QueryStatements;
66

77
use BackedEnum;
8-
use Tempest\Database\Builder\TableDefinition;
98
use Tempest\Database\Config\DatabaseDialect;
109
use Tempest\Database\Enums\DatabaseTextLength;
1110
use Tempest\Database\HasTrailingStatements;
@@ -400,7 +399,7 @@ public function compile(DatabaseDialect $dialect): string
400399
{
401400
return sprintf(
402401
'CREATE TABLE %s (%s);',
403-
new TableDefinition($this->tableName),
402+
$dialect->quoteIdentifier($this->tableName),
404403
arr($this->statements)
405404
// Remove BelongsTo for sqlLite as it does not support those queries
406405
->filter(fn (QueryStatement $queryStatement) => ! ($dialect === DatabaseDialect::SQLITE && $queryStatement instanceof BelongsToStatement))

packages/database/src/QueryStatements/DateStatement.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ public function __construct(
1818
public function compile(DatabaseDialect $dialect): string
1919
{
2020
return sprintf(
21-
'`%s` DATE %s %s',
22-
$this->name,
21+
'%s DATE %s %s',
22+
$dialect->quoteIdentifier($this->name),
2323
$this->default !== null ? "DEFAULT '{$this->default}'" : '',
2424
$this->nullable ? '' : 'NOT NULL',
2525
);

packages/database/src/QueryStatements/DatetimeStatement.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ public function compile(DatabaseDialect $dialect): string
2929
default => null,
3030
};
3131

32+
$name = $dialect->quoteIdentifier($this->name);
33+
3234
return match ($dialect) {
3335
DatabaseDialect::POSTGRESQL => sprintf(
34-
'`%s` TIMESTAMP %s %s',
35-
$this->name,
36+
'%s TIMESTAMP %s %s',
37+
$name,
3638
$default !== null ? "DEFAULT {$default}" : '',
3739
$this->nullable ? '' : 'NOT NULL',
3840
),
3941
default => sprintf(
40-
'`%s` DATETIME %s %s',
41-
$this->name,
42+
'%s DATETIME %s %s',
43+
$name,
4244
$default !== null ? "DEFAULT {$default}" : '',
4345
$this->nullable ? '' : 'NOT NULL',
4446
),

packages/database/src/QueryStatements/DeleteStatement.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function compile(DatabaseDialect $dialect): string
2525
}
2626

2727
$query = arr([
28-
sprintf('DELETE FROM `%s`', $this->table->name),
28+
sprintf('DELETE FROM %s', $dialect->quoteIdentifier($this->table->name)),
2929
]);
3030

3131
if ($this->where->isNotEmpty()) {

packages/database/src/QueryStatements/DropConstraintStatement.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ public function compile(DatabaseDialect $dialect): string
2626

2727
return match ($dialect) {
2828
DatabaseDialect::MYSQL => sprintf(
29-
'ALTER TABLE `%s` DROP CONSTRAINT %s',
30-
$foreignTable,
29+
'ALTER TABLE %s DROP CONSTRAINT %s',
30+
$dialect->quoteIdentifier($foreignTable),
3131
$constraintName,
3232
),
3333
default => '',

0 commit comments

Comments
 (0)