Completed
Pull Request — 2.10.x (#3936)
by Asmir
65:42
created

ComparatorTest::testTableUpdateForeignKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 18
rs 9.8666
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Schema;
4
5
use Doctrine\DBAL\Schema\Column;
6
use Doctrine\DBAL\Schema\ColumnDiff;
7
use Doctrine\DBAL\Schema\Comparator;
8
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
9
use Doctrine\DBAL\Schema\Index;
10
use Doctrine\DBAL\Schema\Schema;
11
use Doctrine\DBAL\Schema\SchemaConfig;
12
use Doctrine\DBAL\Schema\SchemaDiff;
13
use Doctrine\DBAL\Schema\Sequence;
14
use Doctrine\DBAL\Schema\Table;
15
use Doctrine\DBAL\Schema\TableDiff;
16
use Doctrine\DBAL\Types\Type;
17
use PHPUnit\Framework\TestCase;
18
use function array_keys;
19
use function get_class;
20
21
class ComparatorTest extends TestCase
22
{
23
    public function testCompareSame1() : void
24
    {
25
        $schema1 = new Schema([
26
            'bugdb' => new Table(
27
                'bugdb',
28
                [
29
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
30
                ]
31
            ),
32
        ]);
33
        $schema2 = new Schema([
34
            'bugdb' => new Table(
35
                'bugdb',
36
                [
37
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
38
                ]
39
            ),
40
        ]);
41
42
        $expected             = new SchemaDiff();
43
        $expected->fromSchema = $schema1;
44
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
45
    }
46
47
    public function testCompareSame2() : void
48
    {
49
        $schema1 = new Schema([
50
            'bugdb' => new Table(
51
                'bugdb',
52
                [
53
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
54
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
55
                ]
56
            ),
57
        ]);
58
        $schema2 = new Schema([
59
            'bugdb' => new Table(
60
                'bugdb',
61
                [
62
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
63
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
64
                ]
65
            ),
66
        ]);
67
68
        $expected             = new SchemaDiff();
69
        $expected->fromSchema = $schema1;
70
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
71
    }
72
73
    public function testCompareMissingTable() : void
74
    {
75
        $schemaConfig = new SchemaConfig();
76
        $table        = new Table('bugdb', ['integerfield1' => new Column('integerfield1', Type::getType('integer'))]);
77
        $table->setSchemaConfig($schemaConfig);
78
79
        $schema1 = new Schema([$table], [], $schemaConfig);
80
        $schema2 = new Schema([], [], $schemaConfig);
81
82
        $expected = new SchemaDiff([], [], ['bugdb' => $table], $schema1);
83
84
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
85
    }
86
87
    public function testCompareNewTable() : void
88
    {
89
        $schemaConfig = new SchemaConfig();
90
        $table        = new Table('bugdb', ['integerfield1' => new Column('integerfield1', Type::getType('integer'))]);
91
        $table->setSchemaConfig($schemaConfig);
92
93
        $schema1 = new Schema([], [], $schemaConfig);
94
        $schema2 = new Schema([$table], [], $schemaConfig);
95
96
        $expected = new SchemaDiff(['bugdb' => $table], [], [], $schema1);
97
98
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
99
    }
100
101
    public function testCompareOnlyAutoincrementChanged() : void
102
    {
103
        $column1 = new Column('foo', Type::getType('integer'), ['autoincrement' => true]);
104
        $column2 = new Column('foo', Type::getType('integer'), ['autoincrement' => false]);
105
106
        $comparator        = new Comparator();
107
        $changedProperties = $comparator->diffColumn($column1, $column2);
108
109
        self::assertEquals(['autoincrement'], $changedProperties);
110
    }
111
112
    public function testCompareMissingField() : void
113
    {
114
        $missingColumn = new Column('integerfield1', Type::getType('integer'));
115
        $schema1       = new Schema([
116
            'bugdb' => new Table(
117
                'bugdb',
118
                [
119
                    'integerfield1' => $missingColumn,
120
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
121
                ]
122
            ),
123
        ]);
124
        $schema2       = new Schema([
125
            'bugdb' => new Table(
126
                'bugdb',
127
                [
128
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
129
                ]
130
            ),
131
        ]);
132
133
        $expected                                    = new SchemaDiff(
134
            [],
135
            [
136
                'bugdb' => new TableDiff(
137
                    'bugdb',
138
                    [],
139
                    [],
140
                    ['integerfield1' => $missingColumn]
141
                ),
142
            ]
143
        );
144
        $expected->fromSchema                        = $schema1;
145
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
146
147
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
148
    }
149
150
    public function testCompareNewField() : void
151
    {
152
        $schema1 = new Schema([
153
            'bugdb' => new Table(
154
                'bugdb',
155
                [
156
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
157
                ]
158
            ),
159
        ]);
160
        $schema2 = new Schema([
161
            'bugdb' => new Table(
162
                'bugdb',
163
                [
164
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
165
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
166
                ]
167
            ),
168
        ]);
169
170
        $expected                                    = new SchemaDiff(
171
            [],
172
            [
173
                'bugdb' => new TableDiff(
174
                    'bugdb',
175
                    [
176
                        'integerfield2' => new Column('integerfield2', Type::getType('integer')),
177
                    ]
178
                ),
179
            ]
180
        );
181
        $expected->fromSchema                        = $schema1;
182
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
183
184
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
185
    }
186
187
    public function testCompareChangedColumnsChangeType() : void
188
    {
189
        $column1 = new Column('charfield1', Type::getType('string'));
190
        $column2 = new Column('charfield1', Type::getType('integer'));
191
192
        $c = new Comparator();
193
        self::assertEquals(['type'], $c->diffColumn($column1, $column2));
194
        self::assertEquals([], $c->diffColumn($column1, $column1));
195
    }
196
197
    public function testCompareColumnsMultipleTypeInstances() : void
198
    {
199
        $integerType1 = Type::getType('integer');
200
        Type::overrideType('integer', get_class($integerType1));
201
        $integerType2 = Type::getType('integer');
202
203
        $column1 = new Column('integerfield1', $integerType1);
204
        $column2 = new Column('integerfield1', $integerType2);
205
206
        $c = new Comparator();
207
        self::assertEquals([], $c->diffColumn($column1, $column2));
208
    }
209
210
    public function testCompareColumnsOverriddenType() : void
211
    {
212
        $oldStringInstance = Type::getType('string');
213
        $integerType       = Type::getType('integer');
214
215
        Type::overrideType('string', get_class($integerType));
216
        $overriddenStringType = Type::getType('string');
217
218
        Type::overrideType('string', get_class($oldStringInstance));
219
220
        $column1 = new Column('integerfield1', $integerType);
221
        $column2 = new Column('integerfield1', $overriddenStringType);
222
223
        $c = new Comparator();
224
        self::assertEquals([], $c->diffColumn($column1, $column2));
225
    }
226
227
    public function testCompareChangedColumnsChangeCustomSchemaOption() : void
228
    {
229
        $column1 = new Column('charfield1', Type::getType('string'));
230
        $column2 = new Column('charfield1', Type::getType('string'));
231
232
        $column1->setCustomSchemaOption('foo', 'bar');
233
        $column2->setCustomSchemaOption('foo', 'bar');
234
235
        $column1->setCustomSchemaOption('foo1', 'bar1');
236
        $column2->setCustomSchemaOption('foo2', 'bar2');
237
238
        $c = new Comparator();
239
        self::assertEquals(['foo1', 'foo2'], $c->diffColumn($column1, $column2));
240
        self::assertEquals([], $c->diffColumn($column1, $column1));
241
    }
242
243
    public function testCompareChangeColumnsMultipleNewColumnsRename() : void
244
    {
245
        $tableA = new Table('foo');
246
        $tableA->addColumn('datefield1', 'datetime');
247
248
        $tableB = new Table('foo');
249
        $tableB->addColumn('new_datefield1', 'datetime');
250
        $tableB->addColumn('new_datefield2', 'datetime');
251
252
        $c         = new Comparator();
253
        $tableDiff = $c->diffTable($tableA, $tableB);
254
255
        self::assertCount(1, $tableDiff->renamedColumns, 'we should have one rename datefield1 => new_datefield1.');
256
        self::assertArrayHasKey('datefield1', $tableDiff->renamedColumns, "'datefield1' should be set to be renamed to new_datefield1");
257
        self::assertCount(1, $tableDiff->addedColumns, "'new_datefield2' should be added");
258
        self::assertArrayHasKey('new_datefield2', $tableDiff->addedColumns, "'new_datefield2' should be added, not created through renaming!");
259
        self::assertCount(0, $tableDiff->removedColumns, 'Nothing should be removed.');
260
        self::assertCount(0, $tableDiff->changedColumns, 'Nothing should be changed as all fields old & new have diff names.');
261
    }
262
263
    public function testCompareRemovedIndex() : void
264
    {
265
        $schema1 = new Schema([
266
            'bugdb' => new Table(
267
                'bugdb',
268
                [
269
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
270
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
271
                ],
272
                [
273
                    'primary' => new Index(
274
                        'primary',
275
                        ['integerfield1'],
276
                        true
277
                    ),
278
                ]
279
            ),
280
        ]);
281
        $schema2 = new Schema([
282
            'bugdb' => new Table(
283
                'bugdb',
284
                [
285
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
286
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
287
                ]
288
            ),
289
        ]);
290
291
        $expected                                    = new SchemaDiff(
292
            [],
293
            [
294
                'bugdb' => new TableDiff(
295
                    'bugdb',
296
                    [],
297
                    [],
298
                    [],
299
                    [],
300
                    [],
301
                    [
302
                        'primary' => new Index(
303
                            'primary',
304
                            ['integerfield1'],
305
                            true
306
                        ),
307
                    ]
308
                ),
309
            ]
310
        );
311
        $expected->fromSchema                        = $schema1;
312
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
313
314
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
315
    }
316
317
    public function testCompareNewIndex() : void
318
    {
319
        $schema1 = new Schema([
320
            'bugdb' => new Table(
321
                'bugdb',
322
                [
323
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
324
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
325
                ]
326
            ),
327
        ]);
328
        $schema2 = new Schema([
329
            'bugdb' => new Table(
330
                'bugdb',
331
                [
332
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
333
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
334
                ],
335
                [
336
                    'primary' => new Index(
337
                        'primary',
338
                        ['integerfield1'],
339
                        true
340
                    ),
341
                ]
342
            ),
343
        ]);
344
345
        $expected                                    = new SchemaDiff(
346
            [],
347
            [
348
                'bugdb' => new TableDiff(
349
                    'bugdb',
350
                    [],
351
                    [],
352
                    [],
353
                    [
354
                        'primary' => new Index(
355
                            'primary',
356
                            ['integerfield1'],
357
                            true
358
                        ),
359
                    ]
360
                ),
361
            ]
362
        );
363
        $expected->fromSchema                        = $schema1;
364
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
365
366
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
367
    }
368
369
    public function testCompareChangedIndex() : void
370
    {
371
        $schema1 = new Schema([
372
            'bugdb' => new Table(
373
                'bugdb',
374
                [
375
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
376
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
377
                ],
378
                [
379
                    'primary' => new Index(
380
                        'primary',
381
                        ['integerfield1'],
382
                        true
383
                    ),
384
                ]
385
            ),
386
        ]);
387
        $schema2 = new Schema([
388
            'bugdb' => new Table(
389
                'bugdb',
390
                [
391
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
392
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
393
                ],
394
                [
395
                    'primary' => new Index(
396
                        'primary',
397
                        ['integerfield1', 'integerfield2'],
398
                        true
399
                    ),
400
                ]
401
            ),
402
        ]);
403
404
        $expected                                    = new SchemaDiff(
405
            [],
406
            [
407
                'bugdb' => new TableDiff(
408
                    'bugdb',
409
                    [],
410
                    [],
411
                    [],
412
                    [],
413
                    [
414
                        'primary' => new Index(
415
                            'primary',
416
                            [
417
                                'integerfield1',
418
                                'integerfield2',
419
                            ],
420
                            true
421
                        ),
422
                    ]
423
                ),
424
            ]
425
        );
426
        $expected->fromSchema                        = $schema1;
427
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
428
429
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
430
    }
431
432
    public function testCompareChangedIndexFieldPositions() : void
433
    {
434
        $schema1 = new Schema([
435
            'bugdb' => new Table(
436
                'bugdb',
437
                [
438
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
439
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
440
                ],
441
                [
442
                    'primary' => new Index('primary', ['integerfield1', 'integerfield2'], true),
443
                ]
444
            ),
445
        ]);
446
        $schema2 = new Schema([
447
            'bugdb' => new Table(
448
                'bugdb',
449
                [
450
                    'integerfield1' => new Column('integerfield1', Type::getType('integer')),
451
                    'integerfield2' => new Column('integerfield2', Type::getType('integer')),
452
                ],
453
                [
454
                    'primary' => new Index('primary', ['integerfield2', 'integerfield1'], true),
455
                ]
456
            ),
457
        ]);
458
459
        $expected                                    = new SchemaDiff(
460
            [],
461
            [
462
                'bugdb' => new TableDiff(
463
                    'bugdb',
464
                    [],
465
                    [],
466
                    [],
467
                    [],
468
                    [
469
                        'primary' => new Index('primary', ['integerfield2', 'integerfield1'], true),
470
                    ]
471
                ),
472
            ]
473
        );
474
        $expected->fromSchema                        = $schema1;
475
        $expected->changedTables['bugdb']->fromTable = $schema1->getTable('bugdb');
476
477
        self::assertEquals($expected, Comparator::compareSchemas($schema1, $schema2));
478
    }
479
480
    public function testCompareRenamePrimaryKeyAndChangeColumnsDropsItAndCreatesIt() : void
481
    {
482
        $table = new Table('users');
483
        $table->addColumn('id', 'integer', ['notnull' => true]);
484
        $table->addColumn('code', 'integer', ['notnull' => true]);
485
        $table->setPrimaryKey(['id'], 'users_pkey');
486
487
        $toTable = new Table('users');
488
        $toTable->addColumn('id', 'integer', ['notnull' => true]);
489
        $toTable->addColumn('code', 'integer', ['notnull' => true]);
490
        $toTable->setPrimaryKey(['id', 'code'], 'pkey_test');
491
492
        $c         = new Comparator();
493
        $tableDiff = $c->diffTable($table, $toTable);
494
495
        self::assertNotNull($tableDiff);
496
        self::assertCount(1, $tableDiff->addedIndexes);
497
        self::assertSame(['id', 'code'], $tableDiff->addedIndexes['pkey_test']->getColumns());
498
499
        self::assertCount(1, $tableDiff->removedIndexes);
500
        self::assertSame(['id'], $tableDiff->removedIndexes['users_pkey']->getColumns());
501
    }
502
503
    public function testCompareSequences() : void
504
    {
505
        $seq1 = new Sequence('foo', 1, 1);
506
        $seq2 = new Sequence('foo', 1, 2);
507
        $seq3 = new Sequence('foo', 2, 1);
508
        $seq4 = new Sequence('foo', '1', '1');
509
510
        $c = new Comparator();
511
512
        self::assertTrue($c->diffSequence($seq1, $seq2));
513
        self::assertTrue($c->diffSequence($seq1, $seq3));
514
        self::assertFalse($c->diffSequence($seq1, $seq4));
515
    }
516
517
    public function testRemovedSequence() : void
518
    {
519
        $schema1 = new Schema();
520
        $seq     = $schema1->createSequence('foo');
521
522
        $schema2 = new Schema();
523
524
        $c          = new Comparator();
525
        $diffSchema = $c->compare($schema1, $schema2);
526
527
        self::assertCount(1, $diffSchema->removedSequences);
528
        self::assertSame($seq, $diffSchema->removedSequences[0]);
529
    }
530
531
    public function testAddedSequence() : void
532
    {
533
        $schema1 = new Schema();
534
535
        $schema2 = new Schema();
536
        $seq     = $schema2->createSequence('foo');
537
538
        $c          = new Comparator();
539
        $diffSchema = $c->compare($schema1, $schema2);
540
541
        self::assertCount(1, $diffSchema->newSequences);
542
        self::assertSame($seq, $diffSchema->newSequences[0]);
543
    }
544
545
    public function testTableAddForeignKey() : void
546
    {
547
        $tableForeign = new Table('bar');
548
        $tableForeign->addColumn('id', 'integer');
549
550
        $table1 = new Table('foo');
551
        $table1->addColumn('fk', 'integer');
552
553
        $table2 = new Table('foo');
554
        $table2->addColumn('fk', 'integer');
555
        $table2->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
556
557
        $c         = new Comparator();
558
        $tableDiff = $c->diffTable($table1, $table2);
559
560
        self::assertInstanceOf(TableDiff::class, $tableDiff);
561
        self::assertCount(1, $tableDiff->addedForeignKeys);
562
    }
563
564
    public function testTableRemoveForeignKey() : void
565
    {
566
        $tableForeign = new Table('bar');
567
        $tableForeign->addColumn('id', 'integer');
568
569
        $table1 = new Table('foo');
570
        $table1->addColumn('fk', 'integer');
571
572
        $table2 = new Table('foo');
573
        $table2->addColumn('fk', 'integer');
574
        $table2->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
575
576
        $c         = new Comparator();
577
        $tableDiff = $c->diffTable($table2, $table1);
578
579
        self::assertInstanceOf(TableDiff::class, $tableDiff);
580
        self::assertCount(1, $tableDiff->removedForeignKeys);
581
    }
582
583
    public function testTableUpdateForeignKey() : void
584
    {
585
        $tableForeign = new Table('bar');
586
        $tableForeign->addColumn('id', 'integer');
587
588
        $table1 = new Table('foo');
589
        $table1->addColumn('fk', 'integer');
590
        $table1->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
591
592
        $table2 = new Table('foo');
593
        $table2->addColumn('fk', 'integer');
594
        $table2->addForeignKeyConstraint($tableForeign, ['fk'], ['id'], ['onUpdate' => 'CASCADE']);
595
596
        $c         = new Comparator();
597
        $tableDiff = $c->diffTable($table1, $table2);
598
599
        self::assertInstanceOf(TableDiff::class, $tableDiff);
600
        self::assertCount(1, $tableDiff->changedForeignKeys);
601
    }
602
603
    public function testMovedForeignKeyForeignTable() : void
604
    {
605
        $tableForeign = new Table('bar');
606
        $tableForeign->addColumn('id', 'integer');
607
608
        $tableForeign2 = new Table('bar2');
609
        $tableForeign2->addColumn('id', 'integer');
610
611
        $table1 = new Table('foo');
612
        $table1->addColumn('fk', 'integer');
613
        $table1->addForeignKeyConstraint($tableForeign, ['fk'], ['id']);
614
615
        $table2 = new Table('foo');
616
        $table2->addColumn('fk', 'integer');
617
        $table2->addForeignKeyConstraint($tableForeign2, ['fk'], ['id']);
618
619
        $c         = new Comparator();
620
        $tableDiff = $c->diffTable($table1, $table2);
621
622
        self::assertInstanceOf(TableDiff::class, $tableDiff);
623
        self::assertCount(1, $tableDiff->changedForeignKeys);
624
    }
625
626
    public function testTablesCaseInsensitive() : void
627
    {
628
        $schemaA = new Schema();
629
        $schemaA->createTable('foo');
630
        $schemaA->createTable('bAr');
631
        $schemaA->createTable('BAZ');
632
        $schemaA->createTable('new');
633
634
        $schemaB = new Schema();
635
        $schemaB->createTable('FOO');
636
        $schemaB->createTable('bar');
637
        $schemaB->createTable('Baz');
638
        $schemaB->createTable('old');
639
640
        $c    = new Comparator();
641
        $diff = $c->compare($schemaA, $schemaB);
642
643
        $this->assertSchemaTableChangeCount($diff, 1, 0, 1);
644
    }
645
646
    public function testSequencesCaseInsensitive() : void
647
    {
648
        $schemaA = new Schema();
649
        $schemaA->createSequence('foo');
650
        $schemaA->createSequence('BAR');
651
        $schemaA->createSequence('Baz');
652
        $schemaA->createSequence('new');
653
654
        $schemaB = new Schema();
655
        $schemaB->createSequence('FOO');
656
        $schemaB->createSequence('Bar');
657
        $schemaB->createSequence('baz');
658
        $schemaB->createSequence('old');
659
660
        $c    = new Comparator();
661
        $diff = $c->compare($schemaA, $schemaB);
662
663
        $this->assertSchemaSequenceChangeCount($diff, 1, 0, 1);
664
    }
665
666
    public function testCompareColumnCompareCaseInsensitive() : void
667
    {
668
        $tableA = new Table('foo');
669
        $tableA->addColumn('id', 'integer');
670
671
        $tableB = new Table('foo');
672
        $tableB->addColumn('ID', 'integer');
673
674
        $c         = new Comparator();
675
        $tableDiff = $c->diffTable($tableA, $tableB);
676
677
        self::assertFalse($tableDiff);
678
    }
679
680
    public function testCompareIndexBasedOnPropertiesNotName() : void
681
    {
682
        $tableA = new Table('foo');
683
        $tableA->addColumn('id', 'integer');
684
        $tableA->addIndex(['id'], 'foo_bar_idx');
685
686
        $tableB = new Table('foo');
687
        $tableB->addColumn('ID', 'integer');
688
        $tableB->addIndex(['id'], 'bar_foo_idx');
689
690
        $c                                        = new Comparator();
691
        $tableDiff                                = new TableDiff('foo');
692
        $tableDiff->fromTable                     = $tableA;
693
        $tableDiff->renamedIndexes['foo_bar_idx'] = new Index('bar_foo_idx', ['id']);
694
695
        self::assertEquals(
696
            $tableDiff,
697
            $c->diffTable($tableA, $tableB)
698
        );
699
    }
700
701
    public function testCompareForeignKeyBasedOnPropertiesNotName() : void
702
    {
703
        $tableA = new Table('foo');
704
        $tableA->addColumn('id', 'integer');
705
        $tableA->addNamedForeignKeyConstraint('foo_constraint', 'bar', ['id'], ['id']);
706
707
        $tableB = new Table('foo');
708
        $tableB->addColumn('ID', 'integer');
709
        $tableB->addNamedForeignKeyConstraint('bar_constraint', 'bar', ['id'], ['id']);
710
711
        $c         = new Comparator();
712
        $tableDiff = $c->diffTable($tableA, $tableB);
713
714
        self::assertFalse($tableDiff);
715
    }
716
717
    public function testCompareForeignKeyRestrictNoActionAreTheSame() : void
718
    {
719
        $fk1 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'NO ACTION']);
720
        $fk2 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'RESTRICT']);
