From 7a6fbac55b276d6997215d4850eed5b859724ec4 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Wed, 23 Jun 2021 12:26:31 -0700 Subject: [PATCH] [GH-4687] Deprecate Connection::lastInsertId($name) --- UPGRADE.md | 6 ++++++ src/Connection.php | 8 ++++++++ src/Driver/IBMDB2/Connection.php | 9 +++++++++ src/Driver/Mysqli/Connection.php | 9 +++++++++ src/Driver/OCI8/Connection.php | 7 +++++++ src/Driver/PDO/Connection.php | 7 +++++++ src/Driver/PDO/SQLSrv/Connection.php | 7 +++++++ src/Driver/SQLSrv/Connection.php | 7 +++++++ src/Portability/Connection.php | 9 +++++++++ 9 files changed, 69 insertions(+) diff --git a/UPGRADE.md b/UPGRADE.md index b2565e7add2..0d4a4f8461e 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -8,6 +8,12 @@ awareness about deprecated code. # Upgrade to 3.2 +## Deprecated `Connection::lastInsertId($name)` + +The usage of `Connection::lastInsertId()` with a sequence name is deprecated as unsafe in scenarios with multiple +concurrent connections. If a newly inserted row needs to be referenced, it is recommended to generate its identifier +explicitly prior to insertion. + ## Introduction of PSR-6 for result caching Instead of relying on the deprecated `doctrine/cache` library, a PSR-6 cache diff --git a/src/Connection.php b/src/Connection.php index 8ffdd82994c..2b4fbb28c04 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -1209,6 +1209,14 @@ public function getTransactionNestingLevel() */ public function lastInsertId($name = null) { + if ($name !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.' + ); + } + try { return $this->getWrappedConnection()->lastInsertId($name); } catch (Driver\Exception $e) { diff --git a/src/Driver/IBMDB2/Connection.php b/src/Driver/IBMDB2/Connection.php index c8e36da3ea8..32e683ab25d 100644 --- a/src/Driver/IBMDB2/Connection.php +++ b/src/Driver/IBMDB2/Connection.php @@ -10,6 +10,7 @@ use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use stdClass; use function assert; @@ -119,6 +120,14 @@ public function exec(string $sql): int */ public function lastInsertId($name = null) { + if ($name !== null) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.' + ); + } + return db2_last_insert_id($this->conn); } diff --git a/src/Driver/Mysqli/Connection.php b/src/Driver/Mysqli/Connection.php index 23fdac0e313..d0ae82d9823 100644 --- a/src/Driver/Mysqli/Connection.php +++ b/src/Driver/Mysqli/Connection.php @@ -9,6 +9,7 @@ use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use mysqli; use function assert; @@ -134,6 +135,14 @@ public function exec(string $sql): int */ public function lastInsertId($name = null) { + if ($name !== null) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.' + ); + } + return $this->conn->insert_id; } diff --git a/src/Driver/OCI8/Connection.php b/src/Driver/OCI8/Connection.php index 1bc5c62cede..12149e58129 100644 --- a/src/Driver/OCI8/Connection.php +++ b/src/Driver/OCI8/Connection.php @@ -10,6 +10,7 @@ use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use function addcslashes; use function assert; @@ -125,6 +126,12 @@ public function lastInsertId($name = null) return false; } + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.' + ); + $result = $this->query('SELECT ' . $name . '.CURRVAL FROM DUAL')->fetchOne(); if ($result === false) { diff --git a/src/Driver/PDO/Connection.php b/src/Driver/PDO/Connection.php index 169016937af..4d7b90b6e31 100644 --- a/src/Driver/PDO/Connection.php +++ b/src/Driver/PDO/Connection.php @@ -7,6 +7,7 @@ use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use PDO; use PDOException; use PDOStatement; @@ -106,6 +107,12 @@ public function lastInsertId($name = null) return $this->connection->lastInsertId(); } + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.' + ); + return $this->connection->lastInsertId($name); } catch (PDOException $exception) { throw Exception::new($exception); diff --git a/src/Driver/PDO/SQLSrv/Connection.php b/src/Driver/PDO/SQLSrv/Connection.php index a64f4245a18..f9ae09b9b17 100644 --- a/src/Driver/PDO/SQLSrv/Connection.php +++ b/src/Driver/PDO/SQLSrv/Connection.php @@ -7,6 +7,7 @@ use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use PDO; final class Connection implements ServerInfoAwareConnection @@ -53,6 +54,12 @@ public function lastInsertId($name = null) return $this->connection->lastInsertId($name); } + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.' + ); + return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?') ->execute([$name]) ->fetchOne(); diff --git a/src/Driver/SQLSrv/Connection.php b/src/Driver/SQLSrv/Connection.php index e37ea9006cd..b8f9f27b41d 100644 --- a/src/Driver/SQLSrv/Connection.php +++ b/src/Driver/SQLSrv/Connection.php @@ -8,6 +8,7 @@ use Doctrine\DBAL\Driver\SQLSrv\Exception\Error; use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use function is_float; use function is_int; @@ -109,6 +110,12 @@ public function exec(string $sql): int public function lastInsertId($name = null) { if ($name !== null) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.' + ); + $result = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?') ->execute([$name]); } else { diff --git a/src/Portability/Connection.php b/src/Portability/Connection.php index a56397924ba..0e9405bf23b 100644 --- a/src/Portability/Connection.php +++ b/src/Portability/Connection.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Driver\Result as DriverResult; use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; /** * Portability wrapper for a Connection. @@ -64,6 +65,14 @@ public function exec(string $sql): int */ public function lastInsertId($name = null) { + if ($name !== null) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.' + ); + } + return $this->connection->lastInsertId($name); }