Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doctrine/dbal ^4.0.0 #84

Merged
merged 14 commits into from
Mar 8, 2024
1 change: 1 addition & 0 deletions .env.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PHP_VERSION=8.1
17 changes: 3 additions & 14 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ jobs:
strategy:
matrix:
php-version:
- "7.4"
- "8.0"
- "8.1"
- "8.2"
- "8.3"
Expand All @@ -32,22 +30,13 @@ jobs:
custom-entrypoint:
- --entrypoint sh mysql:8 -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password"
include:
- php-version: "7.4"
mysql-version: "8.0"
custom-entrypoint: ~
job: Tests
- php-version: "7.4"
mysql-version: "5.7"
custom-entrypoint: ~
job: Tests
- php-version: "8.2"
mysql-version: "5.7"
job: Tests
- php-version: "8.1"
- php-version: "8.3"
mysql-version: "8.0"
job: Infection
- dependencies: "lowest"
php-version: "7.4"
php-version: "8.1"
mysql-version: "5.7"
name: Lowest deps

Expand Down Expand Up @@ -120,7 +109,7 @@ jobs:
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1"
php-version: ${{ matrix.php-version }}

- name: Install dependencies
uses: ramsey/composer-install@v3
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/docker-compose.override.yml
/phpunit.xml
/.*.cache
.env
9 changes: 5 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"doctrine/dbal": "^3.6.0"
"php": "^8.1",
"doctrine/dbal": "^4.0.0"
},
"require-dev": {
"ext-pdo": "*",
"facile-it/facile-coding-standard": "^0.5.2",
"fig/log-test": "^1.0",
"infection/infection": "^0.26.6",
Expand Down Expand Up @@ -58,7 +59,7 @@
"minimum-stability": "stable",
"scripts": {
"test": "phpunit",
"phpcs": "php-cs-fixer fix --level=psr2 -v --diff --dry-run src/",
"phpcs-fix": "php-cs-fixer fix --level=psr2 -v --diff src/"
"phpcs": "php-cs-fixer fix --dry-run --diff",
"phpcs-fix": "php-cs-fixer fix --diff"
}
}
7 changes: 5 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ services:

php:
<<: *php-props
image: facile.example.com/php:${PHP_VERSION}
build:
context: ./docker
args:
PHP_VERSION: ${PHP_VERSION}
depends_on:
- mysql57
- mysql80
environment:
PHP_IDE_CONFIG: serverName=MySQLComeBack
MYSQL_HOST: mysql57
MYSQL_HOST: mysql80
MYSQL_DRIVER: pdo_mysql
3 changes: 2 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG PHP_VERSION=7.4
ARG PHP_VERSION=8.1
FROM php:${PHP_VERSION}-cli-alpine

RUN docker-php-ext-install -j$(getconf _NPROCESSORS_ONLN) \
Expand All @@ -7,6 +7,7 @@ RUN docker-php-ext-install -j$(getconf _NPROCESSORS_ONLN) \

RUN set -ex \
&& apk add --no-cache --virtual build-dependencies \
linux-headers \
autoconf \
Jean85 marked this conversation as resolved.
Show resolved Hide resolved
make \
g++ \
Expand Down
44 changes: 24 additions & 20 deletions src/ConnectionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

namespace Facile\DoctrineMySQLComeBack\Doctrine\DBAL;

use Doctrine\Common\EventManager;
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Statement as DBALStatement;
use Doctrine\DBAL\Types\Type;
Expand All @@ -16,6 +18,9 @@