721
722
        $c = new Comparator();
723
        self::assertFalse($c->diffForeignKey($fk1, $fk2));
724
    }
725
726
    /**
727
     * @group DBAL-492
728
     */
729
    public function testCompareForeignKeyNamesUnqualifiedAsNoSchemaInformationIsAvailable() : void
730
    {
731
        $fk1 = new ForeignKeyConstraint(['foo'], 'foo.bar', ['baz'], 'fk1');
732
        $fk2 = new ForeignKeyConstraint(['foo'], 'baz.bar', ['baz'], 'fk1');
733
734
        $c = new Comparator();
735
        self::assertFalse($c->diffForeignKey($fk1, $fk2));
736
    }
737
738
    public function testDetectRenameColumn() : void
739
    {
740
        $tableA = new Table('foo');
741
        $tableA->addColumn('foo', 'integer');
742
743
        $tableB = new Table('foo');
744
        $tableB->addColumn('bar', 'integer');
745
746
        $c         = new Comparator();
747
        $tableDiff = $c->diffTable($tableA, $tableB);
748
749
        self::assertCount(0, $tableDiff->addedColumns);
750
        self::assertCount(0, $tableDiff->removedColumns);
751
        self::assertArrayHasKey('foo', $tableDiff->renamedColumns);
752
        self::assertEquals('bar', $tableDiff->renamedColumns['foo']->getName());
753
    }
