Skip to content

Commit 37ab825

Browse files
authored
Merge pull request #6820 from morozov/alter-table-integration-testing
Convert some unit tests to integration tests
2 parents be9c119 + 90e365c commit 37ab825

File tree

2 files changed

+218
-166
lines changed

2 files changed

+218
-166
lines changed
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Tests\Functional\Schema;
6+
7+
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
8+
use Doctrine\DBAL\Platforms\DB2Platform;
9+
use Doctrine\DBAL\Platforms\OraclePlatform;
10+
use Doctrine\DBAL\Platforms\SQLitePlatform;
11+
use Doctrine\DBAL\Platforms\SQLServerPlatform;
12+
use Doctrine\DBAL\Schema\Table;
13+
use Doctrine\DBAL\Tests\FunctionalTestCase;
14+
use Doctrine\DBAL\Types\Types;
15+
16+
class AlterTableTest extends FunctionalTestCase
17+
{
18+
public function testAddPrimaryKeyOnExistingColumn(): void
19+
{
20+
if ($this->connection->getDatabasePlatform() instanceof SQLitePlatform) {
21+
self::markTestSkipped(
22+
'SQLite will automatically set up auto-increment behavior on the primary key column, which this test'
23+
. ' does not expect.',
24+
);
25+
}
26+
27+
$table = new Table('alter_pk');
28+
$table->addColumn('id', Types::INTEGER);
29+
$table->addColumn('val', Types::INTEGER);
30+
31+
$this->testMigration($table, static function (Table $table): void {
32+
$table->setPrimaryKey(['id']);
33+
});
34+
}
35+
36+
public function testAddPrimaryKeyOnNewAutoIncrementColumn(): void
37+
{
38+
if ($this->connection->getDatabasePlatform() instanceof DB2Platform) {
39+
self::markTestSkipped(
40+
'IBM DB2 LUW does not support adding identity columns to an existing table.',
41+
);
42+
}
43+
44+
$table = new Table('alter_pk');
45+
$table->addColumn('val', Types::INTEGER);
46+
47+
$this->testMigration($table, static function (Table $table): void {
48+
$table->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
49+
$table->setPrimaryKey(['id']);
50+
});
51+
}
52+
53+
public function testAlterPrimaryKeyFromAutoincrementToNonAutoincrementColumn(): void
54+
{
55+
$platform = $this->connection->getDatabasePlatform();
56+
57+
if ($platform instanceof AbstractMySQLPlatform) {
58+
self::markTestIncomplete(
59+
'DBAL should not allow this migration on MySQL because an auto-increment column must be part of the'
60+
. ' primary key constraint.',
61+
);
62+
}
63+
64+
if ($platform instanceof SQLitePlatform) {
65+
self::markTestSkipped(
66+
'SQLite does not support auto-increment columns that are not part the primary key constraint',
67+
);
68+
}
69+
70+
$this->ensureDroppingPrimaryKeyConstraintIsSupported();
71+
72+
$table = new Table('alter_pk');
73+
$table->addColumn('id1', Types::INTEGER, ['autoincrement' => true]);
74+
$table->addColumn('id2', Types::INTEGER);
75+
$table->setPrimaryKey(['id1']);
76+
77+
$this->testMigration($table, static function (Table $table): void {
78+
$table->dropPrimaryKey();
79+
$table->setPrimaryKey(['id2']);
80+
});
81+
}
82+
83+
public function testDropPrimaryKeyWithAutoincrementColumn(): void
84+
{
85+
$platform = $this->connection->getDatabasePlatform();
86+
87+
if ($platform instanceof AbstractMySQLPlatform) {
88+
self::markTestIncomplete(
89+
'DBAL should not allow this migration on MySQL because an auto-increment column must be part of the'
90+
. ' primary key constraint.',
91+
);
92+
}
93+
94+
if ($platform instanceof SQLitePlatform) {
95+
self::markTestSkipped(
96+
'SQLite does not support auto-increment columns as part of composite primary key constraint',
97+
);
98+
}
99+
100+
$this->ensureDroppingPrimaryKeyConstraintIsSupported();
101+
102+
$table = new Table('alter_pk');
103+
$table->addColumn('id1', Types::INTEGER, ['autoincrement' => true]);
104+
$table->addColumn('id2', Types::INTEGER);
105+
$table->setPrimaryKey(['id1', 'id2']);
106+
107+
$this->testMigration($table, static function (Table $table): void {
108+
$table->dropPrimaryKey();
109+
});
110+
}
111+
112+
public function testDropNonAutoincrementColumnFromCompositePrimaryKeyWithAutoincrementColumn(): void
113+
{
114+
if ($this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform) {
115+
self::markTestIncomplete(
116+
'DBAL does not restore the auto-increment attribute after dropping and adding the constraint,'
117+
. ' which is a bug.',
118+
);
119+
}
120+
121+
$this->ensureDroppingPrimaryKeyConstraintIsSupported();
122+
123+
$table = new Table('alter_pk');
124+
$table->addColumn('id1', Types::INTEGER, ['autoincrement' => true]);
125+
$table->addColumn('id2', Types::INTEGER);
126+
$table->setPrimaryKey(['id1', 'id2']);
127+
128+
$this->testMigration($table, static function (Table $table): void {
129+
$table->dropPrimaryKey();
130+
$table->setPrimaryKey(['id1']);
131+
});
132+
}
133+
134+
public function testAddNonAutoincrementColumnToPrimaryKeyWithAutoincrementColumn(): void
135+
{
136+
$platform = $this->connection->getDatabasePlatform();
137+
138+
if ($platform instanceof AbstractMySQLPlatform) {
139+
self::markTestIncomplete(
140+
'DBAL does not restore the auto-increment attribute after dropping and adding the constraint,'
141+
. ' which is a bug.',
142+
);
143+
}
144+
145+
if ($platform instanceof SQLitePlatform) {
146+
self::markTestSkipped(
147+
'SQLite does not support auto-increment columns as part of composite primary key constraint',
148+
);
149+
}
150+
151+
$this->ensureDroppingPrimaryKeyConstraintIsSupported();
152+
153+
$table = new Table('alter_pk');
154+
$table->addColumn('id1', Types::INTEGER, ['autoincrement' => true]);
155+
$table->addColumn('id2', Types::INTEGER);
156+
$table->setPrimaryKey(['id1']);
157+
158+
$this->testMigration($table, static function (Table $table): void {
159+
$table->dropPrimaryKey();
160+
$table->setPrimaryKey(['id1', 'id2']);
161+
});
162+
}
163+
164+
public function testAddNewColumnToPrimaryKey(): void
165+
{
166+
$this->ensureDroppingPrimaryKeyConstraintIsSupported();
167+
168+
$table = new Table('alter_pk');
169+
$table->addColumn('id1', Types::INTEGER);
170+
$table->setPrimaryKey(['id1']);
171+
172+
$this->testMigration($table, static function (Table $table): void {
173+
$table->addColumn('id2', Types::INTEGER);
174+
$table->dropPrimaryKey();
175+
$table->setPrimaryKey(['id1', 'id2']);
176+
});
177+
}
178+
179+
private function ensureDroppingPrimaryKeyConstraintIsSupported(): void
180+
{
181+
$platform = $this->connection->getDatabasePlatform();
182+
183+
if (
184+
! ($platform instanceof DB2Platform)
185+
&& ! ($platform instanceof OraclePlatform)
186+
&& ! ($platform instanceof SQLServerPlatform)
187+
) {
188+
return;
189+
}
190+
191+
self::markTestIncomplete(
192+
'Dropping primary key constraint on the currently used database platform is not implemented.',
193+
);
194+
}
195+
196+
private function testMigration(Table $oldTable, callable $migration): void
197+
{
198+
$this->dropAndCreateTable($oldTable);
199+
200+
$newTable = clone $oldTable;
201+
202+
$migration($newTable);
203+
204+
$schemaManager = $this->connection->createSchemaManager();
205+
206+
$diff = $schemaManager->createComparator()
207+
->compareTables($oldTable, $newTable);
208+
209+
$schemaManager->alterTable($diff);
210+
211+
$introspectedTable = $schemaManager->introspectTable($newTable->getName());
212+
213+
$diff = $schemaManager->createComparator()
214+
->compareTables($newTable, $introspectedTable);
215+
216+
self::assertTrue($diff->isEmpty());
217+
}
218+
}

