Skip to content

Commit

Permalink
Merge branch '3.3.x' into 4.0.x
Browse files Browse the repository at this point in the history
* 3.3.x:
  Deprecate Connection::getWrappedConnection(), mark Connection::connect() internal
  Add Connection::getNativeConnection()
  Provide abstract middleware classes
  • Loading branch information
derrabus committed Nov 27, 2021
2 parents 35ead67 + 906dc83 commit 9a669e6
Show file tree
Hide file tree
Showing 31 changed files with 703 additions and 199 deletions.
24 changes: 24 additions & 0 deletions UPGRADE.md
Expand Up @@ -539,6 +539,30 @@ The following methods have been removed.
| `QueryCacheProfile` | `setResultCacheDriver()` | `setResultCache()` |
| `QueryCacheProfile` | `getResultCacheDriver()` | `getResultCache()` |

# Upgrade to 3.3

## Deprecated `Connection::getWrappedConnection()`, `Connection::connect()` made `@internal`.

The wrapper-level `Connection::getWrappedConnection()` method has been deprecated.
Use `Connection::getNativeConnection()` to access the native connection.

The `Connection::connect()` method has been marked internal. It will be marked `protected` in DBAL 4.0.

## Add `Connection::getNativeConnection()`

Driver and middleware connections need to implement a new method `getNativeConnection()` that gives access to the
native database connection. Not doing so is deprecated.

## Deprecate accessors for the native connection in favor of `getNativeConnection()`

The following methods have been deprecated:

* `Doctrine\DBAL\Driver\PDO\Connection::getWrappedConnection()`
* `Doctrine\DBAL\Driver\PDO\SQLSrv\Connection::getWrappedConnection()`
* `Doctrine\DBAL\Driver\Mysqli\Connection::getWrappedResourceHandle()`

Call `getNativeConnection()` to access the underlying PDO or MySQLi connection.

# Upgrade to 3.2

## Deprecated `SQLLogger` and its implementations.
Expand Down
4 changes: 4 additions & 0 deletions phpstan.neon.dist
Expand Up @@ -127,6 +127,10 @@ parameters:
paths:
- src/Driver/Mysqli/Result.php

# Type check for legacy implementations of the Connection interface
# TODO: remove in 4.0.0
- "~Call to function method_exists\\(\\) with Doctrine\\\\DBAL\\\\Driver\\\\Connection and 'getNativeConnection' will always evaluate to true\\.~"

# These properties are accessed via var_dump()
-
message: '~Property Doctrine\\DBAL\\Tests\\Tools\\TestAsset\\.*::\$.* is never read, only written\.~'
Expand Down
9 changes: 9 additions & 0 deletions psalm.xml.dist
Expand Up @@ -55,6 +55,14 @@
See https://github.com/doctrine/dbal/pull/4317
-->
<file name="tests/Functional/LegacyAPITest.php"/>

<!-- TODO: remove in 4.0.0 -->
<referencedMethod name="Doctrine\DBAL\Driver\PDO\Connection::getWrappedConnection"/>
<!--
TODO: remove in 4.0.0
See https://github.com/doctrine/dbal/pull/4966
-->
<referencedMethod name="Doctrine\DBAL\Connection::getWrappedConnection"/>
</errorLevel>
</DeprecatedMethod>
<DocblockTypeContradiction>
Expand Down Expand Up @@ -187,6 +195,7 @@
or breaking API changes.
-->
<file name="src/Platforms/MySQLPlatform.php"/>
<file name="tests/Functional/Driver/AbstractDriverTest.php"/>
</errorLevel>
</RedundantConditionGivenDocblockType>
<TypeDoesNotContainNull>
Expand Down
40 changes: 40 additions & 0 deletions src/Connection.php
Expand Up @@ -31,15 +31,20 @@
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\SQL\Parser;
use Doctrine\DBAL\Types\Type;
use Doctrine\Deprecations\Deprecation;
use LogicException;
use Throwable;
use Traversable;

use function assert;
use function count;
use function get_class;
use function implode;
use function is_int;
use function is_string;
use function key;
use function method_exists;
use function sprintf;

/**
* A database abstraction-level connection that implements features like events, transaction isolation levels,
Expand Down Expand Up @@ -257,10 +262,18 @@ public function createExpressionBuilder(): ExpressionBuilder
/**
* Establishes the connection with the database.
*
* @internal This method will be made protected in DBAL 4.0.
*
* @throws Exception
*/
public function connect(): void
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/issues/4966',
'Public access to Connection::connect() is deprecated.'
);

if ($this->_conn !== null) {
return;
}
Expand Down Expand Up @@ -1240,17 +1253,44 @@ public function rollbackSavepoint(string $savepoint): void
/**
* Gets the wrapped driver connection.
*
* @deprecated Use {@link getNativeConnection()} to access the native connection.
*
* @throws Exception
*/
public function getWrappedConnection(): DriverConnection
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/issues/4966',
'Connection::getWrappedConnection() is deprecated.'
. ' Use Connection::getNativeConnection() to access the native connection.'
);

$this->connect();

assert($this->_conn !== null);

return $this->_conn;
}