754
755
    /**
756
     * You can easily have ambiguities in the column renaming. If these
757
     * are detected no renaming should take place, instead adding and dropping
758
     * should be used exclusively.
759
     *
760
     * @group DBAL-24
761
     */
762
    public function testDetectRenameColumnAmbiguous() : void
763
    {
764
        $tableA = new Table('foo');
765
        $tableA->addColumn('foo', 'integer');
766
        $tableA->addColumn('bar', 'integer');
767
768
        $tableB = new Table('foo');
769
        $tableB->addColumn('baz', 'integer');
770
771
        $c         = new Comparator();
772
        $tableDiff = $c->diffTable($tableA, $tableB);
773
774
        self::assertCount(1, $tableDiff->addedColumns, "'baz' should be added, not created through renaming!");
775
        self::assertArrayHasKey('baz', $tableDiff->addedColumns, "'baz' should be added, not created through renaming!");
776
        self::assertCount(2, $tableDiff->removedColumns, "'foo' and 'bar' should both be dropped, an ambiguity exists which one could be renamed to 'baz'.");
777
        self::assertArrayHasKey('foo', $tableDiff->removedColumns, "'foo' should be removed.");
778
        self::assertArrayHasKey('bar', $tableDiff->removedColumns, "'bar' should be removed.");
779
        self::assertCount(0, $tableDiff->renamedColumns, 'no renamings should take place.');
780
    }
