1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Tests\Functional\Types;
use Doctrine\DBAL\Exception\InvalidColumnType\ColumnValuesRequired;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Types\EnumType;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\RequiresPhpunit;
final class EnumTypeTest extends FunctionalTestCase
{
protected function setUp(): void
{
$this->dropTableIfExists('my_enum_table');
}
#[RequiresPhpunit('< 11.5.18')]
public function testIntrospectEnum(): void
{
if (! $this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform) {
self::markTestSkipped('This test requires MySQL or MariaDB.');
}
$this->connection->executeStatement(<<< 'SQL'
CREATE TABLE my_enum_table (
id BIGINT NOT NULL PRIMARY KEY,
suit ENUM('hearts', 'diamonds', 'clubs', 'spades') NOT NULL DEFAULT 'hearts'
);
SQL);
$schemaManager = $this->connection->createSchemaManager();
$table = $schemaManager->introspectTable('my_enum_table');
self::assertCount(2, $table->getColumns());
self::assertTrue($table->hasColumn('suit'));
self::assertInstanceOf(EnumType::class, $table->getColumn('suit')->getType());
self::assertSame(['hearts', 'diamonds', 'clubs', 'spades'], $table->getColumn('suit')->getValues());
self::assertSame('hearts', $table->getColumn('suit')->getDefault());
}
#[RequiresPhpunit('< 11.5.18')]
public function testDeployEnum(): void
{
$schemaManager = $this->connection->createSchemaManager();
$schema = new Schema(schemaConfig: $schemaManager->createSchemaConfig());
$table = $schema->createTable('my_enum_table');
$table->addColumn('id', Types::BIGINT, ['notnull' => true]);
$table->addColumn('suit', Types::ENUM, [
'values' => ['hearts', 'diamonds', 'clubs', 'spades'],
'notnull' => true,
'default' => 'hearts',
]);
$table->setPrimaryKey(['id']);
$schemaManager->createSchemaObjects($schema);
$introspectedTable = $schemaManager->introspectTable('my_enum_table');
self::assertTrue($schemaManager->createComparator()->compareTables($table, $introspectedTable)->isEmpty());
$this->connection->insert('my_enum_table', ['id' => 1, 'suit' => 'hearts'], ['suit' => Types::ENUM]);
$this->connection->insert(
'my_enum_table',
['id' => 2, 'suit' => 'diamonds'],
['suit' => Type::getType(Types::ENUM)],
);
self::assertEquals(
[[1, 'hearts'], [2, 'diamonds']],
$this->connection->fetchAllNumeric('SELECT id, suit FROM my_enum_table ORDER BY id ASC'),
);
}
#[RequiresPhpunit('< 11.5.18')]
public function testDeployEmptyEnum(): void
{
$schemaManager = $this->connection->createSchemaManager();
$schema = new Schema(schemaConfig: $schemaManager->createSchemaConfig());
$table = $schema->createTable('my_enum_table');
$table->addColumn('id', Types::BIGINT, ['notnull' => true]);
$table->addColumn('suit', Types::ENUM);
$table->setPrimaryKey(['id']);
$this->expectException(ColumnValuesRequired::class);
$schemaManager->createSchemaObjects($schema);
}
/** @param list<string> $expectedValues */
#[DataProvider('provideEnumDefinitions')]
#[RequiresPhpunit('< 11.5.18')]
public function testIntrospectEnumValues(string $definition, array $expectedValues): void
{
if (! $this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform) {
self::markTestSkipped('This test requires MySQL or MariaDB.');
}
$this->connection->executeStatement(<<< SQL
CREATE TABLE my_enum_table (
id BIGINT NOT NULL PRIMARY KEY,
my_enum $definition DEFAULT NULL
);
SQL);
$schemaManager = $this->connection->createSchemaManager();
$table = $schemaManager->introspectTable('my_enum_table');
self::assertInstanceOf(EnumType::class, $table->getColumn('my_enum')->getType());
self::assertSame($expectedValues, $table->getColumn('my_enum')->getValues());
self::assertNull($table->getColumn('my_enum')->getDefault());
}
/** @return iterable<string, array{string, list<string>}> */
public static function provideEnumDefinitions(): iterable
{
yield 'simple' => ['ENUM("a", "b", "c")', ['a', 'b', 'c']];
yield 'empty first' => ['ENUM("", "a", "b", "c")', ['', 'a', 'b', 'c']];
yield 'empty in the middle' => ['ENUM("a", "", "b", "c")', ['a', '', 'b', 'c']];
yield 'empty last' => ['ENUM("a", "b", "c", "")', ['a', 'b', 'c', '']];
yield 'with spaces' => ['ENUM("a b", "c d", "e f")', ['a b', 'c d', 'e f']];
yield 'with quotes' => ['ENUM("a\'b", "c\'d", "e\'f")', ['a\'b', 'c\'d', 'e\'f']];
yield 'with commas' => ['ENUM("a,b", "c,d", "e,f")', ['a,b', 'c,d', 'e,f']];
yield 'with parentheses' => ['ENUM("(a)", "(b)", "(c)")', ['(a)', '(b)', '(c)']];
yield 'with quotes and commas' => ['ENUM("a\'b", "c\'d", "e\'f")', ['a\'b', 'c\'d', 'e\'f']];
yield 'with quotes and parentheses' => ['ENUM("(a)", "(b)", "(c)")', ['(a)', '(b)', '(c)']];
yield 'with commas and parentheses' => ['ENUM("(a,b)", "(c,d)", "(e,f)")', ['(a,b)', '(c,d)', '(e,f)']];
yield 'with quotes, commas and parentheses'
=> ['ENUM("(a\'b)", "(c\'d)", "(e\'f)")', ['(a\'b)', '(c\'d)', '(e\'f)']];
}
}
|