diff --git a/src/Drivers/IDriver.php b/src/Drivers/IDriver.php index 0dd179b..14d7c6a 100644 --- a/src/Drivers/IDriver.php +++ b/src/Drivers/IDriver.php @@ -136,7 +136,7 @@ public function rollbackTransaction(): void; * @throws DriverException * @internal */ - public function createSavepoint(string $name): void; + public function createSavepoint(string|Fqn $name): void; /** @@ -144,7 +144,7 @@ public function createSavepoint(string $name): void; * @throws DriverException * @internal */ - public function releaseSavepoint(string $name): void; + public function releaseSavepoint(string|Fqn $name): void; /** @@ -152,7 +152,7 @@ public function releaseSavepoint(string $name): void; * @throws DriverException * @internal */ - public function rollbackSavepoint(string $name): void; + public function rollbackSavepoint(string|Fqn $name): void; /** diff --git a/src/Drivers/Mysqli/MysqliDriver.php b/src/Drivers/Mysqli/MysqliDriver.php index 56cc66d..05459cb 100644 --- a/src/Drivers/Mysqli/MysqliDriver.php +++ b/src/Drivers/Mysqli/MysqliDriver.php @@ -96,7 +96,7 @@ public function connect(array $params, ILogger $logger): void throw $this->createException( $this->connection->connect_error ?? $this->connection->error, // @phpstan-ignore-line $this->connection->connect_errno, - 'HY000' + 'HY000', ); } @@ -148,7 +148,7 @@ public function query(string $query): Result $this->connection->error, $this->connection->errno, $this->connection->sqlstate, - $query + $query, ); } @@ -250,27 +250,24 @@ public function rollbackTransaction(): void } - public function createSavepoint(string $name): void + public function createSavepoint(string|Fqn $name): void { $this->checkConnection(); - $identifier = str_replace(['`', '.'], ['``', '`.`'], $name); - $this->loggedQuery("SAVEPOINT $identifier"); + $this->loggedQuery('SAVEPOINT ' . $this->convertIdentifierToSql($name)); } - public function releaseSavepoint(string $name): void + public function releaseSavepoint(string|Fqn $name): void { $this->checkConnection(); - $identifier = str_replace(['`', '.'], ['``', '`.`'], $name); - $this->loggedQuery("RELEASE SAVEPOINT $identifier"); + $this->loggedQuery('RELEASE SAVEPOINT ' . $this->convertIdentifierToSql($name)); } - public function rollbackSavepoint(string $name): void + public function rollbackSavepoint(string|Fqn $name): void { $this->checkConnection(); - $identifier = str_replace(['`', '.'], ['``', '`.`'], $name); - $this->loggedQuery("ROLLBACK TO SAVEPOINT $identifier"); + $this->loggedQuery('ROLLBACK TO SAVEPOINT ' . $this->convertIdentifierToSql($name)); } @@ -297,7 +294,7 @@ protected function setupSsl(array $params): void $params['sslCert'] ?? '', $params['sslCa'] ?? '', $params['sslCapath'] ?? '', - $params['sslCipher'] ?? '' + $params['sslCipher'] ?? '', ); } @@ -346,6 +343,17 @@ public function convertStringToSql(string $value): string } + protected function convertIdentifierToSql(string|Fqn $identifier): string + { + $escaped = match (true) { + $identifier instanceof Fqn => str_replace('`', '``', $identifier->schema) . '.' + . str_replace('`', '``', $identifier->name), + default => str_replace('`', '``', $identifier), + }; + return '`' . $escaped . '`'; + } + + /** * This method is based on Doctrine\DBAL project. * @link www.doctrine-project.org diff --git a/src/Drivers/Pdo/PdoDriver.php b/src/Drivers/Pdo/PdoDriver.php index 1856662..d074543 100644 --- a/src/Drivers/Pdo/PdoDriver.php +++ b/src/Drivers/Pdo/PdoDriver.php @@ -208,7 +208,7 @@ public function rollbackTransaction(): void } - public function createSavepoint(string $name): void + public function createSavepoint(string|Fqn $name): void { $this->checkConnection(); $identifier = $this->convertIdentifierToSql($name); @@ -216,7 +216,7 @@ public function createSavepoint(string $name): void } - public function releaseSavepoint(string $name): void + public function releaseSavepoint(string|Fqn $name): void { $this->checkConnection(); $identifier = $this->convertIdentifierToSql($name); @@ -224,7 +224,7 @@ public function releaseSavepoint(string $name): void } - public function rollbackSavepoint(string $name): void + public function rollbackSavepoint(string|Fqn $name): void { $this->checkConnection(); $identifier = $this->convertIdentifierToSql($name); @@ -246,7 +246,7 @@ public function convertStringToSql(string $value): string abstract protected function createResultAdapter(PDOStatement $statement): IResultAdapter; - abstract protected function convertIdentifierToSql(string $identifier): string; + abstract protected function convertIdentifierToSql(string|Fqn $identifier): string; abstract protected function createException( diff --git a/src/Drivers/PdoMysql/PdoMysqlDriver.php b/src/Drivers/PdoMysql/PdoMysqlDriver.php index 138d29e..105f4ef 100644 --- a/src/Drivers/PdoMysql/PdoMysqlDriver.php +++ b/src/Drivers/PdoMysql/PdoMysqlDriver.php @@ -129,9 +129,13 @@ protected function createResultAdapter(PDOStatement $statement): IResultAdapter } - protected function convertIdentifierToSql(string $identifier): string + protected function convertIdentifierToSql(string|Fqn $identifier): string { - return str_replace(['`', '.'], ['``', '`.`'], $identifier); + return match (true) { + $identifier instanceof Fqn => str_replace('`', '``', $identifier->schema) . '.' + . str_replace('`', '``', $identifier->name), + default => str_replace('`', '``', $identifier), + }; } diff --git a/src/Drivers/PdoPgsql/PdoPgsqlDriver.php b/src/Drivers/PdoPgsql/PdoPgsqlDriver.php index 48922f5..3451a27 100644 --- a/src/Drivers/PdoPgsql/PdoPgsqlDriver.php +++ b/src/Drivers/PdoPgsql/PdoPgsqlDriver.php @@ -83,7 +83,7 @@ public function getLastInsertedId(string|Fqn|null $sequenceName = null): mixed assert($this->connection !== null); $sequenceName = match (true) { - $sequenceName instanceOf Fqn => $this->convertIdentifierToSql($sequenceName->schema) . '.' . + $sequenceName instanceof Fqn => $this->convertIdentifierToSql($sequenceName->schema) . '.' . $this->convertIdentifierToSql($sequenceName->name), default => $this->convertIdentifierToSql($sequenceName), }; @@ -115,9 +115,14 @@ protected function createResultAdapter(PDOStatement $statement): IResultAdapter } - protected function convertIdentifierToSql(string $identifier): string + protected function convertIdentifierToSql(string|Fqn $identifier): string { - return '"' . str_replace(['"', '.'], ['""', '"."'], $identifier) . '"'; + $escaped = match (true) { + $identifier instanceof Fqn => str_replace('"', '""', $identifier->schema) . '.' + . str_replace('"', '""', $identifier->name), + default => str_replace('"', '""', $identifier), + }; + return '"' . $escaped . '"'; } diff --git a/src/Drivers/PdoSqlsrv/PdoSqlsrvDriver.php b/src/Drivers/PdoSqlsrv/PdoSqlsrvDriver.php index 672e809..3467b7d 100644 --- a/src/Drivers/PdoSqlsrv/PdoSqlsrvDriver.php +++ b/src/Drivers/PdoSqlsrv/PdoSqlsrvDriver.php @@ -118,21 +118,21 @@ public function setTransactionIsolationLevel(int $level): void } - public function createSavepoint(string $name): void + public function createSavepoint(string|Fqn $name): void { $this->checkConnection(); $this->loggedQuery('SAVE TRANSACTION ' . $this->convertIdentifierToSql($name)); } - public function releaseSavepoint(string $name): void + public function releaseSavepoint(string|Fqn $name): void { // transaction are released automatically // http://stackoverflow.com/questions/3101312/sql-server-2008-no-release-savepoint-for-current-transaction } - public function rollbackSavepoint(string $name): void + public function rollbackSavepoint(string|Fqn $name): void { $this->checkConnection(); $this->loggedQuery('ROLLBACK TRANSACTION ' . $this->convertIdentifierToSql($name)); @@ -146,9 +146,14 @@ protected function createResultAdapter(PDOStatement $statement): IResultAdapter } - protected function convertIdentifierToSql(string $identifier): string + protected function convertIdentifierToSql(string|Fqn $identifier): string { - return '[' . str_replace([']', '.'], [']]', '].['], $identifier) . ']'; + $escaped = match (true) { + $identifier instanceof Fqn => str_replace(']', ']]', $identifier->schema) . '.' + . str_replace(']', ']]', $identifier->name), + default => str_replace(']', ']]', $identifier), + }; + return '[' . $escaped . ']'; } diff --git a/src/Drivers/Pgsql/PgsqlDriver.php b/src/Drivers/Pgsql/PgsqlDriver.php index 595529f..c5f0e8c 100644 --- a/src/Drivers/Pgsql/PgsqlDriver.php +++ b/src/Drivers/Pgsql/PgsqlDriver.php @@ -187,11 +187,7 @@ public function getLastInsertedId(string|Fqn|null $sequenceName = null): mixed $this->checkConnection(); assert($this->connection !== null); - $sequenceName = match (true) { - $sequenceName instanceOf Fqn => pg_escape_identifier($this->connection, $sequenceName->schema) . '.' . - pg_escape_identifier($this->connection, $sequenceName->name), - default => pg_escape_identifier($this->connection, $sequenceName), - }; + $sequenceName = $this->convertIdentifierToSql($sequenceName); $sql = 'SELECT CURRVAL(\'' . $sequenceName . '\')'; return $this->loggedQuery($sql)->fetchField(); } @@ -268,7 +264,7 @@ public function rollbackTransaction(): void } - public function createSavepoint(string $name): void + public function createSavepoint(string|Fqn $name): void { $this->checkConnection(); assert($this->connection !== null); @@ -276,7 +272,7 @@ public function createSavepoint(string $name): void } - public function releaseSavepoint(string $name): void + public function releaseSavepoint(string|Fqn $name): void { $this->checkConnection(); assert($this->connection !== null); @@ -284,7 +280,7 @@ public function releaseSavepoint(string $name): void } - public function rollbackSavepoint(string $name): void + public function rollbackSavepoint(string|Fqn $name): void { $this->checkConnection(); assert($this->connection !== null); @@ -304,11 +300,15 @@ public function convertStringToSql(string $value): string } - protected function convertIdentifierToSql(string $identifier): string + protected function convertIdentifierToSql(string|Fqn $identifier): string { $this->checkConnection(); assert($this->connection !== null); - $escaped = pg_escape_identifier($this->connection, $identifier); + $escaped = match (true) { + $identifier instanceof Fqn => pg_escape_identifier($this->connection, $identifier->schema) . '.' . + pg_escape_identifier($this->connection, $identifier->name), + default => pg_escape_identifier($this->connection, $identifier), + }; if ($escaped === false) { throw new InvalidStateException(); } diff --git a/src/Drivers/Sqlsrv/SqlsrvDriver.php b/src/Drivers/Sqlsrv/SqlsrvDriver.php index 7d6fba5..1dc92d3 100644 --- a/src/Drivers/Sqlsrv/SqlsrvDriver.php +++ b/src/Drivers/Sqlsrv/SqlsrvDriver.php @@ -293,21 +293,21 @@ public function rollbackTransaction(): void } - public function createSavepoint(string $name): void + public function createSavepoint(string|Fqn $name): void { $this->checkConnection(); $this->loggedQuery('SAVE TRANSACTION ' . $this->convertIdentifierToSql($name)); } - public function releaseSavepoint(string $name): void + public function releaseSavepoint(string|Fqn $name): void { // transaction are released automatically // http://stackoverflow.com/questions/3101312/sql-server-2008-no-release-savepoint-for-current-transaction } - public function rollbackSavepoint(string $name): void + public function rollbackSavepoint(string|Fqn $name): void { $this->checkConnection(); $this->loggedQuery('ROLLBACK TRANSACTION ' . $this->convertIdentifierToSql($name)); @@ -320,9 +320,14 @@ public function convertStringToSql(string $value): string } - protected function convertIdentifierToSql(string $value): string + protected function convertIdentifierToSql(string|Fqn $identifier): string { - return '[' . str_replace([']', '.'], [']]', '].['], $value) . ']'; + $escaped = match (true) { + $identifier instanceof Fqn => str_replace(']', ']]', $identifier->schema) . '.' + . str_replace(']', ']]', $identifier->name), + default => str_replace(']', ']]', $identifier), + }; + return '[' . $escaped . ']'; }