原则DBAL,diff命令和枚举类型

问题描述

我正在使用symfony 5.1,tctrine-bundle-bundle 2.2和doctrine-migrations-bundle 2.2。我不使用ORM并定义自己的模式。要添加Enum类型,我使用以下代码

abstract class EnumType extends Type
{
    protected string $name;

    public function getsqlDeclaration(array $fieldDeclaration,AbstractPlatform $platform)
    {
        $values = $this->getValues();
        $maxLength = max(array_map('strlen',$values));
        $columnName = $fieldDeclaration['name'];

        $implodedValues = implode(',',array_map(function($value) {return "'$value'";},$values));

        if ($platform instanceof MysqLPlatform) {
            return "ENUM($implodedValues)";
        }

        if (
            $platform instanceof sqlServer2012Platform
            || $platform instanceof Postgresql94Platform
        ) {
            return "VARCHAR($maxLength) CHECK ({$columnName} IN ($implodedValues))";
        }

        if ($platform instanceof sqlitePlatform) {
            return "TEXT CHECK ({$columnName} IN ($implodedValues))";
        }

        throw DBALException::invalidplatformType($platform);
    }

    public function convertToPHPValue($value,AbstractPlatform $platform)
    {
        return $value;
    }

    public function convertToDatabaseValue($value,AbstractPlatform $platform)
    {
        if (!in_array($value,$this->getValues())) {
            throw new \invalidargumentexception("Invalid '" . $this->name . "' value: " . (string)$value);
        }
        return $value;
    }

    public function getName()
    {
        return $this->name;
    }

    public function requiressqlCommentHint(AbstractPlatform $platform)
    {
        return true;
    }

    abstract function getValues(): array;
}

每个枚举然后扩展此抽象类以设置值。

创建没有问题。当我运行migration diff命令时,出现以下错误消息:

请求了未知的数据库类型枚举,Doctrine \ DBAL \ Platforms \ MysqL57Platform可能不支持

有什么想法可以创建一个差异,其中还包括对枚举本身的任何更改?

解决方法

我通过创建自己的 diff 解决了这个问题,它首先使用以下方法添加“枚举”类型:

if ($connection->getDatabasePlatform() instanceof MySqlPlatform) {
    if (!Type::hasType('enum')) {
        Type::addType('enum',StringType::class);
    }
    $connection->getDatabasePlatform()->registerDoctrineTypeMapping('enum',Types::STRING);
}

之后,我尝试读取所有可用表,并捕获未定义类型的任何异常,将其定义为字符串,然后重试:

$schemaManager = $this->connection->getSchemaManager();
do {
    try {
        return new Schema($schemaManager->listTables(),[],$schemaManager->createSchemaConfig());
    } catch (Exception $exception) {
        $hasErrors = true;
        $message = $exception->getMessage();
        $parts = explode('"',$message);
        // convert any removed custom type to string
        Type::addType($parts[1],StringType::class);
    }
} while ($hasErrors);

这将返回当前的数据库架构。从中可以使用新架构创建差异。