781
782
    /**
783
     * @group DBAL-1063
784
     */
785
    public function testDetectRenameIndex() : void
786
    {
787
        $table1 = new Table('foo');
788
        $table1->addColumn('foo', 'integer');
789
790
        $table2 = clone $table1;
791
792
        $table1->addIndex(['foo'], 'idx_foo');
793
794
        $table2->addIndex(['foo'], 'idx_bar');
795
796
        $comparator = new Comparator();
797
        $tableDiff  = $comparator->diffTable($table1, $table2);
798
799
        self::assertCount(0, $tableDiff->addedIndexes);
800
        self::assertCount(0, $tableDiff->removedIndexes);
801
        self::assertArrayHasKey('idx_foo', $tableDiff->renamedIndexes);
802
        self::assertEquals('idx_bar', $tableDiff->renamedIndexes['idx_foo']->getName());
803
    }
804
805
    /**
806
     * You can easily have ambiguities in the index renaming. If these
807
     * are detected no renaming should take place, instead adding and dropping
808
     * should be used exclusively.
809
     *
810
     * @group DBAL-1063
811
     */
812
    public function testDetectRenameIndexAmbiguous() : void
813
    {
814
        $table1 = new Table('foo');
815
        $table1->addColumn('foo', 'integer');
816
817
        $table2 = clone $table1;
818
819
        $table1->addIndex(['foo'], 'idx_foo');
820
        $table1->addIndex(['foo'], 'idx_bar');
821
822
        $table2->addIndex(['foo'], 'idx_baz');
823
824
        $comparator = new Comparator();
825
        $tableDiff  = $comparator->diffTable($table1, $table2);
826
827
        self::assertCount(1, $tableDiff->addedIndexes);
828
        self::assertArrayHasKey('idx_baz', $tableDiff->addedIndexes);
829
        self::assertCount(2, $tableDiff->removedIndexes);
830
        self::assertArrayHasKey('idx_foo', $tableDiff->removedIndexes);
831
        self::assertArrayHasKey('idx_bar', $tableDiff->removedIndexes);
832
        self::assertCount(0, $tableDiff->renamedIndexes);
833
    }