/**
* @psalm-require-extends \Doctrine\DBAL\Connection
*
* @psalm-type WrapperParameterType = string|Type|ParameterType|ArrayParameterType
* @psalm-type WrapperParameterTypeArray = array<int<0, max>, WrapperParameterType>|array<string, WrapperParameterType>
*/
trait ConnectionTrait
{
Expand All @@ -32,8 +37,7 @@
public function __construct(
array $params,
Driver $driver,
?Configuration $config = null,
?EventManager $eventManager = null
?Configuration $config = null
) {
if (isset($params['driverOptions']['x_reconnect_attempts'])) {
$this->maxReconnectAttempts = $this->validateAttemptsOption($params['driverOptions']['x_reconnect_attempts']);
Expand All @@ -46,7 +50,7 @@
* @psalm-suppress InternalMethod
* @psalm-suppress MixedArgumentTypeCoercion
*/
parent::__construct($params, $driver, $config, $eventManager);
parent::__construct($params, $driver, $config);
}

/**
Expand Down Expand Up @@ -82,7 +86,7 @@
try {
attempt:
$result = $callable();
} catch (\Exception $e) {
} catch (\Throwable $e) {
if (! $this->canTryAgain($e, $sql)) {
throw $e;
}
Expand Down Expand Up @@ -110,7 +114,7 @@
/**
* @internal
*/
public function resetAttemptCount(): void

Check warning on line 117 in src/ConnectionTrait.php

View workflow job for this annotation

GitHub Actions / Infection (PHP 8.3 / MySQL 8.0)

Escaped Mutant for Mutator "PublicVisibility": --- Original +++ New @@ @@ /** * @internal */ - public function resetAttemptCount() : void + protected function resetAttemptCount() : void { $this->currentAttempts = 0; }
{
$this->currentAttempts = 0;
}
Expand All @@ -118,15 +122,15 @@
/**
* @param string $connectionName
*/
public function connect($connectionName = null)
public function connect(?string $connectionName = null): DriverConnection
{
$this->hasBeenClosedWithAnOpenTransaction = false;

/** @psalm-suppress InternalMethod */
return parent::connect($connectionName);
}

public function close()
public function close(): void
{
if ($this->getTransactionNestingLevel() > 0) {
$this->hasBeenClosedWithAnOpenTransaction = true;
Expand All @@ -147,37 +151,37 @@
/**
* @param string $sql
* @param list<mixed>|array<string, mixed> $params
* @param array<int, int|string|Type|null>|array<string, int|string|Type|null> $types
*
* @psalm-param WrapperParameterTypeArray $types
*/
public function executeQuery(string $sql, array $params = [], $types = [], ?QueryCacheProfile $qcp = null): Result
{
return $this->doWithRetry(function () use ($sql, $params, $types, $qcp): Result {
return @parent::executeQuery($sql, $params, $types, $qcp);
return parent::executeQuery($sql, $params, $types, $qcp);
}, $sql);
}

/**
* @param string $sql
* @param list<mixed>|array<string, mixed> $params
* @param array<int, int|string|Type|null>|array<string, int|string|Type|null> $types
* @param list<mixed>|array<string, mixed> $params
*
* @psalm-param WrapperParameterTypeArray $types
*
* @return int|numeric-string
*
* @psalm-suppress MoreSpecificImplementedParamType
*/
public function executeStatement($sql, array $params = [], array $types = [])
public function executeStatement(string $sql, array $params = [], array $types = []): int|string
{
return $this->doWithRetry(function () use ($sql, $params, $types) {
return @parent::executeStatement($sql, $params, $types);
return parent::executeStatement($sql, $params, $types);
}, $sql);
}

public function beginTransaction()
public function beginTransaction(): void
{
if ($this->hasBeenClosedWithAnOpenTransaction || 0 !== $this->getTransactionNestingLevel()) {
return @parent::beginTransaction();
}

return $this->doWithRetry(function (): bool {
return parent::beginTransaction();
$this->doWithRetry(function (): void {
parent::beginTransaction();
});
}

Expand Down
5 changes: 2 additions & 3 deletions src/Connections/PrimaryReadReplicaConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Facile\DoctrineMySQLComeBack\Doctrine\DBAL\Connections;

use Doctrine\Common\EventManager;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Driver;
use Facile\DoctrineMySQLComeBack\Doctrine\DBAL\ConnectionTrait;
Expand All @@ -13,13 +12,13 @@ class PrimaryReadReplicaConnection extends \Doctrine\DBAL\Connections\PrimaryRea
__construct as __traitConstruct;
}

public function __construct(array $params, Driver $driver, ?Configuration $config = null, ?EventManager $eventManager = null)
public function __construct(array $params, Driver $driver, ?Configuration $config = null)
{
if (isset($params['primary']['driverOptions']['x_reconnect_attempts'])) {
$params['driverOptions']['x_reconnect_attempts'] = $this->validateAttemptsOption($params['primary']['driverOptions']['x_reconnect_attempts']);
unset($params['primary']['driverOptions']['x_reconnect_attempts']);
}

self::__traitConstruct($params, $driver, $config, $eventManager);
self::__traitConstruct($params, $driver, $config);
}
}
53 changes: 20 additions & 33 deletions src/Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Facile\DoctrineMySQLComeBack\Doctrine\DBAL;

use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Result;
use Exception;
Expand Down Expand Up @@ -44,49 +45,38 @@
*/
private function recreateStatement(): void
{
/** @psalm-suppress DeprecatedMethod */
$this->stmt = $this->conn->getWrappedConnection()->prepare($this->sql);
$ref = new \ReflectionMethod($this->conn, 'connect');
Jean85 marked this conversation as resolved.
Show resolved Hide resolved

/** @var DriverConnection $wrappedConnection */
$wrappedConnection = $ref->invoke($this->conn);

$this->stmt = $wrappedConnection->prepare($this->sql);

/** @var mixed $value */
foreach ($this->boundValues as $param => $value) {
parent::bindValue($param, $value, $this->types[$param] ?? ParameterType::STRING);
$type = ParameterType::STRING;
if (isset($this->types[$param])) {
$type = $this->types[$param];
}

parent::bindValue($param, $value, $type);
}
}

public function bindValue($param, $value, $type = ParameterType::STRING)
public function bindValue($param, $value, $type = ParameterType::STRING): void
{
$this->boundValues[$param] = $value;

return parent::bindValue($param, $value, $type);
}

/**
* @inheritDoc
*/
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
Jean85 marked this conversation as resolved.
Show resolved Hide resolved
{
$this->boundValues[$param] =&$variable;

/** @psalm-suppress DeprecatedMethod */
return parent::bindParam($param, $variable, $type, $length);
parent::bindValue($param, $value, $type);
}

public function executeQuery(array $params = []): Result
public function executeQuery(): Result
{
if ($params === []) {
return $this->executeWithRetry([parent::class, 'executeQuery']);
}

return $this->executeWithRetry([parent::class, 'executeQuery'], $params);
return $this->executeWithRetry(fn () => parent::executeQuery());
}

public function executeStatement(array $params = []): int
public function executeStatement(): int|string
{
if ($params === []) {
return $this->executeWithRetry([parent::class, 'executeStatement']);
}

return $this->executeWithRetry([parent::class, 'executeStatement'], $params);
return $this->executeWithRetry(fn () => parent::executeStatement());
}

/**
Expand All @@ -100,18 +90,15 @@
*/
private function executeWithRetry(callable $callable, ...$params)
{
$parentCall = \Closure::fromCallable($callable);
$parentCall->bindTo($this, parent::class);

try {
attempt:
$result = $parentCall(...$params);
$result = $callable(...$params);
Jean85 marked this conversation as resolved.
Show resolved Hide resolved
} catch (Exception $e) {
if (! $this->retriableConnection->canTryAgain($e, $this->sql)) {
throw $e;
}

$this->retriableConnection->increaseAttemptCount();

Check warning on line 101 in src/Statement.php

View workflow job for this annotation

GitHub Actions / Infection (PHP 8.3 / MySQL 8.0)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ if (!$this->retriableConnection->canTryAgain($e, $this->sql)) { throw $e; } - $this->retriableConnection->increaseAttemptCount(); + $this->recreateStatement(); goto attempt; }
$this->recreateStatement();

goto attempt;
Expand Down
Loading