Skip to content
Open
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
2 changes: 0 additions & 2 deletions .github/workflows/fix-cs-php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ github.head_ref }}

- name: Run PHP-CS-Fixer
uses: docker://ghcr.io/php-cs-fixer/php-cs-fixer:3.62.0-php8.3
Expand Down
6 changes: 3 additions & 3 deletions src/Webfactory/Slimdump/Doctrine/DummyType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ class DummyType extends Type
{
public const NAME = 'dummy_type';

public function convertToPHPValue($value, AbstractPlatform $platform)
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed
{
throw new LogicException('This Doctrine type assumes that the types won\'t be used to convert any data – it\'s just there to allow the rest of DBAL\'s functionality to work without throwing errors');
}

public function getSQLDeclaration(array $column, AbstractPlatform $platform)
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
throw new LogicException('This Doctrine type assumes that the types won\'t be used to convert any data – it\'s just there to allow the rest of DBAL\'s functionality to work without throwing errors');
}

public function getName()
public function getName(): string
{
return self::NAME;
}
Expand Down
38 changes: 38 additions & 0 deletions src/Webfactory/Slimdump/Doctrine/DummyTypeRegistration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Webfactory\Slimdump\Doctrine;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Types\Type;

/**
* The SchemaManager throws when it encounters a native DB column type Doctrine
* does not map. Registers a placeholder DummyType for every native database
* column type that Doctrine does not map by default (enum, set, geometry, …).
*/
final class DummyTypeRegistration
{
public static function register(Connection $connection): void
{
$platform = $connection->getDatabasePlatform();

if (!Type::hasType(DummyType::NAME)) {
Type::addType(DummyType::NAME, DummyType::class);
}

$schema = $connection->getDatabase();
if (null === $schema) {
return;
}

$sql = 'SELECT DISTINCT DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ?';

foreach ($connection->fetchAllAssociative($sql, [$schema]) as $row) {
$dbType = strtolower((string) $row['DATA_TYPE']);

if ('' !== $dbType && !$platform->hasDoctrineTypeMappingFor($dbType)) {
$platform->registerDoctrineTypeMapping($dbType, DummyType::NAME);
}
}
}
}

This file was deleted.

9 changes: 2 additions & 7 deletions src/Webfactory/Slimdump/SlimdumpCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use Webfactory\Slimdump\Database\CsvOutputFormatDriver;
use Webfactory\Slimdump\Database\MysqlOutputFormatDriver;
use Webfactory\Slimdump\Database\OutputFormatDriverInterface;
use Webfactory\Slimdump\Doctrine\DummyTypeRegistrationEventSubscriber;
use Webfactory\Slimdump\Doctrine\DummyTypeRegistration;

final class SlimdumpCommand extends Command
{
Expand Down Expand Up @@ -71,12 +71,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$connection = $this->createConnection($input);

// In DBAL 3, the SchemaManager parses DC2Type column comments and throws when encountering
// unknown types. We register a DummyType for any unknown type to work around this.
// In DBAL 4, the DC2Type comment mechanism was removed entirely, so this is no longer needed.
if (class_exists(\Doctrine\DBAL\Events::class)) {
$connection->getEventManager()->addEventSubscriber(new DummyTypeRegistrationEventSubscriber($connection->createSchemaManager()));
}
DummyTypeRegistration::register($connection);

$this->setMaxExecutionTimeUnlimited($connection, $progressOutput);

Expand Down
48 changes: 48 additions & 0 deletions test/Webfactory/Slimdump/Doctrine/DummyTypeRegistrationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Webfactory\Slimdump\Doctrine;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class DummyTypeRegistrationTest extends TestCase
{
#[Test]
public function registersDummyTypeForUnknownDbTypesAndSkipsKnownOnes(): void
{
$platform = $this->createMock(AbstractPlatform::class);
$platform->method('hasDoctrineTypeMappingFor')->willReturnMap([
['int', true],
['enum', false],
]);
$platform->expects($this->once())
->method('registerDoctrineTypeMapping')
->with('enum', DummyType::NAME);

$connection = $this->createMock(Connection::class);
$connection->method('getDatabasePlatform')->willReturn($platform);
$connection->method('getDatabase')->willReturn('my_schema');
$connection->method('fetchAllAssociative')->willReturn([
['DATA_TYPE' => 'int'],
['DATA_TYPE' => 'enum'],
]);

DummyTypeRegistration::register($connection);
}

#[Test]
public function returnsEarlyWhenSchemaNameIsNull(): void
{
$platform = $this->createMock(AbstractPlatform::class);
$platform->expects($this->never())->method('registerDoctrineTypeMapping');

$connection = $this->createMock(Connection::class);
$connection->method('getDatabasePlatform')->willReturn($platform);
$connection->method('getDatabase')->willReturn(null);
$connection->expects($this->never())->method('fetchAllAssociative');

DummyTypeRegistration::register($connection);
}
}
Loading