简体   繁体   English

Doctrine DBAL、diff 命令和枚举类型

[英]Doctrine DBAL, diff command and enum type

I am working with symfony 5.1, doctrine-bundle 2.1.2 and doctrine-migrations-bundle 2.2.我正在使用 symfony 5.1、doctrine-bundle 2.1.2 和 doctrine-migrations-bundle 2.2。 I am NOT working with ORM and define my own Schemas.我没有使用 ORM 并定义我自己的架构。 To add Enum types, I am using the following code:要添加枚举类型,我使用以下代码:

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;
}

Each enum then extends this abstract class to set the values.每个枚举然后扩展这个抽象 class 来设置值。

Creating is no issue.创建不是问题。 When I run the migration diff command, I am getting the following error message:当我运行 migration diff 命令时,我收到以下错误消息:

Unknown database type enum requested, Doctrine\DBAL\Platforms\MySQL57Platform may not support it.请求的未知数据库类型枚举,Doctrine\DBAL\Platforms\MySQL57Platform 可能不支持它。

Any ideas how I can create a diff that also includes any changes to the enum itself?有什么想法可以创建一个差异,其中还包括对枚举本身的任何更改吗?

I solved this by creating my own diff which firstly adds the 'enum' type if not already there using:我通过创建自己的 diff 解决了这个问题,如果还没有使用,首先添加 'enum' 类型:

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

After that I try to read all availabble tables, and catch any exception for a type that is not defined, define it as a string and then try again:之后,我尝试读取所有可用表,并捕获未定义类型的任何异常,将其定义为字符串,然后重试:

$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);

This will return the current db schema.这将返回当前的数据库模式。 From which a diff can be created with the new schema.可以使用新模式从中创建差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM