From a0e4d4ea47466df711536fbc6f4d194c2ae369f9 Mon Sep 17 00:00:00 2001 From: Daniel Badura Date: Mon, 9 Mar 2026 18:16:55 +0100 Subject: [PATCH 1/3] Use `Pdo\Pgsql::getNotify` if PHP version is `>= 8.4` instead of `PDO::pgsqlGetNotify`. --- src/Store/DoctrineDbalStore.php | 16 ++++++-- src/Store/StreamDoctrineDbalStore.php | 16 ++++++-- tests/Unit/Store/DoctrineDbalStoreTest.php | 33 ++++++++++++++++ .../Store/StreamDoctrineDbalStoreTest.php | 38 +++++++++++++++++++ 4 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/Store/DoctrineDbalStore.php b/src/Store/DoctrineDbalStore.php index 902d6c418..5efcaa07e 100644 --- a/src/Store/DoctrineDbalStore.php +++ b/src/Store/DoctrineDbalStore.php @@ -34,6 +34,7 @@ use Patchlevel\EventSourcing\Store\Criteria\ToIndexCriterion; use Patchlevel\EventSourcing\Store\Header\IndexHeader; use PDO; +use Pdo\Pgsql; use function array_fill; use function array_filter; @@ -49,6 +50,8 @@ use function is_string; use function sprintf; +use const PHP_VERSION_ID; + final class DoctrineDbalStore implements Store, SubscriptionStore, DoctrineSchemaConfigurator { /** @@ -386,10 +389,15 @@ public function wait(int $timeoutMilliseconds): void $this->connection->executeStatement(sprintf('LISTEN "%s"', $this->config['table_name'])); - /** @var PDO $nativeConnection */ - $nativeConnection = $this->connection->getNativeConnection(); - - $nativeConnection->pgsqlGetNotify(PDO::FETCH_ASSOC, $timeoutMilliseconds); + if (PHP_VERSION_ID >= 80400) { + /** @var Pgsql $nativeConnection */ + $nativeConnection = $this->connection->getNativeConnection(); + $nativeConnection->getNotify(PDO::FETCH_ASSOC, $timeoutMilliseconds); + } else { + /** @var PDO $nativeConnection */ + $nativeConnection = $this->connection->getNativeConnection(); + $nativeConnection->pgsqlGetNotify(PDO::FETCH_ASSOC, $timeoutMilliseconds); + } } public function setupSubscription(): void diff --git a/src/Store/StreamDoctrineDbalStore.php b/src/Store/StreamDoctrineDbalStore.php index 83a24a247..204dcd1f8 100644 --- a/src/Store/StreamDoctrineDbalStore.php +++ b/src/Store/StreamDoctrineDbalStore.php @@ -39,6 +39,7 @@ use Patchlevel\EventSourcing\Store\Header\RecordedOnHeader; use Patchlevel\EventSourcing\Store\Header\StreamNameHeader; use PDO; +use Pdo\Pgsql; use Psr\Clock\ClockInterface; use Ramsey\Uuid\Uuid; @@ -58,6 +59,8 @@ use function str_contains; use function str_replace; +use const PHP_VERSION_ID; + final class StreamDoctrineDbalStore implements StreamStore, SubscriptionStore, DoctrineSchemaConfigurator { /** @@ -465,10 +468,15 @@ public function wait(int $timeoutMilliseconds): void $this->connection->executeStatement(sprintf('LISTEN "%s"', $this->config['table_name'])); - /** @var PDO $nativeConnection */ - $nativeConnection = $this->connection->getNativeConnection(); - - $nativeConnection->pgsqlGetNotify(PDO::FETCH_ASSOC, $timeoutMilliseconds); + if (PHP_VERSION_ID >= 80400) { + /** @var Pgsql $nativeConnection */ + $nativeConnection = $this->connection->getNativeConnection(); + $nativeConnection->getNotify(PDO::FETCH_ASSOC, $timeoutMilliseconds); + } else { + /** @var PDO $nativeConnection */ + $nativeConnection = $this->connection->getNativeConnection(); + $nativeConnection->pgsqlGetNotify(PDO::FETCH_ASSOC, $timeoutMilliseconds); + } } public function setupSubscription(): void diff --git a/tests/Unit/Store/DoctrineDbalStoreTest.php b/tests/Unit/Store/DoctrineDbalStoreTest.php index 0d968ff5d..aa887a29c 100644 --- a/tests/Unit/Store/DoctrineDbalStoreTest.php +++ b/tests/Unit/Store/DoctrineDbalStoreTest.php @@ -41,6 +41,7 @@ use Patchlevel\EventSourcing\Tests\Unit\Fixture\ProfileEmailChanged; use Patchlevel\EventSourcing\Tests\Unit\Fixture\ProfileId; use PDO; +use Pdo\Pgsql; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\RequiresPhp; use PHPUnit\Framework\TestCase; @@ -1343,7 +1344,39 @@ public function testSetupSubscriptionNotPostgres(): void $doctrineDbalStore->setupSubscription(); } + #[RequiresPhp('>= 8.4')] public function testWait(): void + { + $nativeConnection = $this->createMock(Pgsql::class); + $nativeConnection + ->expects($this->once()) + ->method('getNotify') + ->with(PDO::FETCH_ASSOC, 100) + ->willReturn([]); + + $connection = $this->createMock(Connection::class); + $connection->expects($this->once())->method('executeStatement')->with('LISTEN "eventstore"') + ->willReturn(1); + $connection->expects($this->once())->method('getNativeConnection') + ->willReturn($nativeConnection); + + $abstractPlatform = $this->createMock(PostgreSQLPlatform::class); + $connection->expects($this->once())->method('getDatabasePlatform')->willReturn($abstractPlatform); + + $eventSerializer = $this->createMock(EventSerializer::class); + $headersSerializer = $this->createMock(HeadersSerializer::class); + + $doctrineDbalStore = new DoctrineDbalStore( + $connection, + $eventSerializer, + $headersSerializer, + ); + + $doctrineDbalStore->wait(100); + } + + #[RequiresPhp('< 8.4')] + public function testWaitDeprecatedFunction(): void { $nativeConnection = $this->getMockBuilder(PDO::class) ->disableOriginalConstructor() diff --git a/tests/Unit/Store/StreamDoctrineDbalStoreTest.php b/tests/Unit/Store/StreamDoctrineDbalStoreTest.php index c78414c2c..35d50426c 100644 --- a/tests/Unit/Store/StreamDoctrineDbalStoreTest.php +++ b/tests/Unit/Store/StreamDoctrineDbalStoreTest.php @@ -44,7 +44,9 @@ use Patchlevel\EventSourcing\Tests\Unit\Fixture\ProfileEmailChanged; use Patchlevel\EventSourcing\Tests\Unit\Fixture\ProfileId; use PDO; +use Pdo\Pgsql; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\RequiresPhp; use PHPUnit\Framework\TestCase; use Psr\Clock\ClockInterface; use RuntimeException; @@ -1367,7 +1369,43 @@ public function testSetupSubscriptionNotPostgres(): void $doctrineDbalStore->setupSubscription(); } + #[RequiresPhp('>= 8.4')] public function testWait(): void + { + $nativeConnection = $this->createMock(Pgsql::class); + $nativeConnection + ->expects($this->once()) + ->method('getNotify') + ->with(PDO::FETCH_ASSOC, 100) + ->willReturn([]); + + $connection = $this->createMock(Connection::class); + $connection + ->expects($this->once()) + ->method('executeStatement') + ->with('LISTEN "event_store"') + ->willReturn(1); + $connection + ->expects($this->once()) + ->method('getNativeConnection') + ->willReturn($nativeConnection); + + $abstractPlatform = $this->createMock(PostgreSQLPlatform::class); + $connection->method('getDatabasePlatform')->willReturn($abstractPlatform); + + $eventSerializer = $this->createMock(EventSerializer::class); + $headersSerializer = $this->createMock(HeadersSerializer::class); + + $doctrineDbalStore = new StreamDoctrineDbalStore( + $connection, + $eventSerializer, + $headersSerializer, + ); + $doctrineDbalStore->wait(100); + } + + #[RequiresPhp('< 8.4')] + public function testWaitDeprecatedFunction(): void { $nativeConnection = $this->getMockBuilder(PDO::class) ->disableOriginalConstructor() From 333635c21da08aa84ddbe19d3d1198760d2f2925 Mon Sep 17 00:00:00 2001 From: Daniel Badura Date: Mon, 9 Mar 2026 18:29:03 +0100 Subject: [PATCH 2/3] Add `pdo_pgsql` to the list of extensions for unit tests --- .github/workflows/unit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index 0776f96c2..2daa95966 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -46,7 +46,7 @@ jobs: coverage: "pcov" php-version: "${{ matrix.php-version }}" ini-values: memory_limit=-1 - extensions: pdo_sqlite + extensions: pdo_sqlite, pdo_pgsql - uses: ramsey/composer-install@3.1.1 with: From 6e9f6295a85178a960e8f2e0d46cfda393333e5b Mon Sep 17 00:00:00 2001 From: Daniel Badura Date: Mon, 9 Mar 2026 18:41:13 +0100 Subject: [PATCH 3/3] Adjust also other workflows extensions. --- .github/workflows/coding-standard.yml | 1 - .github/workflows/deptrac.yml | 1 - .github/workflows/mutation-tests-diff.yml | 2 +- .github/workflows/mutation-tests.yml | 2 +- .github/workflows/phpstan.yml | 1 - 5 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/coding-standard.yml b/.github/workflows/coding-standard.yml index bdb62784f..bfb0ea133 100644 --- a/.github/workflows/coding-standard.yml +++ b/.github/workflows/coding-standard.yml @@ -34,7 +34,6 @@ jobs: coverage: none php-version: "${{ matrix.php-version }}" ini-values: memory_limit=-1, opcache.enable_cli=1 - extensions: pdo_sqlite - uses: ramsey/composer-install@3.1.1 with: diff --git a/.github/workflows/deptrac.yml b/.github/workflows/deptrac.yml index ea0419496..339aee32a 100644 --- a/.github/workflows/deptrac.yml +++ b/.github/workflows/deptrac.yml @@ -34,7 +34,6 @@ jobs: coverage: "pcov" php-version: "${{ matrix.php-version }}" ini-values: memory_limit=-1 - extensions: pdo_sqlite - uses: ramsey/composer-install@3.1.1 with: diff --git a/.github/workflows/mutation-tests-diff.yml b/.github/workflows/mutation-tests-diff.yml index d01b57fee..db05d5316 100644 --- a/.github/workflows/mutation-tests-diff.yml +++ b/.github/workflows/mutation-tests-diff.yml @@ -32,7 +32,7 @@ jobs: coverage: "pcov" php-version: "${{ matrix.php-version }}" ini-values: memory_limit=-1 - extensions: pdo_sqlite + extensions: pdo_sqlite, pdo_pgsql - uses: ramsey/composer-install@3.1.1 with: diff --git a/.github/workflows/mutation-tests.yml b/.github/workflows/mutation-tests.yml index 379d868f7..f63c2fe32 100644 --- a/.github/workflows/mutation-tests.yml +++ b/.github/workflows/mutation-tests.yml @@ -34,7 +34,7 @@ jobs: coverage: "pcov" php-version: "${{ matrix.php-version }}" ini-values: memory_limit=-1 - extensions: pdo_sqlite + extensions: pdo_sqlite, pdo_pgsql - uses: ramsey/composer-install@3.1.1 with: diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index a1fb6c325..b5b5a6afe 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -34,7 +34,6 @@ jobs: coverage: none php-version: "${{ matrix.php-version }}" ini-values: memory_limit=-1, opcache.enable_cli=1 - extensions: pdo_sqlite - uses: ramsey/composer-install@3.1.1 with: