Skip to content

Commit 7366844

Browse files
committed
Issue #N (reserved keyword order): v5'te bu sorun çözüldü — upstream query builder artık her tanımlayıcıyı driver-spesifik karakterle (MySQL/SQLite: backtick, PostgreSQL: çift tırnak) otomatik quote ediyor. tests/ReservedKeywordRegressionTest.php davranışı kalıcı kayıt altına alıyor.
1 parent c703f1a commit 7366844

1 file changed

Lines changed: 135 additions & 0 deletions

File tree

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<?php
2+
3+
/**
4+
* @package InitPHP\Database
5+
* @license MIT
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Test\InitPHP\Database;
11+
12+
use InitORM\Database\Interfaces\DatabaseInterface;
13+
use InitORM\DBAL\Connection\Interfaces\ConnectionInterface;
14+
use InitPHP\Database\Database;
15+
use PHPUnit\Framework\TestCase;
16+
use Test\InitPHP\Database\Support\SqliteHelper;
17+
18+
/**
19+
* Regression coverage for a class of bugs the 2.x line shipped with: a column
20+
* named after a reserved SQL keyword ({@code order}, {@code select}, …) would
21+
* crash UPDATE / SELECT because the compiler emitted the identifier bare.
22+
*
23+
* Upstream's {@code InitORM\QueryBuilder\Drivers\AbstractDriver::escapeIdentifier()}
24+
* now quotes every identifier driver-specifically (backticks on MySQL/SQLite,
25+
* double quotes on PostgreSQL), so this test asserts the fix stays in place.
26+
* If a future upstream release skips the quoting, these tests fire first.
27+
*
28+
* @see https://github.com/InitPHP/Database/issues — original v2 report.
29+
*/
30+
final class ReservedKeywordRegressionTest extends TestCase
31+
{
32+
private ConnectionInterface $connection;
33+
34+
private DatabaseInterface $db;
35+
36+
protected function setUp(): void
37+
{
38+
$this->connection = SqliteHelper::makeConnection();
39+
$this->db = new Database($this->connection);
40+
41+
// `order`, `select`, `from`, `where` are all reserved in standard SQL.
42+
// SQLite tolerates them inside double quotes when defined.
43+
$this->connection->getPDO()->exec(
44+
'CREATE TABLE posts (
45+
id INTEGER PRIMARY KEY AUTOINCREMENT,
46+
title TEXT,
47+
"order" INTEGER,
48+
"select" TEXT
49+
)'
50+
);
51+
$this->connection->getPDO()->exec(
52+
"INSERT INTO posts (title, \"order\", \"select\") VALUES
53+
('First', 1, 'a'),
54+
('Second', 2, 'b'),
55+
('Third', 3, 'c')"
56+
);
57+
}
58+
59+
public function testUpdateAcceptsReservedKeywordColumnInTheSetMap(): void
60+
{
61+
$this->db->where('id', 1)->update('posts', [
62+
'title' => 'Renamed',
63+
'order' => 10,
64+
]);
65+
66+
$row = $this->db
67+
->select('id', 'title', 'order')
68+
->from('posts')
69+
->where('id', 1)
70+
->read()
71+
->asAssoc()
72+
->row();
73+
74+
self::assertIsArray($row);
75+
self::assertSame('Renamed', $row['title']);
76+
self::assertSame(10, (int) $row['order']);
77+
}
78+
79+
public function testSelectAcceptsReservedKeywordColumnInTheProjection(): void
80+
{
81+
$rows = $this->db
82+
->select('id', 'order', 'select')
83+
->from('posts')
84+
->read()
85+
->asAssoc()
86+
->rows();
87+
88+
self::assertCount(3, $rows);
89+
self::assertArrayHasKey('order', $rows[0]);
90+
self::assertArrayHasKey('select', $rows[0]);
91+
}
92+
93+
public function testWhereAcceptsReservedKeywordColumn(): void
94+
{
95+
$rows = $this->db
96+
->select('id', 'title')
97+
->from('posts')
98+
->where('order', '>', 1)
99+
->read()
100+
->asAssoc()
101+
->rows();
102+
103+
self::assertCount(2, $rows);
104+
}
105+
106+
public function testOrderByAcceptsReservedKeywordColumn(): void
107+
{
108+
$rows = $this->db
109+
->select('id', 'title')
110+
->from('posts')
111+
->orderBy('order', 'DESC')
112+
->read()
113+
->asAssoc()
114+
->rows();
115+
116+
self::assertSame('Third', $rows[0]['title']);
117+
self::assertSame('First', $rows[2]['title']);
118+
}
119+
120+
public function testCompiledSqlActuallyQuotesTheIdentifier(): void
121+
{
122+
$this->db->enableQueryLog();
123+
$this->db->where('id', 1)->update('posts', ['order' => 5]);
124+
125+
$logs = $this->db->getQueryLogs();
126+
self::assertNotEmpty($logs);
127+
self::assertStringContainsString(
128+
'`order`',
129+
$logs[0]['query'],
130+
'Reserved identifiers must be emitted in their quoted form. If this assertion fails, '
131+
. 'upstream initorm/query-builder stopped escaping identifiers — file a bug there before '
132+
. 'shipping a release.'
133+
);
134+
}
135+
}

0 commit comments

Comments
 (0)