834
835
    public function testDetectChangeIdentifierType() : void
836
    {
837
        $this->markTestSkipped('DBAL-2 was reopened, this test cannot work anymore.');
838
839
        $tableA = new Table('foo');
840
        $tableA->addColumn('id', 'integer', ['autoincrement' => false]);
841
842
        $tableB = new Table('foo');
843
        $tableB->addColumn('id', 'integer', ['autoincrement' => true]);
844
845
        $c         = new Comparator();
846
        $tableDiff = $c->diffTable($tableA, $tableB);
847
848
        self::assertInstanceOf(TableDiff::class, $tableDiff);
849
        self::assertArrayHasKey('id', $tableDiff->changedColumns);
850
    }
851
852
    /**
853
     * @group DBAL-105
854
     */
855
    public function testDiff() : void
856
    {
857
        $table = new Table('twitter_users');
858
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
859
        $table->addColumn('twitterId', 'integer');
860
        $table->addColumn('displayName', 'string');
861
        $table->setPrimaryKey(['id']);
862
863
        $newtable = new Table('twitter_users');
864
        $newtable->addColumn('id', 'integer', ['autoincrement' => true]);
865
        $newtable->addColumn('twitter_id', 'integer');
866
        $newtable->addColumn('display_name', 'string');
867
        $newtable->addColumn('logged_in_at', 'datetime');
868
        $newtable->setPrimaryKey(['id']);
869
870
        $c         = new Comparator();
871
        $tableDiff = $c->diffTable($table, $newtable);
872
873
        self::assertInstanceOf(TableDiff::class, $tableDiff);
874
        self::assertEquals(['twitterid', 'displayname'], array_keys($tableDiff->renamedColumns));
875
        self::assertEquals(['logged_in_at'], array_keys($tableDiff->addedColumns));
876
        self::assertCount(0, $tableDiff->removedColumns);
877
    }
878
879
    /**
880
     * @group DBAL-112
881
     */
882
    public function testChangedSequence() : void
883
    {
884
        $schema   = new Schema();
885
        $sequence = $schema->createSequence('baz');
0 ignored issues
show
Unused Code introduced by
The assignment to $sequence is dead and can be removed.
Loading history...
886
887
        $schemaNew = clone $schema;
888
        $schemaNew->getSequence('baz')->setAllocationSize(20);
889
890
        $c    = new Comparator();
891
        $diff = $c->compare($schema, $schemaNew);
892
893
        self::assertSame($diff->changedSequences[0], $schemaNew->getSequence('baz'));
894
    }
