diff --git a/src/Sql/Ddl/AlterTableDecorator.php b/src/Sql/Ddl/AlterTableDecorator.php index 2dcb1db..0dd89b6 100644 --- a/src/Sql/Ddl/AlterTableDecorator.php +++ b/src/Sql/Ddl/AlterTableDecorator.php @@ -27,6 +27,8 @@ final class AlterTableDecorator extends AlterTable implements PlatformDecoratorI /** @var array{ * unsigned: int, * zerofill: int, + * charset: int, + * collate: int, * identity: int, * serial: int, * autoincrement: int, @@ -40,14 +42,16 @@ final class AlterTableDecorator extends AlterTable implements PlatformDecoratorI protected array $columnOptionSortOrder = [ 'unsigned' => 0, 'zerofill' => 1, - 'identity' => 2, - 'serial' => 2, - 'autoincrement' => 2, - 'comment' => 3, - 'columnformat' => 4, - 'format' => 4, - 'storage' => 5, - 'after' => 6, + 'charset' => 2, + 'collate' => 3, + 'identity' => 4, + 'serial' => 4, + 'autoincrement' => 4, + 'comment' => 5, + 'columnformat' => 6, + 'format' => 6, + 'storage' => 7, + 'after' => 8, ]; public function setSubject( @@ -115,6 +119,14 @@ protected function processAddColumns(?PlatformInterface $adapterPlatform = null) $insert = ' ZEROFILL'; $j = 0; break; + case 'charset': + $insert = ' CHARACTER SET ' . $coValue; + $j = 0; + break; + case 'collate': + $insert = ' COLLATE ' . $coValue; + $j = 0; + break; case 'identity': case 'serial': case 'autoincrement': @@ -179,6 +191,14 @@ protected function processChangeColumns(?PlatformInterface $adapterPlatform = nu $insert = ' ZEROFILL'; $j = 0; break; + case 'charset': + $insert = ' CHARACTER SET ' . $coValue; + $j = 0; + break; + case 'collate': + $insert = ' COLLATE ' . $coValue; + $j = 0; + break; case 'identity': case 'serial': case 'autoincrement': diff --git a/src/Sql/Ddl/CreateTableDecorator.php b/src/Sql/Ddl/CreateTableDecorator.php index cfcb7f5..fd1f575 100644 --- a/src/Sql/Ddl/CreateTableDecorator.php +++ b/src/Sql/Ddl/CreateTableDecorator.php @@ -28,13 +28,15 @@ final class CreateTableDecorator extends CreateTable implements PlatformDecorato protected $columnOptionSortOrder = [ 'unsigned' => 0, 'zerofill' => 1, - 'identity' => 2, - 'serial' => 2, - 'autoincrement' => 2, - 'comment' => 3, - 'columnformat' => 4, - 'format' => 4, - 'storage' => 5, + 'charset' => 2, + 'collate' => 3, + 'identity' => 4, + 'serial' => 4, + 'autoincrement' => 4, + 'comment' => 5, + 'columnformat' => 6, + 'format' => 6, + 'storage' => 7, ]; public function setSubject( @@ -113,6 +115,14 @@ protected function processColumns(?PlatformInterface $platform = null): ?array $insert = ' ZEROFILL'; $j = 0; break; + case 'charset': + $insert = ' CHARACTER SET ' . $coValue; + $j = 0; + break; + case 'collate': + $insert = ' COLLATE ' . $coValue; + $j = 0; + break; case 'identity': case 'serial': case 'autoincrement': diff --git a/test/unit/Sql/Ddl/AlterTableDecoratorTest.php b/test/unit/Sql/Ddl/AlterTableDecoratorTest.php new file mode 100644 index 0000000..d9f6809 --- /dev/null +++ b/test/unit/Sql/Ddl/AlterTableDecoratorTest.php @@ -0,0 +1,163 @@ +createMock(Connection::class), + $this->createMock(Statement::class), + $this->createMock(Result::class), + ); + $this->platform = new AdapterPlatform($driver); + } + + private function buildSql(AlterTable $table): string + { + $decorator = new AlterTableDecorator(); + $decorator->setSubject($table); + + return $decorator->getSqlString($this->platform); + } + + public function testAddColumnCharset(): void + { + $alter = new AlterTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('charset', 'utf8mb3'); + $alter->addColumn($col); + + $sql = $this->buildSql($alter); + + self::assertStringContainsString('CHARACTER SET utf8mb3', $sql); + } + + public function testAddColumnCollate(): void + { + $alter = new AlterTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('collate', 'utf8mb3_unicode_ci'); + $alter->addColumn($col); + + $sql = $this->buildSql($alter); + + self::assertStringContainsString('COLLATE utf8mb3_unicode_ci', $sql); + } + + public function testAddColumnCharsetAndCollate(): void + { + $alter = new AlterTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('charset', 'utf8mb3'); + $col->setOption('collate', 'utf8mb3_unicode_ci'); + $alter->addColumn($col); + + $sql = $this->buildSql($alter); + + self::assertStringContainsString('CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci', $sql); + } + + public function testAddColumnCharsetBeforeNotNull(): void + { + $alter = new AlterTable('test'); + $col = new Column\Varchar('name', 255); + $col->setNullable(false); + $col->setOption('charset', 'utf8mb3'); + $col->setOption('collate', 'utf8mb3_unicode_ci'); + $alter->addColumn($col); + + $sql = $this->buildSql($alter); + + self::assertMatchesRegularExpression( + '/CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL/', + $sql, + ); + } + + public function testChangeColumnCharset(): void + { + $alter = new AlterTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('charset', 'utf8mb3'); + $alter->changeColumn('name', $col); + + $sql = $this->buildSql($alter); + + self::assertStringContainsString('CHARACTER SET utf8mb3', $sql); + } + + public function testChangeColumnCollate(): void + { + $alter = new AlterTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('collate', 'utf8mb3_unicode_ci'); + $alter->changeColumn('name', $col); + + $sql = $this->buildSql($alter); + + self::assertStringContainsString('COLLATE utf8mb3_unicode_ci', $sql); + } + + public function testChangeColumnCharsetAndCollate(): void + { + $alter = new AlterTable('test'); + $col = new Column\Varchar('name', 255); + $col->setNullable(false); + $col->setOption('charset', 'utf8mb3'); + $col->setOption('collate', 'utf8mb3_unicode_ci'); + $alter->changeColumn('name', $col); + + $sql = $this->buildSql($alter); + + self::assertMatchesRegularExpression( + '/CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL/', + $sql, + ); + } + + public function testAddColumnAfter(): void + { + $alter = new AlterTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('after', 'id'); + $alter->addColumn($col); + + $sql = $this->buildSql($alter); + + self::assertStringContainsString('AFTER `id`', $sql); + } + + public function testAddColumnUnsigned(): void + { + $alter = new AlterTable('test'); + $col = new Column\Integer('id'); + $col->setOption('unsigned', true); + $col->setOption('auto_increment', true); + $alter->addColumn($col); + + $sql = $this->buildSql($alter); + + self::assertStringContainsString('UNSIGNED', $sql); + self::assertStringContainsString('AUTO_INCREMENT', $sql); + } +} diff --git a/test/unit/Sql/Ddl/CreateTableDecoratorTest.php b/test/unit/Sql/Ddl/CreateTableDecoratorTest.php new file mode 100644 index 0000000..1aa25da --- /dev/null +++ b/test/unit/Sql/Ddl/CreateTableDecoratorTest.php @@ -0,0 +1,159 @@ +createMock(Connection::class), + $this->createMock(Statement::class), + $this->createMock(Result::class), + ); + $this->platform = new AdapterPlatform($driver); + } + + private function buildSql(CreateTable $table): string + { + $decorator = new CreateTableDecorator(); + $decorator->setSubject($table); + + return $decorator->getSqlString($this->platform); + } + + public function testColumnCharset(): void + { + $table = new CreateTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('charset', 'utf8mb3'); + $table->addColumn($col); + + $sql = $this->buildSql($table); + + self::assertStringContainsString('CHARACTER SET utf8mb3', $sql); + } + + public function testColumnCollate(): void + { + $table = new CreateTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('collate', 'utf8mb3_unicode_ci'); + $table->addColumn($col); + + $sql = $this->buildSql($table); + + self::assertStringContainsString('COLLATE utf8mb3_unicode_ci', $sql); + } + + public function testColumnCharsetAndCollate(): void + { + $table = new CreateTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('charset', 'utf8mb3'); + $col->setOption('collate', 'utf8mb3_unicode_ci'); + $table->addColumn($col); + + $sql = $this->buildSql($table); + + self::assertStringContainsString('CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci', $sql); + } + + public function testCharsetAppearsBeforeNotNull(): void + { + $table = new CreateTable('test'); + $col = new Column\Varchar('name', 255); + $col->setNullable(false); + $col->setOption('charset', 'utf8mb3'); + $col->setOption('collate', 'utf8mb3_unicode_ci'); + $table->addColumn($col); + + $sql = $this->buildSql($table); + + self::assertMatchesRegularExpression( + '/CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL/', + $sql, + ); + } + + public function testCharsetAppearsAfterUnsigned(): void + { + $table = new CreateTable('test'); + $col = new Column\Integer('id'); + $col->setOption('unsigned', true); + $col->setOption('charset', 'utf8mb3'); + $table->addColumn($col); + + $sql = $this->buildSql($table); + + self::assertMatchesRegularExpression('/UNSIGNED CHARACTER SET utf8mb3/', $sql); + } + + public function testUnsignedOption(): void + { + $table = new CreateTable('test'); + $col = new Column\Integer('id'); + $col->setOption('unsigned', true); + $col->setOption('auto_increment', true); + $table->addColumn($col); + + $sql = $this->buildSql($table); + + self::assertStringContainsString('UNSIGNED', $sql); + self::assertStringContainsString('AUTO_INCREMENT', $sql); + } + + public function testCommentOption(): void + { + $table = new CreateTable('test'); + $col = new Column\Varchar('name', 255); + $col->setOption('comment', 'A test column'); + $table->addColumn($col); + + $sql = $this->buildSql($table); + + self::assertStringContainsString('COMMENT', $sql); + } + + public function testFullColumnDefinition(): void + { + $table = new CreateTable('test'); + + $id = new Column\Integer('id'); + $id->setOption('unsigned', true); + $id->setOption('auto_increment', true); + $table->addColumn($id); + + $name = new Column\Varchar('agency_id', 255); + $name->setNullable(false); + $name->setOption('charset', 'utf8mb3'); + $name->setOption('collate', 'utf8mb3_unicode_ci'); + $table->addColumn($name); + + $table->addConstraint(new Constraint\PrimaryKey(['id'])); + + $sql = $this->buildSql($table); + + self::assertStringContainsString('UNSIGNED', $sql); + self::assertStringContainsString('AUTO_INCREMENT', $sql); + self::assertStringContainsString('CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL', $sql); + } +}