Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public static function beginTransaction() : void
self::$transactionActive = true;

foreach (self::$clients as $client) {
if (!$client->isConnected()) {
continue;
}

if ($client->getTransactionNestingLevel() === 0) {
$client->beginTransaction();
}
Expand Down Expand Up @@ -55,7 +59,7 @@ public static function connect(ConnectionParameters $params, ?ValueConverters $c

$key = \sha1(\sprintf('%s:%d:%s:%s', $params->host(), $params->port(), $params->database(), $params->user() ?? ''));

if (!\array_key_exists($key, self::$clients)) {
if (!\array_key_exists($key, self::$clients) || !self::$clients[$key]->isConnected()) {
self::$clients[$key] = PgSqlClient::connect($params, $converters);

if (self::$transactionActive) {
Expand Down Expand Up @@ -93,6 +97,10 @@ public static function rollBack() : void
self::$transactionActive = false;

foreach (self::$clients as $client) {
if (!$client->isConnected()) {
continue;
}

while ($client->getTransactionNestingLevel() > 0) {
$client->rollBack();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Flow\Bridge\PHPUnit\PostgreSQL\Tests\Context;

use Flow\Bridge\PHPUnit\PostgreSQL\StaticClient;
use Flow\PostgreSql\Client\Client;

final class StaticClientContext
{
public static function injectClient(string $key, Client $client) : void
{
self::injectClients([$key => $client]);
}

/**
* @param array<string, Client> $clients
*/
public static function injectClients(array $clients) : void
{
$reflection = new \ReflectionClass(StaticClient::class);
$property = $reflection->getProperty('clients');
$property->setValue(null, $clients);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

declare(strict_types=1);

namespace Flow\Bridge\PHPUnit\PostgreSQL\Tests\Double;

use Flow\PostgreSql\AST\Transformers\ExplainConfig;
use Flow\PostgreSql\Client\{Client, ConnectionParameters, Cursor, Notification, RowMapper};
use Flow\PostgreSql\Client\Types\ValueConverters;
use Flow\PostgreSql\Explain\Plan\Plan;
use Flow\PostgreSql\QueryBuilder\Sql;

final class FakeClient implements Client
{
public bool $connected = true;

public int $transactionLevel = 0;

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

public function close() : void
{
$this->connected = false;
}

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

public function converters() : ValueConverters
{
throw new \RuntimeException('Not implemented');
}

public function cursor(Sql|string $sql, array $parameters = []) : Cursor
{
throw new \RuntimeException('Not implemented');
}

public function execute(Sql|string $sql, array $parameters = []) : int
{
throw new \RuntimeException('Not implemented');
}

public function explain(Sql|string $sql, array $parameters = [], ?ExplainConfig $config = null) : Plan
{
throw new \RuntimeException('Not implemented');
}

public function fetch(Sql|string $sql, array $parameters = []) : ?array
{
throw new \RuntimeException('Not implemented');
}

public function fetchAll(Sql|string $sql, array $parameters = []) : array
{
throw new \RuntimeException('Not implemented');
}

public function fetchAllInto(RowMapper $mapper, Sql|string $sql, array $parameters = []) : array
{
throw new \RuntimeException('Not implemented');
}

public function fetchInto(RowMapper $mapper, Sql|string $sql, array $parameters = []) : mixed
{
throw new \RuntimeException('Not implemented');
}

public function fetchOne(Sql|string $sql, array $parameters = []) : array
{
throw new \RuntimeException('Not implemented');
}

public function fetchOneInto(RowMapper $mapper, Sql|string $sql, array $parameters = []) : mixed
{
throw new \RuntimeException('Not implemented');
}

public function fetchScalar(Sql|string $sql, array $parameters = []) : mixed
{
throw new \RuntimeException('Not implemented');
}

public function fetchScalarBool(Sql|string $sql, array $parameters = []) : bool
{
throw new \RuntimeException('Not implemented');
}

public function fetchScalarFloat(Sql|string $sql, array $parameters = []) : float
{
throw new \RuntimeException('Not implemented');
}

public function fetchScalarInt(Sql|string $sql, array $parameters = []) : int
{
throw new \RuntimeException('Not implemented');
}

public function fetchScalarString(Sql|string $sql, array $parameters = []) : string
{
throw new \RuntimeException('Not implemented');
}

public function getTransactionNestingLevel() : int
{
return $this->transactionLevel;
}

public function isAutoCommit() : bool
{
throw new \RuntimeException('Not implemented');
}

public function isConnected() : bool
{
return $this->connected;
}

public function lastInsertId(string $sequenceName) : int|string
{
throw new \RuntimeException('Not implemented');
}

public function listen(string $channel) : void
{
throw new \RuntimeException('Not implemented');
}

public function parameters() : ConnectionParameters
{
throw new \RuntimeException('Not implemented');
}

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

public function setAutoCommit(bool $autoCommit) : void
{
throw new \RuntimeException('Not implemented');
}

public function transaction(callable $callback) : mixed
{
throw new \RuntimeException('Not implemented');
}

public function unlisten(string $channel) : void
{
throw new \RuntimeException('Not implemented');
}

public function wait(int $milliseconds) : ?Notification
{
throw new \RuntimeException('Not implemented');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace Flow\Bridge\PHPUnit\PostgreSQL\Tests\Unit;

use Flow\Bridge\PHPUnit\PostgreSQL\{SkipTransactionRollback, StaticClient};
use Flow\Bridge\PHPUnit\PostgreSQL\Tests\Context\StaticClientContext;
use Flow\Bridge\PHPUnit\PostgreSQL\Tests\Double\FakeClient;
use PHPUnit\Framework\TestCase;

#[SkipTransactionRollback]
Expand All @@ -20,6 +22,29 @@ protected function tearDown() : void
StaticClient::reset();
}

public function test_begin_transaction_skips_closed_clients() : void
{
$fakeClient = new FakeClient();
$fakeClient->connected = false;

StaticClientContext::injectClient('test-key', $fakeClient);

StaticClient::beginTransaction();

self::assertSame(0, $fakeClient->transactionLevel);
}

public function test_begin_transaction_works_on_connected_clients() : void
{
$fakeClient = new FakeClient();

StaticClientContext::injectClient('test-key', $fakeClient);

StaticClient::beginTransaction();

self::assertSame(1, $fakeClient->transactionLevel);
}

public function test_disable_sets_disabled_state() : void
{
StaticClient::enable();
Expand Down Expand Up @@ -49,4 +74,28 @@ public function test_reset_clears_all_state() : void

self::assertFalse(StaticClient::isEnabled());
}

public function test_rollback_skips_closed_clients() : void
{
$fakeClient = new FakeClient();
$fakeClient->connected = false;

StaticClientContext::injectClient('test-key', $fakeClient);

StaticClient::rollBack();

self::assertSame(0, $fakeClient->transactionLevel);
}

public function test_rollback_works_on_connected_clients() : void
{
$fakeClient = new FakeClient();
$fakeClient->transactionLevel = 1;

StaticClientContext::injectClient('test-key', $fakeClient);

StaticClient::rollBack();

self::assertSame(0, $fakeClient->transactionLevel);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,11 @@ public function test_build_registers_as_filesystem_factory_attribute_for_autocon

$childDefinition = new ChildDefinition('parent');

if (\method_exists($container, 'getAttributeAutoconfigurators')) {
$autoconfigured = $container->getAttributeAutoconfigurators();
self::assertArrayHasKey(AsFilesystemFactory::class, $autoconfigured);
$autoconfigured = $container->getAttributeAutoconfigurators();
self::assertArrayHasKey(AsFilesystemFactory::class, $autoconfigured);

foreach ($autoconfigured[AsFilesystemFactory::class] as $configurator) {
$configurator($childDefinition, new AsFilesystemFactory(protocol: 'my-fs'), new \ReflectionClass(\stdClass::class));
}
} else {
$autoconfigured = $container->getAutoconfiguredAttributes();
self::assertArrayHasKey(AsFilesystemFactory::class, $autoconfigured);
$autoconfigured[AsFilesystemFactory::class]($childDefinition, new AsFilesystemFactory(protocol: 'my-fs'), new \ReflectionClass(\stdClass::class));
foreach ($autoconfigured[AsFilesystemFactory::class] as $configurator) {
$configurator($childDefinition, new AsFilesystemFactory(protocol: 'my-fs'), new \ReflectionClass(\stdClass::class));
}

$tags = $childDefinition->getTag('flow_filesystem.factory');
Expand Down
Loading
Loading