Skip to content

Commit

Permalink
Fix driver cloning (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
butschster committed Jan 10, 2022
1 parent d10a425 commit 0e38747
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 8 deletions.
16 changes: 11 additions & 5 deletions src/Driver/Driver.php
Expand Up @@ -145,6 +145,12 @@ public function __call(string $name, array $arguments): mixed
};
}

public function __clone()
{
$this->schemaHandler = $this->schemaHandler->withDriver($this);
$this->queryBuilder = $this->queryBuilder->withDriver($this);
}

/**
* Get driver source database or file name.
*
Expand Down Expand Up @@ -273,6 +279,11 @@ public function lastInsertID(string $sequence = null)
return $result;
}

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

/**
* Start SQL transaction with specified isolation level (not all DBMS support it). Nested
* transactions are processed using savepoints.
Expand Down Expand Up @@ -636,9 +647,4 @@ protected function defineLoggerContext(float $queryStart, ?PDOStatement $stateme

return $context;
}

public function getTransactionLevel(): int
{
return $this->transactionLevel;
}
}
72 changes: 69 additions & 3 deletions tests/Database/Unit/Driver/AbstractDriverTest.php
Expand Up @@ -6,11 +6,17 @@

use Cycle\Database\Config\SQLiteDriverConfig;
use Cycle\Database\Driver\Driver;
use Cycle\Database\Driver\DriverInterface;
use Cycle\Database\Driver\HandlerInterface;
use Cycle\Database\Query\BuilderInterface;
use Mockery as m;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;

class AbstractDriverTest extends TestCase
{
use m\Adapter\Phpunit\MockeryPHPUnitIntegration;

private Driver $driver;

protected function setUp(): void
Expand All @@ -22,11 +28,71 @@ protected function setUp(): void

public function testLoggerShouldBeSet()
{
$logger = $this->createMock(LoggerInterface::class);
$logger->expects($this->once())
->method('debug')->with('Insert ID: 0', []);
$logger = m::mock(LoggerInterface::class);
$logger->shouldReceive('debug')
->once()->with('Insert ID: 0');

$this->driver->setLogger($logger);
$this->driver->lastInsertID();
}

public function testGetNotSetNameShouldThrowAnException()
{
$this->expectException(\RuntimeException::class);
$this->expectErrorMessage('Driver name is not defined.');
$this->driver->getName();
}

public function testWithName()
{
$handler = m::mock(HandlerInterface::class);
$builder = m::mock(BuilderInterface::class);

$handler->shouldReceive('withDriver')->once();
$builder->shouldReceive('withDriver')->once();

$driver = TestDriver::createWith(
new SQLiteDriverConfig(),
$handler,
$builder
);

$driver->getSchemaHandler()->shouldReceive('withDriver')->once();
$driver->getQueryBuilder()->shouldReceive('withDriver')->once();

$newDriver = $driver->withName('test');
$this->assertSame('test', $newDriver->getName());

$this->checkImmutability($driver, $newDriver);
}

public function testClone()
{
$handler = m::mock(HandlerInterface::class);
$builder = m::mock(BuilderInterface::class);

$handler->shouldReceive('withDriver')->once();
$builder->shouldReceive('withDriver')->once();

$driver = TestDriver::createWith(
new SQLiteDriverConfig(),
$handler,
$builder
);

$driver->getSchemaHandler()->shouldReceive('withDriver')->once();
$driver->getQueryBuilder()->shouldReceive('withDriver')->once();

$newDriver = clone $driver;

$this->checkImmutability($driver, $newDriver);
}

private function checkImmutability(DriverInterface $driver, DriverInterface $newDriver): void
{
// Immutability
$this->assertNotSame($driver, $newDriver);
$this->assertNotSame($driver->getSchemaHandler(), $newDriver->getSchemaHandler());
$this->assertNotSame($driver->getQueryBuilder(), $newDriver->getQueryBuilder());
}
}
15 changes: 15 additions & 0 deletions tests/Database/Unit/Driver/TestDriver.php
Expand Up @@ -6,9 +6,11 @@

use Cycle\Database\Config\DriverConfig;
use Cycle\Database\Driver\Driver;
use Cycle\Database\Driver\HandlerInterface;
use Cycle\Database\Driver\SQLite\SQLiteCompiler;
use Cycle\Database\Driver\SQLite\SQLiteHandler;
use Cycle\Database\Exception\StatementException;
use Cycle\Database\Query\BuilderInterface;
use Cycle\Database\Query\QueryBuilder;

class TestDriver extends Driver
Expand All @@ -32,4 +34,17 @@ public static function create(DriverConfig $config): Driver
QueryBuilder::defaultBuilder()
);
}

public static function createWith(
DriverConfig $config,
HandlerInterface $handler,
BuilderInterface $builder
): Driver {
return new self(
$config,
$handler,
new SQLiteCompiler('""'),
$builder
);
}
}

0 comments on commit 0e38747

Please sign in to comment.