Skip to content

Commit

Permalink
Merge pull request #3548 from morozov/issues/3545
Browse files Browse the repository at this point in the history
Remove user provided PDO functionality
  • Loading branch information
morozov committed Jun 27, 2019
2 parents b6ab8df + 708ff44 commit 16e6957
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 245 deletions.
4 changes: 4 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
6 changes: 0 additions & 6 deletions lib/Doctrine/DBAL/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
Expand Down
18 changes: 1 addition & 17 deletions lib/Doctrine/DBAL/DriverManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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']];

Expand Down Expand Up @@ -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'])) {
Expand Down
15 changes: 0 additions & 15 deletions lib/Doctrine/DBAL/Exception/InvalidPdoInstance.php

This file was deleted.

77 changes: 11 additions & 66 deletions tests/Doctrine/Tests/DBAL/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
use Exception;
use PHPUnit\Framework\MockObject\MockObject;
use stdClass;
use function call_user_func_array;

/**
* @requires extension pdo_mysql
Expand Down Expand Up @@ -664,82 +663,28 @@ public function testFetchAll() : void
self::assertSame($result, $conn->fetchAll($statement, $params, $types));
}

public function testConnectionDoesNotMaintainTwoReferencesToExternalPDO() : void
{
$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() : void
{
$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() : void
{
/** @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', []);
}

/**
* @return array<int, array<int, mixed>>
*/
public static function dataCallConnectOnce() : iterable
{
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]],
];
}

/**
* @param array<int, mixed> $params
*
* @dataProvider dataCallConnectOnce
*/
public function testCallConnectOnce(string $method, array $params) : void
public function testCallConnectOnce() : void
{
$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();
}

/**
Expand Down
8 changes: 3 additions & 5 deletions tests/Doctrine/Tests/DBAL/Driver/PDOExceptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
Loading

0 comments on commit 16e6957

Please sign in to comment.