Skip to content

Commit

Permalink
feat(database): add explicit ConnectionClosed exception
Browse files Browse the repository at this point in the history
  • Loading branch information
blackshadev committed Jan 24, 2025
1 parent 423487a commit 4fca50d
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Tempest/Database/src/ConnectionInitializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Tempest\Container\Container;
use Tempest\Container\Initializer;
use Tempest\Container\Singleton;
use Tempest\Core\AppConfig;

final class ConnectionInitializer implements Initializer
{
Expand All @@ -16,7 +17,7 @@ final class ConnectionInitializer implements Initializer
public function initialize(Container $container): Connection
{
// Reuse same connection instance in unit tests
if (self::$instance !== null) {
if (self::$instance !== null && $container->get(AppConfig::class)->environment->isTesting()) {
return self::$instance;
}

Expand Down
13 changes: 13 additions & 0 deletions src/Tempest/Database/src/Exceptions/ConnectionClosed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Tempest\Database\Exceptions;

final class ConnectionClosed extends DatabaseException
{
public function __construct()
{
parent::__construct('Connection is closed');
}
}
21 changes: 21 additions & 0 deletions src/Tempest/Database/src/PDOConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PDO;
use PDOStatement;
use Tempest\Database\Connections\DatabaseConnection;
use Tempest\Database\Exceptions\ConnectionClosed;

final class PDOConnection implements Connection
{
Expand All @@ -18,26 +19,46 @@ public function __construct(private readonly DatabaseConnection $connection)

public function beginTransaction(): bool
{
if ($this->pdo === null) {
throw new ConnectionClosed();
}

return $this->pdo->beginTransaction();
}

public function commit(): bool
{
if ($this->pdo === null) {
throw new ConnectionClosed();
}

return $this->pdo->commit();
}

public function rollback(): bool
{
if ($this->pdo === null) {
throw new ConnectionClosed();
}

return $this->pdo->rollBack();
}

public function lastInsertId(): false|string
{
if ($this->pdo === null) {
throw new ConnectionClosed();
}

return $this->pdo->lastInsertId();
}

public function prepare(string $sql): false|PDOStatement
{
if ($this->pdo === null) {
throw new ConnectionClosed();
}

return $this->pdo->prepare($sql);
}

Expand Down
85 changes: 85 additions & 0 deletions src/Tempest/Database/tests/PDOConnectionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

namespace Tempest\Database\Tests;

use Generator;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Tempest\Database\Connections\SQLiteConnection;
use Tempest\Database\Exceptions\ConnectionClosed;
use Tempest\Database\PDOConnection;

/**
* @internal
*/
final class PDOConnectionTest extends TestCase
{
private const string PATH = ':memory:';

#[DataProvider('provideQueryMethods')]
public function test_connection_must_be_open(string $method, array $params): void
{
$this->expectException(ConnectionClosed::class);

$connection = new PDOConnection(new SQLiteConnection(self::PATH));

$connection->$method(...$params);
}

#[DataProvider('provideQueryMethods')]
public function test_close_must_be_open(string $method, array $params): void
{
$this->expectException(ConnectionClosed::class);

$connection = new PDOConnection(new SQLiteConnection(self::PATH));
$connection->connect();
$connection->close();

$connection->$method(...$params);
}

public static function provideQueryMethods(): Generator
{
yield 'lastInsertId' => ['lastInsertId', []];
yield 'commit' => ['commit', []];
yield 'rollback' => ['rollback', []];
yield 'beginTransaction' => ['beginTransaction', []];
yield 'prepare' => ['prepare', ['select 1']];
}

public function test_commit(): void
{
$connection = new PDOConnection(new SQLiteConnection(self::PATH));
$connection->connect();

$this->assertTrue($connection->beginTransaction());
$this->assertTrue($connection->commit());
}

public function test_rollback(): void
{
$connection = new PDOConnection(new SQLiteConnection(self::PATH));
$connection->connect();

$this->assertTrue($connection->beginTransaction());
$this->assertTrue($connection->rollback());
}

public function test_last_insert_id(): void
{
$connection = new PDOConnection(new SQLiteConnection(self::PATH));
$connection->connect();

$this->assertSame('0', $connection->lastInsertId());
}

public function test_prepare(): void
{
$connection = new PDOConnection(new SQLiteConnection(self::PATH));
$connection->connect();

$this->assertNotFalse($connection->prepare('select 1'));
}
}

0 comments on commit 4fca50d

Please sign in to comment.