Skip to content

Commit 510e6b7

Browse files
authored
Merge pull request #221 from nextras/sequence-casing
Fix sequence casing escaping & add support for FQN for last inserted id (BC break!)
2 parents 0718360 + 5475de2 commit 510e6b7

File tree

11 files changed

+112
-52
lines changed

11 files changed

+112
-52
lines changed

src/Connection.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Exception;
77
use Nextras\Dbal\Drivers\IDriver;
88
use Nextras\Dbal\Exception\InvalidArgumentException;
9+
use Nextras\Dbal\Platforms\Data\Fqn;
910
use Nextras\Dbal\Platforms\IPlatform;
1011
use Nextras\Dbal\QueryBuilder\QueryBuilder;
1112
use Nextras\Dbal\Result\Result;
@@ -144,7 +145,7 @@ public function queryByQueryBuilder(QueryBuilder $queryBuilder): Result
144145

145146

146147
/** @inheritdoc */
147-
public function getLastInsertedId(?string $sequenceName = null)
148+
public function getLastInsertedId(string|Fqn|null $sequenceName = null)
148149
{
149150
if (!$this->connected) {
150151
$this->connect();

src/Drivers/IDriver.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Nextras\Dbal\Exception\NotSupportedException;
99
use Nextras\Dbal\IConnection;
1010
use Nextras\Dbal\ILogger;
11+
use Nextras\Dbal\Platforms\Data\Fqn;
1112
use Nextras\Dbal\Platforms\IPlatform;
1213
use Nextras\Dbal\Result\Result;
1314

@@ -64,7 +65,7 @@ public function query(string $query): Result;
6465
* Returns the last inserted id.
6566
* @internal
6667
*/
67-
public function getLastInsertedId(?string $sequenceName = null): mixed;
68+
public function getLastInsertedId(string|Fqn|null $sequenceName = null): mixed;
6869

6970

7071
/**
@@ -135,23 +136,23 @@ public function rollbackTransaction(): void;
135136
* @throws DriverException
136137
* @internal
137138
*/
138-
public function createSavepoint(string $name): void;
139+
public function createSavepoint(string|Fqn $name): void;
139140

140141

141142
/**
142143
* Releases the savepoint.
143144
* @throws DriverException
144145
* @internal
145146
*/
146-
public function releaseSavepoint(string $name): void;
147+
public function releaseSavepoint(string|Fqn $name): void;
147148

148149

149150
/**
150151
* Rollbacks the savepoint.
151152
* @throws DriverException
152153
* @internal
153154
*/
154-
public function rollbackSavepoint(string $name): void;
155+
public function rollbackSavepoint(string|Fqn $name): void;
155156

156157

157158
/**

src/Drivers/Mysqli/MysqliDriver.php

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Nextras\Dbal\Exception\NotSupportedException;
1818
use Nextras\Dbal\IConnection;
1919
use Nextras\Dbal\ILogger;
20+
use Nextras\Dbal\Platforms\Data\Fqn;
2021
use Nextras\Dbal\Platforms\IPlatform;
2122
use Nextras\Dbal\Platforms\MySqlPlatform;
2223
use Nextras\Dbal\Result\Result;
@@ -95,7 +96,7 @@ public function connect(array $params, ILogger $logger): void
9596
throw $this->createException(
9697
$this->connection->connect_error ?? $this->connection->error, // @phpstan-ignore-line
9798
$this->connection->connect_errno,
98-
'HY000'
99+
'HY000',
99100
);
100101
}
101102

@@ -147,7 +148,7 @@ public function query(string $query): Result
147148
$this->connection->error,
148149
$this->connection->errno,
149150
$this->connection->sqlstate,
150-
$query
151+
$query,
151152
);
152153
}
153154

@@ -159,7 +160,7 @@ public function query(string $query): Result
159160
}
160161

161162

162-
public function getLastInsertedId(?string $sequenceName = null): mixed
163+
public function getLastInsertedId(string|Fqn|null $sequenceName = null): mixed
163164
{
164165
$this->checkConnection();
165166
assert($this->connection !== null);
@@ -249,27 +250,24 @@ public function rollbackTransaction(): void
249250
}
250251

251252

252-
public function createSavepoint(string $name): void
253+
public function createSavepoint(string|Fqn $name): void
253254
{
254255
$this->checkConnection();
255-
$identifier = str_replace(['`', '.'], ['``', '`.`'], $name);
256-
$this->loggedQuery("SAVEPOINT $identifier");
256+
$this->loggedQuery('SAVEPOINT ' . $this->convertIdentifierToSql($name));
257257
}
258258

259259

260-
public function releaseSavepoint(string $name): void
260+
public function releaseSavepoint(string|Fqn $name): void
261261
{
262262
$this->checkConnection();
263-
$identifier = str_replace(['`', '.'], ['``', '`.`'], $name);
264-
$this->loggedQuery("RELEASE SAVEPOINT $identifier");
263+
$this->loggedQuery('RELEASE SAVEPOINT ' . $this->convertIdentifierToSql($name));
265264
}
266265

267266

268-
public function rollbackSavepoint(string $name): void
267+
public function rollbackSavepoint(string|Fqn $name): void
269268
{
270269
$this->checkConnection();
271-
$identifier = str_replace(['`', '.'], ['``', '`.`'], $name);
272-
$this->loggedQuery("ROLLBACK TO SAVEPOINT $identifier");
270+
$this->loggedQuery('ROLLBACK TO SAVEPOINT ' . $this->convertIdentifierToSql($name));
273271
}
274272

275273

@@ -296,7 +294,7 @@ protected function setupSsl(array $params): void
296294
$params['sslCert'] ?? '',
297295
$params['sslCa'] ?? '',
298296
$params['sslCapath'] ?? '',
299-
$params['sslCipher'] ?? ''
297+
$params['sslCipher'] ?? '',
300298
);
301299
}
302300

@@ -345,6 +343,17 @@ public function convertStringToSql(string $value): string
345343
}
346344

347345

346+
protected function convertIdentifierToSql(string|Fqn $identifier): string
347+
{
348+
$escaped = match (true) {
349+
$identifier instanceof Fqn => str_replace('`', '``', $identifier->schema) . '.'
350+
. str_replace('`', '``', $identifier->name),
351+
default => str_replace('`', '``', $identifier),
352+
};
353+
return '`' . $escaped . '`';
354+
}
355+
356+
348357
/**
349358
* This method is based on Doctrine\DBAL project.
350359
* @link www.doctrine-project.org

src/Drivers/Pdo/PdoDriver.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Nextras\Dbal\Drivers\IDriver;
1010
use Nextras\Dbal\Exception\InvalidStateException;
1111
use Nextras\Dbal\ILogger;
12+
use Nextras\Dbal\Platforms\Data\Fqn;
1213
use Nextras\Dbal\Result\IResultAdapter;
1314
use Nextras\Dbal\Result\Result;
1415
use Nextras\Dbal\Utils\LoggerHelper;
@@ -108,7 +109,7 @@ public function query(string $query): Result
108109
}
109110

110111

111-
public function getLastInsertedId(?string $sequenceName = null): mixed
112+
public function getLastInsertedId(string|Fqn|null $sequenceName = null): mixed
112113
{
113114
$this->checkConnection();
114115
assert($this->connection !== null);
@@ -207,23 +208,23 @@ public function rollbackTransaction(): void
207208
}
208209

209210

210-
public function createSavepoint(string $name): void
211+
public function createSavepoint(string|Fqn $name): void
211212
{
212213
$this->checkConnection();
213214
$identifier = $this->convertIdentifierToSql($name);
214215
$this->loggedQuery("SAVEPOINT $identifier");
215216
}
216217

217218

218-
public function releaseSavepoint(string $name): void
219+
public function releaseSavepoint(string|Fqn $name): void
219220
{
220221
$this->checkConnection();
221222
$identifier = $this->convertIdentifierToSql($name);
222223
$this->loggedQuery("RELEASE SAVEPOINT $identifier");
223224
}
224225

225226

226-
public function rollbackSavepoint(string $name): void
227+
public function rollbackSavepoint(string|Fqn $name): void
227228
{
228229
$this->checkConnection();
229230
$identifier = $this->convertIdentifierToSql($name);
@@ -245,7 +246,7 @@ public function convertStringToSql(string $value): string
245246
abstract protected function createResultAdapter(PDOStatement $statement): IResultAdapter;
246247

247248

248-
abstract protected function convertIdentifierToSql(string $identifier): string;
249+
abstract protected function convertIdentifierToSql(string|Fqn $identifier): string;
249250

250251

251252
abstract protected function createException(

src/Drivers/PdoMysql/PdoMysqlDriver.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Nextras\Dbal\Exception\NotSupportedException;
1818
use Nextras\Dbal\IConnection;
1919
use Nextras\Dbal\ILogger;
20+
use Nextras\Dbal\Platforms\Data\Fqn;
2021
use Nextras\Dbal\Platforms\IPlatform;
2122
use Nextras\Dbal\Platforms\MySqlPlatform;
2223
use Nextras\Dbal\Result\IResultAdapter;
@@ -100,7 +101,7 @@ public function createPlatform(IConnection $connection): IPlatform
100101
}
101102

102103

103-
public function getLastInsertedId(?string $sequenceName = null): int
104+
public function getLastInsertedId(string|Fqn|null $sequenceName = null): int
104105
{
105106
return (int) parent::getLastInsertedId($sequenceName);
106107
}
@@ -128,9 +129,13 @@ protected function createResultAdapter(PDOStatement $statement): IResultAdapter
128129
}
129130

130131

131-
protected function convertIdentifierToSql(string $identifier): string
132+
protected function convertIdentifierToSql(string|Fqn $identifier): string
132133
{
133-
return str_replace(['`', '.'], ['``', '`.`'], $identifier);
134+
return match (true) {
135+
$identifier instanceof Fqn => str_replace('`', '``', $identifier->schema) . '.'
136+
. str_replace('`', '``', $identifier->name),
137+
default => str_replace('`', '``', $identifier),
138+
};
134139
}
135140

136141

src/Drivers/PdoPgsql/PdoPgsqlDriver.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Nextras\Dbal\Exception\NotSupportedException;
1818
use Nextras\Dbal\IConnection;
1919
use Nextras\Dbal\ILogger;
20+
use Nextras\Dbal\Platforms\Data\Fqn;
2021
use Nextras\Dbal\Platforms\IPlatform;
2122
use Nextras\Dbal\Platforms\PostgreSqlPlatform;
2223
use Nextras\Dbal\Result\IResultAdapter;
@@ -72,15 +73,21 @@ public function createPlatform(IConnection $connection): IPlatform
7273
}
7374

7475

75-
public function getLastInsertedId(?string $sequenceName = null): mixed
76+
public function getLastInsertedId(string|Fqn|null $sequenceName = null): mixed
7677
{
7778
if ($sequenceName === null) {
7879
throw new InvalidArgumentException('PgsqlDriver requires to pass sequence name for getLastInsertedId() method.');
7980
}
8081

8182
$this->checkConnection();
8283
assert($this->connection !== null);
83-
$sql = 'SELECT CURRVAL(' . $this->convertStringToSql($sequenceName) . ')';
84+
85+
$sequenceName = match (true) {
86+
$sequenceName instanceof Fqn => $this->convertIdentifierToSql($sequenceName->schema) . '.' .
87+
$this->convertIdentifierToSql($sequenceName->name),
88+
default => $this->convertIdentifierToSql($sequenceName),
89+
};
90+
$sql = 'SELECT CURRVAL(\'' . $sequenceName . '\')';
8491
return $this->loggedQuery($sql)->fetchField();
8592
}
8693

@@ -108,9 +115,14 @@ protected function createResultAdapter(PDOStatement $statement): IResultAdapter
108115
}
109116

110117

111-
protected function convertIdentifierToSql(string $identifier): string
118+
protected function convertIdentifierToSql(string|Fqn $identifier): string
112119
{
113-
return '"' . str_replace(['"', '.'], ['""', '"."'], $identifier) . '"';
120+
$escaped = match (true) {
121+
$identifier instanceof Fqn => str_replace('"', '""', $identifier->schema) . '.'
122+
. str_replace('"', '""', $identifier->name),
123+
default => str_replace('"', '""', $identifier),
124+
};
125+
return '"' . $escaped . '"';
114126
}
115127

116128

src/Drivers/PdoSqlsrv/PdoSqlsrvDriver.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Nextras\Dbal\Exception\NotSupportedException;
1515
use Nextras\Dbal\IConnection;
1616
use Nextras\Dbal\ILogger;
17+
use Nextras\Dbal\Platforms\Data\Fqn;
1718
use Nextras\Dbal\Platforms\IPlatform;
1819
use Nextras\Dbal\Platforms\SqlServerPlatform;
1920
use Nextras\Dbal\Result\IResultAdapter;
@@ -94,7 +95,7 @@ public function createPlatform(IConnection $connection): IPlatform
9495
}
9596

9697

97-
public function getLastInsertedId(?string $sequenceName = null): mixed
98+
public function getLastInsertedId(string|Fqn|null $sequenceName = null): mixed
9899
{
99100
$this->checkConnection();
100101
return $this->loggedQuery('SELECT SCOPE_IDENTITY()')->fetchField();
@@ -117,21 +118,21 @@ public function setTransactionIsolationLevel(int $level): void
117118
}
118119

119120

120-
public function createSavepoint(string $name): void
121+
public function createSavepoint(string|Fqn $name): void
121122
{
122123
$this->checkConnection();
123124
$this->loggedQuery('SAVE TRANSACTION ' . $this->convertIdentifierToSql($name));
124125
}
125126

126127

127-
public function releaseSavepoint(string $name): void
128+
public function releaseSavepoint(string|Fqn $name): void
128129
{
129130
// transaction are released automatically
130131
// http://stackoverflow.com/questions/3101312/sql-server-2008-no-release-savepoint-for-current-transaction
131132
}
132133

133134

134-
public function rollbackSavepoint(string $name): void
135+
public function rollbackSavepoint(string|Fqn $name): void
135136
{
136137
$this->checkConnection();
137138
$this->loggedQuery('ROLLBACK TRANSACTION ' . $this->convertIdentifierToSql($name));
@@ -145,9 +146,14 @@ protected function createResultAdapter(PDOStatement $statement): IResultAdapter
145146
}
146147

147148

148-
protected function convertIdentifierToSql(string $identifier): string
149+
protected function convertIdentifierToSql(string|Fqn $identifier): string
149150
{
150-
return '[' . str_replace([']', '.'], [']]', '].['], $identifier) . ']';
151+
$escaped = match (true) {
152+
$identifier instanceof Fqn => str_replace(']', ']]', $identifier->schema) . '.'
153+
. str_replace(']', ']]', $identifier->name),
154+
default => str_replace(']', ']]', $identifier),
155+
};
156+
return '[' . $escaped . ']';
151157
}
152158

153159

0 commit comments

Comments
 (0)