895
896
    /**
897
     * @group DBAL-106
898
     */
899
    public function testDiffDecimalWithNullPrecision() : void
900
    {
901
        $column = new Column('foo', Type::getType('decimal'));
902
        $column->setPrecision(null);
903
904
        $column2 = new Column('foo', Type::getType('decimal'));
905
906
        $c = new Comparator();
907
        self::assertEquals([], $c->diffColumn($column, $column2));
908
    }
909
910
    /**
911
     * @group DBAL-204
912
     */
913
    public function testFqnSchemaComparison() : void
914
    {
915
        $config = new SchemaConfig();
916
        $config->setName('foo');
917
918
        $oldSchema = new Schema([], [], $config);
919
        $oldSchema->createTable('bar');
920
921
        $newSchema = new Schema([], [], $config);
922
        $newSchema->createTable('foo.bar');
923
924
        $expected             = new SchemaDiff();
925
        $expected->fromSchema = $oldSchema;
926
927
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
928
    }
929
930
    /**
931
     * @group DBAL-669
932
     */
933
    public function testNamespacesComparison() : void
934
    {
935
        $config = new SchemaConfig();
936
        $config->setName('schemaName');
937
938
        $oldSchema = new Schema([], [], $config);
939
        $oldSchema->createTable('taz');
940
        $oldSchema->createTable('war.tab');
941
942
        $newSchema = new Schema([], [], $config);
943
        $newSchema->createTable('bar.tab');
944
        $newSchema->createTable('baz.tab');
945
        $newSchema->createTable('war.tab');
946
947
        $expected                = new SchemaDiff();
948
        $expected->fromSchema    = $oldSchema;
949
        $expected->newNamespaces = ['bar' => 'bar', 'baz' => 'baz'];
950
951
        $diff = Comparator::compareSchemas($oldSchema, $newSchema);
952
953
        self::assertEquals(['bar' => 'bar', 'baz' => 'baz'], $diff->newNamespaces);
954
        self::assertCount(2, $diff->newTables);
955
    }
956
957
    /**
958
     * @group DBAL-204
959
     */
960
    public function testFqnSchemaComparisonDifferentSchemaNameButSameTableNoDiff() : void
961
    {
962
        $config = new SchemaConfig();
963
        $config->setName('foo');
964
965
        $oldSchema = new Schema([], [], $config);
966
        $oldSchema->createTable('foo.bar');
967
968
        $newSchema = new Schema();
969
        $newSchema->createTable('bar');
970
971
        $expected             = new SchemaDiff();
972
        $expected->fromSchema = $oldSchema;
973
974
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
975
    }
976
977
    /**
978
     * @group DBAL-204
979
     */
980
    public function testFqnSchemaComparisonNoSchemaSame() : void
981
    {
982
        $config = new SchemaConfig();
983
        $config->setName('foo');
984
        $oldSchema = new Schema([], [], $config);
985
        $oldSchema->createTable('bar');
986
987
        $newSchema = new Schema();
988
        $newSchema->createTable('bar');
989
990
        $expected             = new SchemaDiff();
991
        $expected->fromSchema = $oldSchema;
992
993
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
994
    }
995
996
    /**
997
     * @group DDC-1657
998
     */
999
    public function testAutoIncrementSequences() : void
1000
    {
1001
        $oldSchema = new Schema();
1002
        $table     = $oldSchema->createTable('foo');
1003
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1004
        $table->setPrimaryKey(['id']);
1005
        $oldSchema->createSequence('foo_id_seq');
1006
1007
        $newSchema = new Schema();
1008
        $table     = $newSchema->createTable('foo');
1009
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1010
        $table->setPrimaryKey(['id']);
1011
1012
        $c    = new Comparator();
1013
        $diff = $c->compare($oldSchema, $newSchema);
1014
1015
        self::assertCount(0, $diff->removedSequences);
1016
    }
1017
1018
    /**
1019
     * Check that added autoincrement sequence is not populated in newSequences
1020
     *
1021
     * @group DBAL-562
1022
     */
1023
    public function testAutoIncrementNoSequences() : void
1024
    {
1025
        $oldSchema = new Schema();
1026
        $table     = $oldSchema->createTable('foo');
1027
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1028
        $table->setPrimaryKey(['id']);
1029
1030
        $newSchema = new Schema();
1031
        $table     = $newSchema->createTable('foo');
1032
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
1033
        $table->setPrimaryKey(['id']);
1034
        $newSchema->createSequence('foo_id_seq');
1035
1036
        $c    = new Comparator();
1037
        $diff = $c->compare($oldSchema, $newSchema);
1038
1039
        self::assertCount(0, $diff->newSequences);
1040
    }
1041
1042
    /**
1043
     * You can get multiple drops for a FK when a table referenced by a foreign
1044
     * key is deleted, as this FK is referenced twice, once on the orphanedForeignKeys
1045
     * array because of the dropped table, and once on changedTables array. We
1046
     * now check that the key is present once.
1047
     */
1048
    public function testAvoidMultipleDropForeignKey() : void
1049
    {
1050
        $oldSchema = new Schema();
1051
1052
        $tableA = $oldSchema->createTable('table_a');
1053
        $tableA->addColumn('id', 'integer');
1054
1055
        $tableB = $oldSchema->createTable('table_b');
1056
        $tableB->addColumn('id', 'integer');
1057
1058
        $tableC = $oldSchema->createTable('table_c');
1059
        $tableC->addColumn('id', 'integer');
1060
        $tableC->addColumn('table_a_id', 'integer');
1061
        $tableC->addColumn('table_b_id', 'integer');
1062
1063
        $tableC->addForeignKeyConstraint($tableA, ['table_a_id'], ['id']);
1064
        $tableC->addForeignKeyConstraint($tableB, ['table_b_id'], ['id']);
1065
1066
        $newSchema = new Schema();
1067
1068
        $tableB = $newSchema->createTable('table_b');
1069
        $tableB->addColumn('id', 'integer');
1070
1071
        $tableC = $newSchema->createTable('table_c');
1072
        $tableC->addColumn('id', 'integer');
1073
1074
        $comparator = new Comparator();
1075
        $schemaDiff = $comparator->compare($oldSchema, $newSchema);
1076
1077
        self::assertCount(1, $schemaDiff->changedTables['table_c']->removedForeignKeys);
1078
        self::assertCount(1, $schemaDiff->orphanedForeignKeys);
1079
    }
