From 1c41a5970bb8fefeac070aab565d09e993929647 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Mon, 20 May 2019 15:22:56 -0700 Subject: [PATCH] Remove user provided PDO functionality --- UPGRADE.md | 4 + lib/Doctrine/DBAL/Connection.php | 6 - lib/Doctrine/DBAL/DriverManager.php | 18 +-- .../DBAL/Exception/InvalidPdoInstance.php | 15 --- tests/Doctrine/Tests/DBAL/ConnectionTest.php | 73 ++--------- .../Tests/DBAL/Driver/PDOExceptionTest.php | 8 +- .../Doctrine/Tests/DBAL/DriverManagerTest.php | 118 +----------------- .../Functional/Driver/PDOConnectionTest.php | 8 +- .../DBAL/Functional/PDOStatementTest.php | 8 +- 9 files changed, 29 insertions(+), 229 deletions(-) delete mode 100644 lib/Doctrine/DBAL/Exception/InvalidPdoInstance.php diff --git a/UPGRADE.md b/UPGRADE.md index 4f938ec0329..be3702745b3 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,9 @@ # Upgrade to 3.0 +## BC BREAK User-provided `PDO` instance is no longer supported + +In order to share the same `PDO` instances between DBAL and other components, initialize the connection in DBAL and access it using `Connection::getWrappedConnection()->getWrappedConnection()`. + ## BC BREAK PostgreSqlPlatform ForeignKeyConstraint support for `feferred` misspelling removed `PostgreSqlPlatform::getAdvancedForeignKeyOptionsSQL()` had a typo in it in 2.x. Both the option name diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index 26c35ed828a..f5dcadd9785 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -197,12 +197,6 @@ public function __construct( $this->_driver = $driver; $this->params = $params; - if (isset($params['pdo'])) { - $this->_conn = $params['pdo']; - $this->isConnected = true; - unset($this->params['pdo']); - } - if (isset($params['platform'])) { if (! $params['platform'] instanceof Platforms\AbstractPlatform) { throw InvalidPlatformType::new($params['platform']); diff --git a/lib/Doctrine/DBAL/DriverManager.php b/lib/Doctrine/DBAL/DriverManager.php index 4a16ee1735c..3699efc71e5 100644 --- a/lib/Doctrine/DBAL/DriverManager.php +++ b/lib/Doctrine/DBAL/DriverManager.php @@ -17,10 +17,8 @@ use Doctrine\DBAL\Driver\SQLSrv\Driver as SQLSrvDriver; use Doctrine\DBAL\Exception\DriverRequired; use Doctrine\DBAL\Exception\InvalidDriverClass; -use Doctrine\DBAL\Exception\InvalidPdoInstance; use Doctrine\DBAL\Exception\InvalidWrapperClass; use Doctrine\DBAL\Exception\UnknownDriver; -use PDO; use function array_keys; use function array_map; use function array_merge; @@ -175,17 +173,7 @@ public static function getConnection( } } - // check for existing pdo object - if (isset($params['pdo']) && ! $params['pdo'] instanceof PDO) { - throw InvalidPdoInstance::new(); - } - - if (isset($params['pdo'])) { - $params['pdo']->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $params['driver'] = 'pdo_' . $params['pdo']->getAttribute(PDO::ATTR_DRIVER_NAME); - } else { - self::_checkParams($params); - } + self::_checkParams($params); $className = $params['driverClass'] ?? self::$_driverMap[$params['driver']]; @@ -281,10 +269,6 @@ private static function parseDatabaseUrl(array $params) : array $url = array_map('rawurldecode', $url); - // If we have a connection URL, we have to unset the default PDO instance connection parameter (if any) - // as we cannot merge connection details from the URL into the PDO instance (URL takes precedence). - unset($params['pdo']); - $params = self::parseDatabaseUrlScheme($url, $params); if (isset($url['host'])) { diff --git a/lib/Doctrine/DBAL/Exception/InvalidPdoInstance.php b/lib/Doctrine/DBAL/Exception/InvalidPdoInstance.php deleted file mode 100644 index dd5609e65d9..00000000000 --- a/lib/Doctrine/DBAL/Exception/InvalidPdoInstance.php +++ /dev/null @@ -1,15 +0,0 @@ -fetchAll($statement, $params, $types)); } - public function testConnectionDoesNotMaintainTwoReferencesToExternalPDO() - { - $params['pdo'] = new stdClass(); - - $driverMock = $this->createMock(Driver::class); - - $conn = new Connection($params, $driverMock); - - self::assertArrayNotHasKey('pdo', $conn->getParams(), 'Connection is maintaining additional reference to the PDO connection'); - } - - public function testPassingExternalPDOMeansConnectionIsConnected() - { - $params['pdo'] = new stdClass(); - - $driverMock = $this->createMock(Driver::class); - - $conn = new Connection($params, $driverMock); - - self::assertTrue($conn->isConnected(), 'Connection is not connected after passing external PDO'); - } - public function testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException() { /** @var Driver $driver */ - $driver = $this->createMock(Driver::class); - $pdoMock = $this->createMock(\Doctrine\DBAL\Driver\Connection::class); - - // should never execute queries with invalid arguments - $pdoMock->expects($this->never())->method('exec'); - $pdoMock->expects($this->never())->method('prepare'); - - $conn = new Connection(['pdo' => $pdoMock], $driver); + $driver = $this->createMock(Driver::class); + $conn = new Connection([], $driver); $this->expectException(InvalidArgumentException::class); $conn->delete('kittens', []); } - public function dataCallConnectOnce() + public function testCallConnectOnce() { - return [ - ['delete', ['tbl', ['id' => 12345]]], - ['insert', ['tbl', ['data' => 'foo']]], - ['update', ['tbl', ['data' => 'bar'], ['id' => 12345]]], - ['prepare', ['select * from dual']], - ['executeUpdate', ['insert into tbl (id) values (?)'], [123]], - ]; - } - - /** - * @dataProvider dataCallConnectOnce - */ - public function testCallConnectOnce($method, $params) - { - $driverMock = $this->createMock(Driver::class); - $pdoMock = $this->createMock(Connection::class); - $platformMock = $this->createMock(AbstractPlatform::class); - $stmtMock = $this->createMock(Statement::class); - - $pdoMock->expects($this->any()) - ->method('prepare') - ->will($this->returnValue($stmtMock)); - - $conn = $this->getMockBuilder(Connection::class) - ->setConstructorArgs([['pdo' => $pdoMock, 'platform' => $platformMock], $driverMock]) - ->setMethods(['connect']) - ->getMock(); + /** @var Driver|MockObject $driver */ + $driver = $this->createMock(Driver::class); + $driver->expects($this->once()) + ->method('connect'); - $conn->expects($this->once())->method('connect'); + $platform = $this->createMock(AbstractPlatform::class); - call_user_func_array([$conn, $method], $params); + $conn = new Connection(['platform' => $platform], $driver); + $conn->connect(); + $conn->connect(); } /** diff --git a/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php b/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php index f8930233dc0..3f60ec1d5d2 100644 --- a/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php +++ b/tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php @@ -7,8 +7,10 @@ use Doctrine\DBAL\Driver\PDOException; use Doctrine\Tests\DbalTestCase; use PHPUnit\Framework\MockObject\MockObject; -use function extension_loaded; +/** + * @requires extension pdo + */ class PDOExceptionTest extends DbalTestCase { public const ERROR_CODE = 666; @@ -33,10 +35,6 @@ class PDOExceptionTest extends DbalTestCase protected function setUp() : void { - if (! extension_loaded('PDO')) { - $this->markTestSkipped('PDO is not installed.'); - } - parent::setUp(); $this->wrappedException = new \PDOException(self::MESSAGE); diff --git a/tests/Doctrine/Tests/DBAL/DriverManagerTest.php b/tests/Doctrine/Tests/DBAL/DriverManagerTest.php index 7dbb4f5bdd0..0fa043e568d 100644 --- a/tests/Doctrine/Tests/DBAL/DriverManagerTest.php +++ b/tests/Doctrine/Tests/DBAL/DriverManagerTest.php @@ -16,50 +16,13 @@ use Doctrine\DBAL\Sharding\PoolingShardConnection; use Doctrine\DBAL\Sharding\ShardChoser\MultiTenantShardChoser; use Doctrine\Tests\DbalTestCase; -use PDO; use stdClass; -use function extension_loaded; use function get_class; use function in_array; use function is_array; class DriverManagerTest extends DbalTestCase { - /** - * @requires extension pdo_sqlite - */ - public function testInvalidPdoInstance() - { - $this->expectException(DBALException::class); - DriverManager::getConnection(['pdo' => 'test']); - } - - /** - * @requires extension pdo_sqlite - */ - public function testValidPdoInstance() - { - $conn = DriverManager::getConnection([ - 'pdo' => new PDO('sqlite::memory:'), - ]); - - self::assertEquals('sqlite', $conn->getDatabasePlatform()->getName()); - } - - /** - * @group DBAL-32 - * @requires extension pdo_sqlite - */ - public function testPdoInstanceSetErrorMode() - { - $pdo = new PDO('sqlite::memory:'); - $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); - $options = ['pdo' => $pdo]; - - DriverManager::getConnection($options); - self::assertEquals(PDO::ERRMODE_EXCEPTION, $pdo->getAttribute(PDO::ATTR_ERRMODE)); - } - public function testCheckParams() { $this->expectException(DBALException::class); @@ -81,7 +44,7 @@ public function testCustomPlatform() { $platform = $this->createMock(AbstractPlatform::class); $options = [ - 'pdo' => new PDO('sqlite::memory:'), + 'url' => 'sqlite::memory:', 'platform' => $platform, ]; @@ -98,7 +61,7 @@ public function testCustomWrapper() $wrapperClass = get_class($wrapper); $options = [ - 'pdo' => new PDO('sqlite::memory:'), + 'url' => 'sqlite::memory:', 'wrapperClass' => $wrapperClass, ]; @@ -114,7 +77,7 @@ public function testInvalidWrapperClass() $this->expectException(DBALException::class); $options = [ - 'pdo' => new PDO('sqlite::memory:'), + 'url' => 'sqlite::memory:', 'wrapperClass' => stdClass::class, ]; @@ -213,16 +176,6 @@ public function testDatabaseUrl($url, $expected) { $options = is_array($url) ? $url : ['url' => $url]; - if (isset($options['pdo'])) { - if (! extension_loaded('pdo')) { - $this->markTestSkipped('PDO is not installed'); - } - - $options['pdo'] = $this->createMock(PDO::class); - } - - $options = is_array($url) ? $url : ['url' => $url]; - if ($expected === false) { $this->expectException(DBALException::class); } @@ -231,7 +184,7 @@ public function testDatabaseUrl($url, $expected) $params = $conn->getParams(); foreach ($expected as $key => $value) { - if (in_array($key, ['pdo', 'driver', 'driverClass'], true)) { + if (in_array($key, ['driver', 'driverClass'], true)) { self::assertInstanceOf($value, $conn->getDriver()); } else { self::assertEquals($value, $params[$key]); @@ -389,13 +342,6 @@ public function databaseUrls() ['url' => '//foo:bar@localhost/baz'], false, ], - 'URL without scheme but default PDO driver' => [ - [ - 'url' => '//foo:bar@localhost/baz', - 'pdo' => true, - ], - false, - ], 'URL without scheme but default driver' => [ [ 'url' => '//foo:bar@localhost/baz', @@ -422,20 +368,6 @@ public function databaseUrls() 'driverClass' => $driverClass, ], ], - 'URL without scheme but default PDO driver and default driver' => [ - [ - 'url' => '//foo:bar@localhost/baz', - 'pdo' => true, - 'driver' => 'pdo_mysql', - ], - [ - 'user' => 'foo', - 'password' => 'bar', - 'host' => 'localhost', - 'dbname' => 'baz', - 'driver' => PDOMySQLDriver::class, - ], - ], 'URL without scheme but driver and custom driver' => [ [ 'url' => '//foo:bar@localhost/baz', @@ -450,19 +382,6 @@ public function databaseUrls() 'driverClass' => $driverClass, ], ], - 'URL with default PDO driver' => [ - [ - 'url' => 'mysql://foo:bar@localhost/baz', - 'pdo' => true, - ], - [ - 'user' => 'foo', - 'password' => 'bar', - 'host' => 'localhost', - 'dbname' => 'baz', - 'driver' => PDOMySQLDriver::class, - ], - ], 'URL with default driver' => [ [ 'url' => 'mysql://foo:bar@localhost/baz', @@ -489,20 +408,6 @@ public function databaseUrls() 'driver' => PDOMySQLDriver::class, ], ], - 'URL with default PDO driver and default driver' => [ - [ - 'url' => 'mysql://foo:bar@localhost/baz', - 'pdo' => true, - 'driver' => 'sqlite', - ], - [ - 'user' => 'foo', - 'password' => 'bar', - 'host' => 'localhost', - 'dbname' => 'baz', - 'driver' => PDOMySQLDriver::class, - ], - ], 'URL with default driver and default custom driver' => [ [ 'url' => 'mysql://foo:bar@localhost/baz', @@ -517,21 +422,6 @@ public function databaseUrls() 'driver' => PDOMySQLDriver::class, ], ], - 'URL with default PDO driver and default driver and default custom driver' => [ - [ - 'url' => 'mysql://foo:bar@localhost/baz', - 'pdo' => true, - 'driver' => 'sqlite', - 'driverClass' => $driverClass, - ], - [ - 'user' => 'foo', - 'password' => 'bar', - 'host' => 'localhost', - 'dbname' => 'baz', - 'driver' => PDOMySQLDriver::class, - ], - ], ]; } } diff --git a/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOConnectionTest.php b/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOConnectionTest.php index 318f285a818..ab14c753ce8 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOConnectionTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Driver/PDOConnectionTest.php @@ -8,9 +8,11 @@ use Doctrine\DBAL\Driver\PDOException; use Doctrine\Tests\DbalFunctionalTestCase; use PDO; -use function extension_loaded; use function sprintf; +/** + * @requires extension pdo + */ class PDOConnectionTest extends DbalFunctionalTestCase { /** @@ -22,10 +24,6 @@ class PDOConnectionTest extends DbalFunctionalTestCase protected function setUp() : void { - if (! extension_loaded('PDO')) { - $this->markTestSkipped('PDO is not installed.'); - } - parent::setUp(); $this->driverConnection = $this->connection->getWrappedConnection(); diff --git a/tests/Doctrine/Tests/DBAL/Functional/PDOStatementTest.php b/tests/Doctrine/Tests/DBAL/Functional/PDOStatementTest.php index c1982cbc0c8..869d52c85b5 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/PDOStatementTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/PDOStatementTest.php @@ -8,16 +8,14 @@ use Doctrine\DBAL\Schema\Table; use Doctrine\Tests\DbalFunctionalTestCase; use PDO; -use function extension_loaded; +/** + * @requires extension pdo + */ class PDOStatementTest extends DbalFunctionalTestCase { protected function setUp() : void { - if (! extension_loaded('pdo')) { - $this->markTestSkipped('PDO is not installed'); - } - parent::setUp(); if (! $this->connection->getWrappedConnection() instanceof PDOConnection) {