/**
* @return resource|object
*/
public function getNativeConnection()
{
$this->connect();

assert($this->_conn !== null);
if (! method_exists($this->_conn, 'getNativeConnection')) {
throw new LogicException(sprintf(
'The driver connection %s does not support accessing the native connection.',
get_class($this->_conn)
));
}

return $this->_conn->getNativeConnection();
}

/**
* Creates a SchemaManager that can be used to inspect or change the
* database schema through the connection.
Expand Down
2 changes: 2 additions & 0 deletions src/Driver/Connection.php
Expand Up @@ -9,6 +9,8 @@
/**
* Connection interface.
* Driver connections must implement this interface.
*
* @method resource|object getNativeConnection()
*/
interface Connection extends ServerVersionProvider
{
Expand Down
8 changes: 8 additions & 0 deletions src/Driver/IBMDB2/Connection.php
Expand Up @@ -123,4 +123,12 @@ public function rollBack(): void
throw ConnectionError::new($this->connection);
}
}

/**
* @return resource
*/
public function getNativeConnection()
{
return $this->connection;
}
}
87 changes: 87 additions & 0 deletions src/Driver/Middleware/AbstractConnectionMiddleware.php
@@ -0,0 +1,87 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Middleware;

use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement;
use LogicException;

use function get_class;
use function method_exists;
use function sprintf;

abstract class AbstractConnectionMiddleware implements Connection
{
private Connection $wrappedConnection;

public function __construct(Connection $wrappedConnection)
{
$this->wrappedConnection = $wrappedConnection;
}

public function prepare(string $sql): Statement
{
return $this->wrappedConnection->prepare($sql);
}

public function query(string $sql): Result
{
return $this->wrappedConnection->query($sql);
}

public function quote(string $value): string
{
return $this->wrappedConnection->quote($value);
}

public function exec(string $sql): int
{
return $this->wrappedConnection->exec($sql);
}

/**
* {@inheritdoc}
*/
public function lastInsertId()
{
return $this->wrappedConnection->lastInsertId();
}

public function beginTransaction(): void
{
$this->wrappedConnection->beginTransaction();
}

public function commit(): void
{
$this->wrappedConnection->commit();
}

public function rollBack(): void
{
$this->wrappedConnection->rollBack();
}

public function getServerVersion(): string
{
return $this->wrappedConnection->getServerVersion();
}

/**
* @return resource|object
*/
public function getNativeConnection()
{
if (! method_exists($this->wrappedConnection, 'getNativeConnection')) {
throw new LogicException(sprintf(
'The driver connection %s does not support accessing the native connection.',
get_class($this->wrappedConnection)
));
}

return $this->wrappedConnection->getNativeConnection();
}
}
46 changes: 46 additions & 0 deletions src/Driver/Middleware/AbstractDriverMiddleware.php
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Middleware;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\API\ExceptionConverter;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\ServerVersionProvider;

abstract class AbstractDriverMiddleware implements Driver
{
private Driver $wrappedDriver;

public function __construct(Driver $wrappedDriver)
{
$this->wrappedDriver = $wrappedDriver;
}

/**
* {@inheritdoc}
*/
public function connect(array $params): DriverConnection
{
return $this->wrappedDriver->connect($params);
}

public function getDatabasePlatform(ServerVersionProvider $versionProvider): AbstractPlatform
{
return $this->wrappedDriver->getDatabasePlatform($versionProvider);
}

public function getSchemaManager(Connection $conn, AbstractPlatform $platform): AbstractSchemaManager
{
return $this->wrappedDriver->getSchemaManager($conn, $platform);
}

public function getExceptionConverter(): ExceptionConverter
{
return $this->wrappedDriver->getExceptionConverter();
}
}
80 changes: 80 additions & 0 deletions src/Driver/Middleware/AbstractResultMiddleware.php
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Middleware;

use Doctrine\DBAL\Driver\Result;

abstract class AbstractResultMiddleware implements Result
{
private Result $wrappedResult;

public function __construct(Result $result)
{
$this->wrappedResult = $result;
}

/**
* {@inheritdoc}
*/
public function fetchNumeric()
{
return $this->wrappedResult->fetchNumeric();
}

/**
* {@inheritdoc}
*/
public function fetchAssociative()
{
return $this->wrappedResult->fetchAssociative();
}

/**
* {@inheritdoc}
*/
public function fetchOne()
{
return $this->wrappedResult->fetchOne();
}

/**
* {@inheritdoc}
*/
public function fetchAllNumeric(): array
{
return $this->wrappedResult->fetchAllNumeric();
}

/**
* {@inheritdoc}
*/
public function fetchAllAssociative(): array
{
return $this->wrappedResult->fetchAllAssociative();
}

/**
* {@inheritdoc}
*/
public function fetchFirstColumn(): array
{
return $this->wrappedResult->fetchFirstColumn();
}

public function rowCount(): int
{
return $this->wrappedResult->rowCount();
}

public function columnCount(): int
{
return $this->wrappedResult->columnCount();
}

public function free(): void
{
$this->wrappedResult->free();
}
}

0 comments on commit 9a669e6

Please sign in to comment.