1080
1081
    public function testCompareChangedColumn() : void
1082
    {
1083
        $oldSchema = new Schema();
1084
1085
        $tableFoo = $oldSchema->createTable('foo');
1086
        $tableFoo->addColumn('id', 'integer');
1087
1088
        $newSchema = new Schema();
1089
        $table     = $newSchema->createTable('foo');
1090
        $table->addColumn('id', 'string');
1091
1092
        $expected                      = new SchemaDiff();
1093
        $expected->fromSchema          = $oldSchema;
1094
        $tableDiff                     = $expected->changedTables['foo'] = new TableDiff('foo');
1095
        $tableDiff->fromTable          = $tableFoo;
1096
        $columnDiff                    = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
1097
        $columnDiff->fromColumn        = $tableFoo->getColumn('id');
1098
        $columnDiff->changedProperties = ['type'];
1099
1100
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
1101
    }
1102
1103
    public function testCompareChangedBinaryColumn() : void
1104
    {
1105
        $oldSchema = new Schema();
1106
1107
        $tableFoo = $oldSchema->createTable('foo');
1108
        $tableFoo->addColumn('id', 'binary');
1109
1110
        $newSchema = new Schema();
1111
        $table     = $newSchema->createTable('foo');
1112
        $table->addColumn('id', 'binary', ['length' => 42, 'fixed' => true]);
1113
1114
        $expected                      = new SchemaDiff();
1115
        $expected->fromSchema          = $oldSchema;
1116
        $tableDiff                     = $expected->changedTables['foo'] = new TableDiff('foo');
1117
        $tableDiff->fromTable          = $tableFoo;
1118
        $columnDiff                    = $tableDiff->changedColumns['id'] = new ColumnDiff('id', $table->getColumn('id'));
1119
        $columnDiff->fromColumn        = $tableFoo->getColumn('id');
1120
        $columnDiff->changedProperties = ['length', 'fixed'];
1121
1122
        self::assertEquals($expected, Comparator::compareSchemas($oldSchema, $newSchema));
1123
    }
1124
1125
    /**
1126
     * @group DBAL-617
1127
     */
1128
    public function testCompareQuotedAndUnquotedForeignKeyColumns() : void
1129
    {
1130
        $fk1 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'NO ACTION']);
1131
        $fk2 = new ForeignKeyConstraint(['`foo`'], 'bar', ['`baz`'], 'fk1', ['onDelete' => 'NO ACTION']);
1132
1133
        $comparator = new Comparator();
1134
        $diff       = $comparator->diffForeignKey($fk1, $fk2);
1135
1136
        self::assertFalse($diff);
1137
    }
1138
1139
    public function assertSchemaTableChangeCount(SchemaDiff $diff, int $newTableCount = 0, int $changeTableCount = 0, int $removeTableCount = 0) : void
1140
    {
1141
        self::assertCount($newTableCount, $diff->newTables);
1142
        self::assertCount($changeTableCount, $diff->changedTables);
1143
        self::assertCount($removeTableCount, $diff->removedTables);
1144
    }
1145
1146
    public function assertSchemaSequenceChangeCount(
1147
        SchemaDiff $diff,
1148
        int $newSequenceCount = 0,
1149
        int $changeSequenceCount = 0,
1150
        int $removeSequenceCount = 0
1151
    ) : void {
1152
        self::assertCount($newSequenceCount, $diff->newSequences, 'Expected number of new sequences is wrong.');
1153
        self::assertCount($changeSequenceCount, $diff->changedSequences, 'Expected number of changed sequences is wrong.');
1154
        self::assertCount($removeSequenceCount, $diff->removedSequences, 'Expected number of removed sequences is wrong.');
1155
    }
1156
1157
    public function testDiffColumnPlatformOptions() : void
1158
    {
1159
        $column1 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'bar' => 'bar']]);
1160
        $column2 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'foobar' => 'foobar']]);
1161
        $column3 = new Column('foo', Type::getType('string'), ['platformOptions' => ['foo' => 'foo', 'bar' => 'rab']]);
1162
        $column4 = new Column('foo', Type::getType('string'));
1163
1164
        $comparator = new Comparator();
1165
1166
        self::assertEquals([], $comparator->diffColumn($column1, $column2));
1167
        self::assertEquals([], $comparator->diffColumn($column2, $column1));
1168
        self::assertEquals(['bar'], $comparator->diffColumn($column1, $column3));
1169
        self::assertEquals(['bar'], $comparator->diffColumn($column3, $column1));
1170
        self::assertEquals([], $comparator->diffColumn($column1, $column4));
1171
        self::assertEquals([], $comparator->diffColumn($column4, $column1));
1172
    }
1173
1174
    public function testComplexDiffColumn() : void
1175
    {
1176
        $column1 = new Column('foo', Type::getType('string'), [
1177
            'platformOptions' => ['foo' => 'foo'],
1178
            'customSchemaOptions' => ['foo' => 'bar'],
1179
        ]);
1180
1181
        $column2 = new Column('foo', Type::getType('string'), [
1182
            'platformOptions' => ['foo' => 'bar'],
1183
        ]);
1184
1185
        $comparator = new Comparator();
1186
1187
        self::assertEquals([], $comparator->diffColumn($column1, $column2));
1188
        self::assertEquals([], $comparator->diffColumn($column2, $column1));
1189
    }
1190
1191
    /**
1192
     * @group DBAL-669
1193
     */
1194
    public function testComparesNamespaces() : void
