Dbal: Allow extending MariaDb1027Platform class

Created on 2 May 2018  路  6Comments  路  Source: doctrine/dbal

MariaDb1027Platform is marked as final. I suggest removing the final modifier.

The point is to be able to override the behavior of the Platform like for example changing the truncate table query.
I agree that I can just write my own Platform based on MySqlPlatform, which is non-final, but then there is a hard-coded reference in MySqlSchemaManager that checks if the platform is instanceof MariaDb1027Platform which is needed to fix the problem with quoted nulls in column definitions. If I write my own platform, the 'instanceof' comparison will be always false.

All 6 comments

We can't guarantee BC on subclassing, so no, the class will not be made open. Please C&P it instead, if you want to customise it.

+1

@Ocramius Any idea how to work around this with C&P method? Do I have to hack into SchemaManager and who knows what else? :/

https://github.com/doctrine/dbal/blob/01c22b7d1f58d5ae40a0e362bbef3fe685087b52/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php#L178

@Ocramius Any idea how to work around this with C&P method? Do I have to hack into SchemaManager and who knows what else? :/

https://github.com/doctrine/dbal/blob/01c22b7d1f58d5ae40a0e362bbef3fe685087b52/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php#L178

there is no normal way how to do it ...
so I did it "my way"

1. composer .json - add calling this scipt at first line
"app:update-maria-db-platform-condition": "symfony-cmd",

2. create SF command UpdateMariaDbPlatformConditionCommand
````
class UpdateMariaDbPlatformConditionCommand extends Command
{
protected function configure()
{
$this
->setName('app:update-maria-db-platform-condition')
->setDescription("Update hardcoded condition for MariaDbPlatform");
}

protected function execute(InputInterface $input, OutputInterface $output)
{
    $reflector = new \ReflectionClass(MySqlSchemaManager::class);
    $schemaDiffPath = $reflector->getFileName();

    $content = file_get_contents($schemaDiffPath);

    if (strpos($content, 'CustomMariaDbPlatform') === false) {

        $old = '$this->_platform instanceof MariaDb1027Platform';
        $new = '$this->_platform instanceof MariaDb1027Platform || $this->_platform instanceof \\'.CustomMariaDbPlatform::class;
        $newContent = str_replace($old, $new, $content);


        $old = 'getMariaDb1027ColumnDefault(MariaDb1027Platform ';
        $new = 'getMariaDb1027ColumnDefault(';
        $newContent = str_replace($old, $new, $newContent);

        file_put_contents($schemaDiffPath, $newContent);
    }

    return true;
}

}
````

3. create CustomMariaDbPlatform and do whatever you need
````
class CustomMariaDbPlatform extends MySqlPlatform
{
public function getJsonTypeDeclarationSQL(array $field) : string
{
return 'LONGTEXT';
}

protected function getReservedKeywordsClass() : string
{
    return MariaDb102Keywords::class;
}

protected function initializeDoctrineTypeMappings() : void
{
    parent::initializeDoctrineTypeMappings();

    $this->doctrineTypeMapping['json'] = Type::JSON;
}

public function getTruncateTableSQL($tableName, $cascade = false)
{
    return sprintf('SET foreign_key_checks = 0;TRUNCATE %s;SET foreign_key_checks = 1;', $tableName);
}

````

If I were reading more carefully, I would notice exactly this is mentioned by OP. I am sorry for bothering with something already answered.

@poolerMF Thank you, interesting solution. I don't really like touching the vendor folder, so I would probably stick to "overriding" the class using composer. Every solution seems to be ugly in some way, it's needed for dev purposes only, so shortest path sounds reasonable. Anyway I have returned to 10.1 and will solve this later.


I just can't get rid of a feeling there is something wrong if you are offered writing your own Platform, but simply can't do it for MariaDB without breaking everything else.

Wouldn't make very specific marker interface more sense (instead of depending on final class)? If I get this correctly it's still considered to be a bug on MariaDB side? I am not good at naming interfaces, but something in the sense of MariaDb1027DefaultTypeBugAware. Can't really see how could that make BC problems in the future.

Was this page helpful?
0 / 5 - 0 ratings