enumeum / doctrine-enums
Doctrine 扩展,用于管理 PostgreSQL 中的枚举类型
Requires
- php: ^8.1
- doctrine/annotations: ^1.13
- doctrine/common: ^2.13 || ^3.0
- doctrine/event-manager: ^1.0
Requires (Dev)
- doctrine/dbal: ^2.13 || ^3.2
- doctrine/orm: ^2.14
- ergebnis/composer-normalize: ^2.28
- friendsofphp/php-cs-fixer: ^3.0
- nesbot/carbon: ^2.55
- phpstan/phpstan: ^1.1
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^8.5 || ^9.5
- symfony/cache: ^4.4 || ^5.3 || ^6.0
- symfony/var-dumper: ^6.2
Conflicts
- doctrine/dbal: <2.13.1 || ^3.0 <3.2
- doctrine/orm: <2.10.2
- sebastian/comparator: <2.0
README
本包包含 Doctrine ORM 和 DBAL 的扩展,提供 PostgreSQL 数据库中枚举类型的管理功能。是的,数据库中的枚举类型是坏做法,你应该避免使用它们。但有时数据库管理需要枚举类型作为对某些字段的简单约束。本包提供了一种透明的方法,将 PHP 枚举作为数据库类型添加,并在 Doctrine 实体中与适当的字段一起使用。
要求
最低 PHP 版本是 8.1。
安装
composer require enumeum/doctrine-enums
使用方法
PHP 枚举属性
- #[Enumeum\DoctrineEnum\Attribute\EnumType(name: 'type_name')] 这个属性表示这个枚举是数据库类型。默认情况下,它将在数据库中创建具有其自己的 case 的类型。
枚举设置
<?php namespace App\Enums; use Enumeum\DoctrineEnum\Attribute\EnumType; #[EnumType(name: 'status_type')] enum StatusType: string { case STARTED = 'started'; case PROCESSING = 'processing'; case FINISHED = 'finished'; }
实体设置
请注意,实体的配置与通常的配置没有区别。Doctrine 支持 "enumType" 属性,并透明地转换它。
<?php namespace App\Entities; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use App\Enum\StatusType; /** * @ORM\Entity * @ORM\Table(name="entity") */ #[ORM\Entity] #[ORM\Table(name: 'entity')] class Entity { /** * @ORM\Id * @ORM\Column(type="integer") */ #[ORM\Id] #[ORM\Column(type: Types::INTEGER)] private int $id; /** * @ORM\Column(type="string", enumType=StatusType::class, options={"comment":"Comment"}) */ #[ORM\Column(type: Types::STRING, enumType: StatusType::class, options: ['comment' => 'Comment'])] private StatusType $status; public function __construct( int $id, StatusType $status, ) { $this->id = $id; $this->status = $status; } public function getId(): int { return $this->id; } public function getStatus(): StatusType { return $this->status; } }
DBAL 配置
<?php namespace App; use Enumeum\DoctrineEnum\Definition\DefinitionRegistryLoader; use Enums\BaseStatusType; $enumClassNames = [ BaseStatusType::class, // ... ]; $enumDirPaths = [ [ 'path' => __DIR__.'/../Enums', 'namespace' => 'App\Enums', ] // ... ]; $loader = DefinitionRegistryLoader::create(new EnumClassLocator([]), $enumClassNames, $enumDirPaths);
可以通过适当的方法添加一个或多个额外的类型或目录
$loader->loadType(BaseStatusType::class); $loader->loadTypes([BaseStatusType::class]); $loader->loadDir([ 'path' => __DIR__.'/../Enums', 'namespace' : 'App\Enums', ]); $loader->loadDirs([ [ 'path' => __DIR__.'/../Enums', 'namespace' : 'App\Enums', ], ]);
填充加载器为 Enumeum\DoctrineEnum\Definition\DefinitionRegistry 实例提供枚举定义的集合。每次调用都会创建一个新的 Registry 实例。
$registry = $loader->getRegistry();
DBAL 模式操作需要加载新的类型,因此使用特殊的 Enumeum\DoctrineEnum\Type\TypeRegistryLoader。
TypeRegistryLoader::load($registry->getDefinitions());
下一步是创建 Enumeum\DoctrineEnum\EnumTool 并使用它来生成数据库枚举持久化或直接更新数据库的 SQL 查询。
<?php namespace App; use Enumeum\DoctrineEnum\EnumTool; $tool = EnumTool::create($registry, $doctrineDbalConnection); // Updates database with configured enums $tool->createSchema(); // ... OR generates SQL queries for update $sql = $tool->getCreateSchemaSql();
ORM 配置
ORM 部分只需要将 Enumeum\DoctrineEnum\EventSubscriber\PostGenerateSchemaSubscriber 添加到 Doctrine 的 EventManager。
<?php namespace App; use Doctrine\Common\EventManager; use Doctrine\ORM\EntityManager; use Enumeum\DoctrineEnum\EnumUsage\TableColumnRegistry; use Enumeum\DoctrineEnum\EventSubscriber\PostGenerateSchemaSubscriber; $evm = new EventManager(); $em = EntityManager::create($params, $config, $evm); $evm->addEventSubscriber(new PostGenerateSchemaSubscriber( $registry, new TableColumnRegistry($em->getConnection()), ));
使用方法
如果你已经更改了枚举值、结构、添加或删除类型,那么请使用 Enumeum\DoctrineEnum\EnumTool。它将生成同步配置枚举或直接更新数据库的 SQL 查询。之后,如果需要更改不仅包括枚举,还包括模式,那么请执行模式差异/更新。
运行测试
要设置和运行测试,请按照以下步骤操作
- 安装 Docker 并确保你有
docker-compose
和make
(可选) - 从项目根目录运行
make start
以在守护进程模式下启动容器(或使用docker-compose up -d --build --remove-orphans --force-recreate
) - 通过
make console
进入容器(或使用docker-compose exec php bash
) - 检查你是否在根目录
/var/www
,如果不是,则使用以下命令导航:cd /var/www
- 通过
composer install
安装 Composer 依赖项 - 从容器外部使用
make test
运行测试(或使用容器内部的bin/phpunit -c tests/
)
可能的未来功能
删除枚举值而不重新创建的命令。 https://postgrespro.ru/list/thread-id/2388881