1195
    {
1196
        $comparator = new Comparator();
1197
        $fromSchema = $this->getMockBuilder(Schema::class)
1198
            ->onlyMethods(['getNamespaces', 'hasNamespace'])
1199
            ->getMock();
1200
        $toSchema   = $this->getMockBuilder(Schema::class)
1201
            ->onlyMethods(['getNamespaces', 'hasNamespace'])
1202
            ->getMock();
1203
1204
        $fromSchema->expects($this->once())
1205
            ->method('getNamespaces')
1206
            ->will($this->returnValue(['foo', 'bar']));
1207
1208
        $fromSchema->expects($this->at(0))
1209
            ->method('hasNamespace')
1210
            ->with('bar')
1211
            ->will($this->returnValue(true));
1212
1213
        $fromSchema->expects($this->at(1))
1214
            ->method('hasNamespace')
1215
            ->with('baz')
1216
            ->will($this->returnValue(false));
1217
1218
        $toSchema->expects($this->once())
1219
            ->method('getNamespaces')
1220
            ->will($this->returnValue(['bar', 'baz']));
1221
1222
        $toSchema->expects($this->at(1))
1223
            ->method('hasNamespace')
1224
            ->with('foo')
1225
            ->will($this->returnValue(false));
1226
1227
        $toSchema->expects($this->at(2))
1228
            ->method('hasNamespace')
1229
            ->with('bar')
1230
            ->will($this->returnValue(true));
1231
1232
        $expected                    = new SchemaDiff();
1233
        $expected->fromSchema        = $fromSchema;
1234
        $expected->newNamespaces     = ['baz' => 'baz'];
1235
        $expected->removedNamespaces = ['foo' => 'foo'];
1236
1237
        self::assertEquals($expected, $comparator->compare($fromSchema, $toSchema));
1238
    }
1239
1240
    public function testCompareGuidColumns() : void
1241
    {
1242
        $comparator = new Comparator();
1243
1244
        $column1 = new Column('foo', Type::getType('guid'), ['comment' => 'GUID 1']);
1245
        $column2 = new Column(
1246
            'foo',
1247
            Type::getType('guid'),
1248
            ['notnull' => false, 'length' => '36', 'fixed' => true, 'default' => 'NEWID()', 'comment' => 'GUID 2.']
1249
        );
1250
1251
        self::assertEquals(['notnull', 'default', 'comment'], $comparator->diffColumn($column1, $column2));
1252
        self::assertEquals(['notnull', 'default', 'comment'], $comparator->diffColumn($column2, $column1));
1253
    }
1254
1255
    /**
1256
     * @group DBAL-1009
1257
     * @dataProvider getCompareColumnComments
1258
     */
1259
    public function testCompareColumnComments(?string $comment1, ?string $comment2, bool $equals) : void
1260
    {
1261
        $column1 = new Column('foo', Type::getType('integer'), ['comment' => $comment1]);
1262
        $column2 = new Column('foo', Type::getType('integer'), ['comment' => $comment2]);
1263
1264
        $comparator = new Comparator();
1265
1266
        $expectedDiff = $equals ? [] : ['comment'];
1267
1268
        $actualDiff = $comparator->diffColumn($column1, $column2);
1269
1270
        self::assertSame($expectedDiff, $actualDiff);
1271
1272
        $actualDiff = $comparator->diffColumn($column2, $column1);
1273
1274
        self::assertSame($expectedDiff, $actualDiff);
1275
    }
1276
1277
    /**
1278
     * @return mixed[][]
1279
     */
1280
    public static function getCompareColumnComments() : iterable
1281
    {
1282
        return [
1283
            [null, null, true],
1284
            ['', '', true],
1285
            [' ', ' ', true],
1286
            ['0', '0', true],
1287
            ['foo', 'foo', true],
1288
1289
            [null, '', true],
1290
            [null, ' ', false],
1291
            [null, '0', false],
1292
            [null, 'foo', false],
1293
1294
            ['', ' ', false],
1295
            ['', '0', false],
1296
            ['', 'foo', false],
1297
1298
            [' ', '0', false],
1299
            [' ', 'foo', false],
1300
1301
            ['0', 'foo', false],
1302
        ];
1303
    }
1304
1305
    public function testForeignKeyRemovalWithRenamedLocalColumn() : void
1306
    {
1307
        $fromSchema = new Schema([
1308
            'table1' => new Table(
1309
                'table1',
1310
                [
1311
                    'id' => new Column('id', Type::getType('integer')),
1312
                ]
1313
            ),
1314
            'table2' => new Table(
1315
                'table2',
1316
                [
1317
                    'id' => new Column('id', Type::getType('integer')),
1318
                    'id_table1' => new Column('id_table1', Type::getType('integer')),
1319
                ],
1320
                [],
1321
                [
1322
                    new ForeignKeyConstraint(['id_table1'], 'table1', ['id'], 'fk_table2_table1'),
1323
                ]
1324
            ),
1325
        ]);
1326
        $toSchema   = new Schema([
1327
            'table2' => new Table(
1328
                'table2',
1329
                [
1330
                    'id' => new Column('id', Type::getType('integer')),
1331
                    'id_table3' => new Column('id_table3', Type::getType('integer')),
1332
                ],
1333
                [],
1334
                [
1335
                    new ForeignKeyConstraint(['id_table3'], 'table3', ['id'], 'fk_table2_table3'),
1336
                ]
1337
            ),
1338
            'table3' => new Table(
1339
                'table3',
1340
                [
1341
                    'id' => new Column('id', Type::getType('integer')),
1342
                ]
1343
            ),
1344
        ]);
1345
        $actual     = Comparator::compareSchemas($fromSchema, $toSchema);
1346
        self::assertArrayHasKey('table2', $actual->changedTables);
1347
        self::assertCount(1, $actual->orphanedForeignKeys);
1348
        self::assertEquals('fk_table2_table1', $actual->orphanedForeignKeys[0]->getName());
1349
        self::assertCount(1, $actual->changedTables['table2']->addedForeignKeys, 'FK to table3 should be added.');
1350
        self::assertEquals('table3', $actual->changedTables['table2']->addedForeignKeys[0]->getForeignTableName());
1351
    }
1352
}
1353