Skip to content

Commit 8421ff7

Browse files
authored
Merge pull request #48 from simon-mundy/ddl-bug
Resolves issue #47
2 parents 328bd24 + 7e89982 commit 8421ff7

4 files changed

Lines changed: 367 additions & 15 deletions

File tree

src/Sql/Ddl/AlterTableDecorator.php

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ final class AlterTableDecorator extends AlterTable implements PlatformDecoratorI
2727
/** @var array{
2828
* unsigned: int,
2929
* zerofill: int,
30+
* charset: int,
31+
* collate: int,
3032
* identity: int,
3133
* serial: int,
3234
* autoincrement: int,
@@ -40,14 +42,16 @@ final class AlterTableDecorator extends AlterTable implements PlatformDecoratorI
4042
protected array $columnOptionSortOrder = [
4143
'unsigned' => 0,
4244
'zerofill' => 1,
43-
'identity' => 2,
44-
'serial' => 2,
45-
'autoincrement' => 2,
46-
'comment' => 3,
47-
'columnformat' => 4,
48-
'format' => 4,
49-
'storage' => 5,
50-
'after' => 6,
45+
'charset' => 2,
46+
'collate' => 3,
47+
'identity' => 4,
48+
'serial' => 4,
49+
'autoincrement' => 4,
50+
'comment' => 5,
51+
'columnformat' => 6,
52+
'format' => 6,
53+
'storage' => 7,
54+
'after' => 8,
5155
];
5256

5357
public function setSubject(
@@ -115,6 +119,14 @@ protected function processAddColumns(?PlatformInterface $adapterPlatform = null)
115119
$insert = ' ZEROFILL';
116120
$j = 0;
117121
break;
122+
case 'charset':
123+
$insert = ' CHARACTER SET ' . $coValue;
124+
$j = 0;
125+
break;
126+
case 'collate':
127+
$insert = ' COLLATE ' . $coValue;
128+
$j = 0;
129+
break;
118130
case 'identity':
119131
case 'serial':
120132
case 'autoincrement':
@@ -179,6 +191,14 @@ protected function processChangeColumns(?PlatformInterface $adapterPlatform = nu
179191
$insert = ' ZEROFILL';
180192
$j = 0;
181193
break;
194+
case 'charset':
195+
$insert = ' CHARACTER SET ' . $coValue;
196+
$j = 0;
197+
break;
198+
case 'collate':
199+
$insert = ' COLLATE ' . $coValue;
200+
$j = 0;
201+
break;
182202
case 'identity':
183203
case 'serial':
184204
case 'autoincrement':

src/Sql/Ddl/CreateTableDecorator.php

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ final class CreateTableDecorator extends CreateTable implements PlatformDecorato
2828
protected $columnOptionSortOrder = [
2929
'unsigned' => 0,
3030
'zerofill' => 1,
31-
'identity' => 2,
32-
'serial' => 2,
33-
'autoincrement' => 2,
34-
'comment' => 3,
35-
'columnformat' => 4,
36-
'format' => 4,
37-
'storage' => 5,
31+
'charset' => 2,
32+
'collate' => 3,
33+
'identity' => 4,
34+
'serial' => 4,
35+
'autoincrement' => 4,
36+
'comment' => 5,
37+
'columnformat' => 6,
38+
'format' => 6,
39+
'storage' => 7,
3840
];
3941

4042
public function setSubject(
@@ -113,6 +115,14 @@ protected function processColumns(?PlatformInterface $platform = null): ?array
113115
$insert = ' ZEROFILL';
114116
$j = 0;
115117
break;
118+
case 'charset':
119+
$insert = ' CHARACTER SET ' . $coValue;
120+
$j = 0;
121+
break;
122+
case 'collate':
123+
$insert = ' COLLATE ' . $coValue;
124+
$j = 0;
125+
break;
116126
case 'identity':
117127
case 'serial':
118128
case 'autoincrement':
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpDbTest\Mysql\Sql\Ddl;
6+
7+
use PhpDb\Adapter\Driver\Pdo\Result;
8+
use PhpDb\Adapter\Driver\Pdo\Statement;
9+
use PhpDb\Mysql\AdapterPlatform;
10+
use PhpDb\Mysql\Pdo\Connection;
11+
use PhpDb\Mysql\Pdo\Driver;
12+
use PhpDb\Mysql\Sql\Ddl\AlterTableDecorator;
13+
use PhpDb\Sql\Ddl\AlterTable;
14+
use PhpDb\Sql\Ddl\Column;
15+
use PHPUnit\Framework\Attributes\CoversMethod;
16+
use PHPUnit\Framework\TestCase;
17+
18+
#[CoversMethod(AlterTableDecorator::class, 'processAddColumns')]
19+
#[CoversMethod(AlterTableDecorator::class, 'processChangeColumns')]
20+
#[CoversMethod(AlterTableDecorator::class, 'getSqlInsertOffsets')]
21+
final class AlterTableDecoratorTest extends TestCase
22+
{
23+
protected AdapterPlatform $platform;
24+
25+
protected function setUp(): void
26+
{
27+
$driver = new Driver(
28+
$this->createMock(Connection::class),
29+
$this->createMock(Statement::class),
30+
$this->createMock(Result::class),
31+
);
32+
$this->platform = new AdapterPlatform($driver);
33+
}
34+
35+
private function buildSql(AlterTable $table): string
36+
{
37+
$decorator = new AlterTableDecorator();
38+
$decorator->setSubject($table);
39+
40+
return $decorator->getSqlString($this->platform);
41+
}
42+
43+
public function testAddColumnCharset(): void
44+
{
45+
$alter = new AlterTable('test');
46+
$col = new Column\Varchar('name', 255);
47+
$col->setOption('charset', 'utf8mb3');
48+
$alter->addColumn($col);
49+
50+
$sql = $this->buildSql($alter);
51+
52+
self::assertStringContainsString('CHARACTER SET utf8mb3', $sql);
53+
}
54+
55+
public function testAddColumnCollate(): void
56+
{
57+
$alter = new AlterTable('test');
58+
$col = new Column\Varchar('name', 255);
59+
$col->setOption('collate', 'utf8mb3_unicode_ci');
60+
$alter->addColumn($col);
61+
62+
$sql = $this->buildSql($alter);
63+
64+
self::assertStringContainsString('COLLATE utf8mb3_unicode_ci', $sql);
65+
}
66+
67+
public function testAddColumnCharsetAndCollate(): void
68+
{
69+
$alter = new AlterTable('test');
70+
$col = new Column\Varchar('name', 255);
71+
$col->setOption('charset', 'utf8mb3');
72+
$col->setOption('collate', 'utf8mb3_unicode_ci');
73+
$alter->addColumn($col);
74+
75+
$sql = $this->buildSql($alter);
76+
77+
self::assertStringContainsString('CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci', $sql);
78+
}
79+
80+
public function testAddColumnCharsetBeforeNotNull(): void
81+
{
82+
$alter = new AlterTable('test');
83+
$col = new Column\Varchar('name', 255);
84+
$col->setNullable(false);
85+
$col->setOption('charset', 'utf8mb3');
86+
$col->setOption('collate', 'utf8mb3_unicode_ci');
87+
$alter->addColumn($col);
88+
89+
$sql = $this->buildSql($alter);
90+
91+
self::assertMatchesRegularExpression(
92+
'/CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL/',
93+
$sql,
94+
);
95+
}
96+
97+
public function testChangeColumnCharset(): void
98+
{
99+
$alter = new AlterTable('test');
100+
$col = new Column\Varchar('name', 255);
101+
$col->setOption('charset', 'utf8mb3');
102+
$alter->changeColumn('name', $col);
103+
104+
$sql = $this->buildSql($alter);
105+
106+
self::assertStringContainsString('CHARACTER SET utf8mb3', $sql);
107+
}
108+
109+
public function testChangeColumnCollate(): void
110+
{
111+
$alter = new AlterTable('test');
112+
$col = new Column\Varchar('name', 255);
113+
$col->setOption('collate', 'utf8mb3_unicode_ci');
114+
$alter->changeColumn('name', $col);
115+
116+
$sql = $this->buildSql($alter);
117+
118+
self::assertStringContainsString('COLLATE utf8mb3_unicode_ci', $sql);
119+
}
120+
121+
public function testChangeColumnCharsetAndCollate(): void
122+
{
123+
$alter = new AlterTable('test');
124+
$col = new Column\Varchar('name', 255);
125+
$col->setNullable(false);
126+
$col->setOption('charset', 'utf8mb3');
127+
$col->setOption('collate', 'utf8mb3_unicode_ci');
128+
$alter->changeColumn('name', $col);
129+
130+
$sql = $this->buildSql($alter);
131+
132+
self::assertMatchesRegularExpression(
133+
'/CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL/',
134+
$sql,
135+
);
136+
}
137+
138+
public function testAddColumnAfter(): void
139+
{
140+
$alter = new AlterTable('test');
141+
$col = new Column\Varchar('name', 255);
142+
$col->setOption('after', 'id');
143+
$alter->addColumn($col);
144+
145+
$sql = $this->buildSql($alter);
146+
147+
self::assertStringContainsString('AFTER `id`', $sql);
148+
}
149+
150+
public function testAddColumnUnsigned(): void
151+
{
152+
$alter = new AlterTable('test');
153+
$col = new Column\Integer('id');
154+
$col->setOption('unsigned', true);
155+
$col->setOption('auto_increment', true);
156+
$alter->addColumn($col);
157+
158+
$sql = $this->buildSql($alter);
159+
160+
self::assertStringContainsString('UNSIGNED', $sql);
161+
self::assertStringContainsString('AUTO_INCREMENT', $sql);
162+
}
163+
}

0 commit comments

Comments
 (0)