tests/Platforms/AbstractMySQLPlatformTestCase.php

Lines changed: 0 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -282,172 +282,6 @@ public function testBlobTypeDeclarationSQL(): void
282282
self::assertEquals('LONGBLOB', $this->platform->getBlobTypeDeclarationSQL([]));
283283
}
284284

285-
public function testAlterTableAddPrimaryKey(): void
286-
{
287-
$table = new Table('alter_table_add_pk');
288-
$table->addColumn('id', Types::INTEGER);
289-
$table->addColumn('foo', Types::INTEGER);
290-
$table->addIndex(['id'], 'idx_id');
291-
292-
$diffTable = clone $table;
293-
294-
$diffTable->dropIndex('idx_id');
295-
$diffTable->setPrimaryKey(['id']);
296-
297-
$diff = $this->createComparator()
298-
->compareTables($table, $diffTable);
299-
300-
self::assertEquals(
301-
['DROP INDEX idx_id ON alter_table_add_pk', 'ALTER TABLE alter_table_add_pk ADD PRIMARY KEY (id)'],
302-
$this->platform->getAlterTableSQL($diff),
303-
);
304-
}
305-
306-
public function testAlterPrimaryKeyWithAutoincrementColumn(): void
307-
{
308-
$table = new Table('alter_primary_key');
309-
$table->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
310-
$table->addColumn('foo', Types::INTEGER);
311-
$table->setPrimaryKey(['id']);
312-
313-
$diffTable = clone $table;
314-
315-
$diffTable->dropPrimaryKey();
316-
$diffTable->setPrimaryKey(['foo']);
317-
318-
$diff = $this->createComparator()
319-
->compareTables($table, $diffTable);
320-
321-
self::assertEquals(
322-
[
323-
'ALTER TABLE alter_primary_key MODIFY id INT NOT NULL',
324-
'DROP INDEX `primary` ON alter_primary_key',
325-
'ALTER TABLE alter_primary_key ADD PRIMARY KEY (foo)',
326-
],
327-
$this->platform->getAlterTableSQL($diff),
328-
);
329-
}
330-
331-
public function testDropPrimaryKeyWithAutoincrementColumn(): void
332-
{
333-
$table = new Table('drop_primary_key');
334-
$table->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
335-
$table->addColumn('foo', Types::INTEGER);
336-
$table->addColumn('bar', Types::INTEGER);
337-
$table->setPrimaryKey(['id', 'foo']);
338-
339-
$diffTable = clone $table;
340-
341-
$diffTable->dropPrimaryKey();
342-
343-
$diff = $this->createComparator()
344-
->compareTables($table, $diffTable);
345-
346-
self::assertEquals(
347-
[
348-
'ALTER TABLE drop_primary_key MODIFY id INT NOT NULL',
349-
'DROP INDEX `primary` ON drop_primary_key',
350-
],
351-
$this->platform->getAlterTableSQL($diff),
352-
);
353-
}
354-
355-
public function testDropNonAutoincrementColumnFromCompositePrimaryKeyWithAutoincrementColumn(): void
356-
{
357-
$table = new Table('tbl');
358-
$table->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
359-
$table->addColumn('foo', Types::INTEGER);
360-
$table->addColumn('bar', Types::INTEGER);
361-
$table->setPrimaryKey(['id', 'foo']);
362-
363-
$diffTable = clone $table;
364-
365-
$diffTable->dropPrimaryKey();
366-
$diffTable->setPrimaryKey(['id']);
367-
368-
$diff = $this->createComparator()
369-
->compareTables($table, $diffTable);
370-
371-
self::assertSame(
372-
[
373-
'ALTER TABLE tbl MODIFY id INT NOT NULL',
374-
'DROP INDEX `primary` ON tbl',
375-
'ALTER TABLE tbl ADD PRIMARY KEY (id)',
376-
],
377-
$this->platform->getAlterTableSQL($diff),
378-
);
379-
}
380-
381-
public function testAddNonAutoincrementColumnToPrimaryKeyWithAutoincrementColumn(): void
382-
{
383-
$table = new Table('tbl');
384-
$table->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
385-
$table->addColumn('foo', Types::INTEGER);
386-
$table->addColumn('bar', Types::INTEGER);
387-
$table->setPrimaryKey(['id']);
388-
389-
$diffTable = clone $table;
390-
391-
$diffTable->dropPrimaryKey();
392-
$diffTable->setPrimaryKey(['id', 'foo']);
393-
394-
$diff = $this->createComparator()
395-
->compareTables($table, $diffTable);
396-
397-
self::assertSame(
398-
[
399-
'ALTER TABLE tbl MODIFY id INT NOT NULL',
400-
'DROP INDEX `primary` ON tbl',
401-
'ALTER TABLE tbl ADD PRIMARY KEY (id, foo)',
402-
],
403-
$this->platform->getAlterTableSQL($diff),
404-
);
405-
}
406-
407-
public function testAddAutoIncrementPrimaryKey(): void
408-
{
409-
$keyTable = new Table('foo');
410-
$keyTable->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
411-
$keyTable->addColumn('baz', Types::STRING, ['length' => 32]);
412-
$keyTable->setPrimaryKey(['id']);
413-
414-
$oldTable = new Table('foo');
415-
$oldTable->addColumn('baz', Types::STRING, ['length' => 32]);
416-
417-
$diff = $this->createComparator()
418-
->compareTables($oldTable, $keyTable);
419-
420-
$sql = $this->platform->getAlterTableSQL($diff);
421-
422-
self::assertEquals(['ALTER TABLE foo ADD id INT AUTO_INCREMENT NOT NULL, ADD PRIMARY KEY (id)'], $sql);
423-
}
424-
425-
public function testAlterPrimaryKeyWithNewColumn(): void
426-
{
427-
$table = new Table('yolo');
428-
$table->addColumn('pkc1', Types::INTEGER);
429-
$table->addColumn('col_a', Types::INTEGER);
430-
$table->setPrimaryKey(['pkc1']);
431-
432-
$diffTable = clone $table;
433-
434-
$diffTable->addColumn('pkc2', Types::INTEGER);
435-
$diffTable->dropPrimaryKey();
436-
$diffTable->setPrimaryKey(['pkc1', 'pkc2']);
437-
438-
$diff = $this->createComparator()
439-
->compareTables($table, $diffTable);
440-
441-
self::assertSame(
442-
[
443-
'DROP INDEX `primary` ON yolo',
444-
'ALTER TABLE yolo ADD pkc2 INT NOT NULL',
445-
'ALTER TABLE yolo ADD PRIMARY KEY (pkc1, pkc2)',
446-
],
447-
$this->platform->getAlterTableSQL($diff),
448-
);
449-
}
450-
451285
public function testInitializesDoctrineTypeMappings(): void
452286
{
453287
self::assertTrue($this->platform->hasDoctrineTypeMappingFor('binary'));

0 commit comments

Comments
 (0)