Passed
Pull Request — master (#3086)
by Michael
03:33
created

SchemaManagerFunctionalTestCase   F

Complexity

Total Complexity 115

Size/Duplication

Total Lines 1457
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 115
dl 0
loc 1457
rs 0.6314
c 0
b 0
f 0

58 Methods

Rating   Name   Duplication   Size   Complexity  
B testDoesNotListIndexesImplicitlyCreatedByForeignKeys() 0 25 2
A testComparatorShouldReturnFalseWhenLegacyJsonArrayColumnHasComment() 0 11 1
A removeJsonArrayTable() 0 4 2
A testComparatorShouldAddCommentToLegacyJsonArrayTypeThatDoesNotHaveIt() 0 16 2
A testComparatorShouldNotAddCommentToJsonTypeSinceItIsTheDefaultNow() 0 15 2
A testComparatorShouldModifyOnlyTheCommentWhenUpdatingFromJsonArrayTypeOnLegacyPlatforms() 0 22 2
A getAlterColumnComment() 0 15 1
A testListForeignKeysComposite() 0 22 2
A testComparatorShouldReturnAllChangesWhenUsingLegacyJsonArrayType() 0 16 2
B testListTableDetailsWithFullQualifiedTableName() 0 37 2
B testCreateAndListSequences() 0 34 3
A testListTableWithBinary() 0 19 1
A commentsProvider() 0 11 1
A testCommentStringsAreQuoted() 0 16 4
A testColumnDefaultLifecycle() 0 49 1
A testComparatorShouldReturnAllChangesWhenUsingLegacyJsonArrayTypeEvenWhenPlatformHasJsonSupport() 0 16 2
A testCommentNotDuplicated() 0 20 2
A testExtractDoctrineTypeFromComment() 0 5 1
B testAlterColumnComment() 0 41 4
A testDropAndCreateIndex() 0 14 1
A testAutoincrementDetection() 0 16 2
A getCreateExampleViewSql() 0 3 1
A testCreateAndListViews() 0 16 2
A createListTableColumns() 0 13 1
A getPlatformName() 0 7 1
A testDiffListTableColumns() 0 14 2
B testUpdateSchemaWithForeignKeyRenaming() 0 40 2
B testCreateTableWithForeignKeys() 0 26 2
B testAutomaticallyAppendCommentOnMarkedColumns() 0 23 4
A testCommentHintOnDateIntervalTypeColumn() 0 20 4
A testCreateSchema() 0 6 1
B testListTableColumnsDispatchEvent() 0 24 1
B testComparisonWithAutoDetectedSequenceDefinition() 0 28 2
A testListNamespaceNames() 0 18 3
A assertHasTable() 0 10 3
A testListDatabases() 0 12 2
B testAlterTableScenario() 0 84 3
A testDropAndCreateSequence() 0 11 2
A testListTableColumns() 0 69 1
B testListSequences() 0 26 4
A hasElementWithName() 0 10 1
A testListTableColumnsWithFixedStringColumn() 0 15 1
A testTableInNamespace() 0 22 3
B testRenameIndexUsedInForeignKeyConstraint() 0 36 2
B testListTableIndexes() 0 26 1
A getTestCompositeTable() 0 9 1
B testGetColumnComment() 0 35 4
A tearDown() 0 12 2
B testDropsDatabaseWithActiveConnections() 0 32 4
B testChangeColumnsTypeWithDefaultValue() 0 35 1
B testListForeignKeys() 0 26 3
A getTestTable() 0 9 1
B testListTableIndexesDispatchEvent() 0 26 1
A testListTableWithBlob() 0 14 1
A testAutoincrementDetectionMulticolumns() 0 17 2
A createTestTable() 0 9 1
A setUp() 0 11 2
A testListTables() 0 21 3

How to fix   Complexity   

Complex Class

Complex classes like SchemaManagerFunctionalTestCase often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SchemaManagerFunctionalTestCase, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional\Schema;
4
5
use Doctrine\Common\EventManager;
6
use Doctrine\DBAL\DBALException;
7
use Doctrine\DBAL\Events;
8
use Doctrine\DBAL\Platforms\OraclePlatform;
9
use Doctrine\DBAL\Schema\Column;
10
use Doctrine\DBAL\Schema\ColumnDiff;
11
use Doctrine\DBAL\Schema\Comparator;
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 function array_filter;
18
use function array_keys;
19
use function array_map;
20
use function array_search;
21
use function array_values;
22
use function count;
23
use function current;
24
use function end;
25
use function explode;
26
use function get_class;
27
use function in_array;
28
use function str_replace;
29
use function strlen;
30
use function strtolower;
31
use function substr;
32
33
class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTestCase
34
{
35
    /**
36
     * @var \Doctrine\DBAL\Schema\AbstractSchemaManager
37
     */
38
    protected $_sm;
39
40
    protected function getPlatformName()
41
    {
42
        $class = get_class($this);
43
        $e = explode('\\', $class);
44
        $testClass = end($e);
45
        $dbms = strtolower(str_replace('SchemaManagerTest', null, $testClass));
46
        return $dbms;
47
    }
48
49
    protected function setUp()
50
    {
51
        parent::setUp();
52
53
        $dbms = $this->getPlatformName();
54
55
        if ($this->_conn->getDatabasePlatform()->getName() !== $dbms) {
56
            $this->markTestSkipped(get_class($this) . ' requires the use of ' . $dbms);
57
        }
58
59
        $this->_sm = $this->_conn->getSchemaManager();
60
    }
61
62
63
    protected function tearDown()
64
    {
65
        parent::tearDown();
66
67
        $this->_sm->tryMethod('dropTable', 'testschema.my_table_in_namespace');
68
69
        //TODO: SchemaDiff does not drop removed namespaces?
70
        try {
71
            //sql server versions below 2016 do not support 'IF EXISTS' so we have to catch the exception here
72
            $this->_conn->exec('DROP SCHEMA testschema');
73
        } catch (DBALException $e) {
74
            return;
75
        }
76
    }
77
78
79
    /**
80
     * @group DBAL-1220
81
     */
82
    public function testDropsDatabaseWithActiveConnections()
83
    {
84
        if (! $this->_sm->getDatabasePlatform()->supportsCreateDropDatabase()) {
85
            $this->markTestSkipped('Cannot drop Database client side with this Driver.');
86
        }
87
88
        $this->_sm->dropAndCreateDatabase('test_drop_database');
89
90
        $knownDatabases = $this->_sm->listDatabases();
91
        if ($this->_conn->getDatabasePlatform() instanceof OraclePlatform) {
92
            self::assertContains('TEST_DROP_DATABASE', $knownDatabases);
93
        } else {
94
            self::assertContains('test_drop_database', $knownDatabases);
95
        }
96
97
        $params = $this->_conn->getParams();
98
        if ($this->_conn->getDatabasePlatform() instanceof OraclePlatform) {
99
            $params['user'] = 'test_drop_database';
100
        } else {
101
            $params['dbname'] = 'test_drop_database';
102
        }
103
104
        $user = $params['user'] ?? null;
105
        $password = $params['password'] ?? null;
106
107
        $connection = $this->_conn->getDriver()->connect($params, $user, $password);
108
109
        self::assertInstanceOf('Doctrine\DBAL\Driver\Connection', $connection);
110
111
        $this->_sm->dropDatabase('test_drop_database');
112
113
        self::assertNotContains('test_drop_database', $this->_sm->listDatabases());
114
    }
115
116
    /**
117
     * @group DBAL-195
118
     */
119
    public function testDropAndCreateSequence()
120
    {
121
        if ( ! $this->_conn->getDatabasePlatform()->supportsSequences()) {
122
            $this->markTestSkipped($this->_conn->getDriver()->getName().' does not support sequences.');
123
        }
124
125
        $name = 'dropcreate_sequences_test_seq';
126
127
        $this->_sm->dropAndCreateSequence(new Sequence($name, 20, 10));
128
129
        self::assertTrue($this->hasElementWithName($this->_sm->listSequences(), $name));
130
    }
131
132
    private function hasElementWithName(array $items, string $name) : bool
133
    {
134
        $filteredList = array_filter(
135
            $items,
136
            function (\Doctrine\DBAL\Schema\AbstractAsset $item) use ($name) : bool {
137
                return $item->getShortestName($item->getNamespaceName()) === $name;
138
            }
139
        );
140
141
        return count($filteredList) === 1;
142
    }
143
144
    public function testListSequences()
145
    {
146
        if (! $this->_conn->getDatabasePlatform()->supportsSequences()) {
147
            $this->markTestSkipped($this->_conn->getDriver()->getName() . ' does not support sequences.');
148
        }
149
150
        $sequence = new Sequence('list_sequences_test_seq', 20, 10);
151
        $this->_sm->createSequence($sequence);
152
153
        $sequences = $this->_sm->listSequences();
154
155
        self::assertInternalType('array', $sequences, 'listSequences() should return an array.');
156
157
        $foundSequence = null;
158
        foreach ($sequences as $sequence) {
159
            self::assertInstanceOf(Sequence::class, $sequence, 'Array elements of listSequences() should be Sequence instances.');
160
            if (strtolower($sequence->getName()) !== 'list_sequences_test_seq') {
161
                continue;
162
            }
163
164
            $foundSequence = $sequence;
165
        }
166
167
        self::assertNotNull($foundSequence, "Sequence with name 'list_sequences_test_seq' was not found.");
168
        self::assertSame(20, $foundSequence->getAllocationSize(), 'Allocation Size is expected to be 20.');
169
        self::assertSame(10, $foundSequence->getInitialValue(), 'Initial Value is expected to be 10.');
170
    }
171
172
    public function testListDatabases()
173
    {
174
        if (!$this->_sm->getDatabasePlatform()->supportsCreateDropDatabase()) {
175
            $this->markTestSkipped('Cannot drop Database client side with this Driver.');
176
        }
177
178
        $this->_sm->dropAndCreateDatabase('test_create_database');
179
        $databases = $this->_sm->listDatabases();
180
181
        $databases = array_map('strtolower', $databases);
182
183
        self::assertContains('test_create_database', $databases);
184
    }
185
186
    /**
187
     * @group DBAL-1058
188
     */
189
    public function testListNamespaceNames()
190
    {
191
        if (!$this->_sm->getDatabasePlatform()->supportsSchemas()) {
192
            $this->markTestSkipped('Platform does not support schemas.');
193
        }
194
195
        // Currently dropping schemas is not supported, so we have to workaround here.
196
        $namespaces = $this->_sm->listNamespaceNames();
197
        $namespaces = array_map('strtolower', $namespaces);
198
199
        if (!in_array('test_create_schema', $namespaces)) {
200
            $this->_conn->executeUpdate($this->_sm->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema'));
201
202
            $namespaces = $this->_sm->listNamespaceNames();
203
            $namespaces = array_map('strtolower', $namespaces);
204
        }
205
206
        self::assertContains('test_create_schema', $namespaces);
207
    }
208
209
    public function testListTables()
210
    {
211
        $this->createTestTable('list_tables_test');
212
        $tables = $this->_sm->listTables();
213
214
        self::assertInternalType('array', $tables);
215
        self::assertTrue(count($tables) > 0, "List Tables has to find at least one table named 'list_tables_test'.");
216
217
        $foundTable = false;
218
        foreach ($tables as $table) {
219
            self::assertInstanceOf('Doctrine\DBAL\Schema\Table', $table);
220
            if (strtolower($table->getName()) == 'list_tables_test') {
221
                $foundTable = true;
222
223
                self::assertTrue($table->hasColumn('id'));
224
                self::assertTrue($table->hasColumn('test'));
225
                self::assertTrue($table->hasColumn('foreign_key_test'));
226
            }
227
        }
228
229
        self::assertTrue( $foundTable , "The 'list_tables_test' table has to be found.");
230
    }
231
232
    public function createListTableColumns()
233
    {
234
        $table = new Table('list_table_columns');
235
        $table->addColumn('id', 'integer', array('notnull' => true));
236
        $table->addColumn('test', 'string', array('length' => 255, 'notnull' => false, 'default' => 'expected default'));
237
        $table->addColumn('foo', 'text', array('notnull' => true));
238
        $table->addColumn('bar', 'decimal', array('precision' => 10, 'scale' => 4, 'notnull' => false));
239
        $table->addColumn('baz1', 'datetime');
240
        $table->addColumn('baz2', 'time');
241
        $table->addColumn('baz3', 'date');
242
        $table->setPrimaryKey(array('id'));
243
244
        return $table;
245
    }
246
247
    public function testListTableColumns()
248
    {
249
        $table = $this->createListTableColumns();
250
251
        $this->_sm->dropAndCreateTable($table);
252
253
        $columns = $this->_sm->listTableColumns('list_table_columns');
254
        $columnsKeys = array_keys($columns);
255
256
        self::assertArrayHasKey('id', $columns);
257
        self::assertEquals(0, array_search('id', $columnsKeys));
258
        self::assertEquals('id',   strtolower($columns['id']->getname()));
259
        self::assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['id']->gettype());
260
        self::assertEquals(false,  $columns['id']->getunsigned());
261
        self::assertEquals(true,   $columns['id']->getnotnull());
262
        self::assertEquals(null,   $columns['id']->getdefault());
263
        self::assertInternalType('array',  $columns['id']->getPlatformOptions());
264
265
        self::assertArrayHasKey('test', $columns);
266
        self::assertEquals(1, array_search('test', $columnsKeys));
267
        self::assertEquals('test', strtolower($columns['test']->getname()));
268
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['test']->gettype());
269
        self::assertEquals(255,    $columns['test']->getlength());
270
        self::assertEquals(false,  $columns['test']->getfixed());
271
        self::assertEquals(false,  $columns['test']->getnotnull());
272
        self::assertEquals('expected default',   $columns['test']->getdefault());
273
        self::assertInternalType('array',  $columns['test']->getPlatformOptions());
274
275
        self::assertEquals('foo',  strtolower($columns['foo']->getname()));
276
        self::assertEquals(2, array_search('foo', $columnsKeys));
277
        self::assertInstanceOf('Doctrine\DBAL\Types\TextType', $columns['foo']->gettype());
278
        self::assertEquals(false,  $columns['foo']->getunsigned());
279
        self::assertEquals(false,  $columns['foo']->getfixed());
280
        self::assertEquals(true,   $columns['foo']->getnotnull());
281
        self::assertEquals(null,   $columns['foo']->getdefault());
282
        self::assertInternalType('array',  $columns['foo']->getPlatformOptions());
283
284
        self::assertEquals('bar',  strtolower($columns['bar']->getname()));
285
        self::assertEquals(3, array_search('bar', $columnsKeys));
286
        self::assertInstanceOf('Doctrine\DBAL\Types\DecimalType', $columns['bar']->gettype());
287
        self::assertEquals(null,   $columns['bar']->getlength());
288
        self::assertEquals(10,     $columns['bar']->getprecision());
289
        self::assertEquals(4,      $columns['bar']->getscale());
290
        self::assertEquals(false,  $columns['bar']->getunsigned());
291
        self::assertEquals(false,  $columns['bar']->getfixed());
292
        self::assertEquals(false,  $columns['bar']->getnotnull());
293
        self::assertEquals(null,   $columns['bar']->getdefault());
294
        self::assertInternalType('array',  $columns['bar']->getPlatformOptions());
295
296
        self::assertEquals('baz1', strtolower($columns['baz1']->getname()));
297
        self::assertEquals(4, array_search('baz1', $columnsKeys));
298
        self::assertInstanceOf('Doctrine\DBAL\Types\DateTimeType', $columns['baz1']->gettype());
299
        self::assertEquals(true,   $columns['baz1']->getnotnull());
300
        self::assertEquals(null,   $columns['baz1']->getdefault());
301
        self::assertInternalType('array',  $columns['baz1']->getPlatformOptions());
302
303
        self::assertEquals('baz2', strtolower($columns['baz2']->getname()));
304
        self::assertEquals(5, array_search('baz2', $columnsKeys));
305
        self::assertContains($columns['baz2']->gettype()->getName(), array('time', 'date', 'datetime'));
306
        self::assertEquals(true,   $columns['baz2']->getnotnull());
307
        self::assertEquals(null,   $columns['baz2']->getdefault());
308
        self::assertInternalType('array',  $columns['baz2']->getPlatformOptions());
309
310
        self::assertEquals('baz3', strtolower($columns['baz3']->getname()));
311
        self::assertEquals(6, array_search('baz3', $columnsKeys));
312
        self::assertContains($columns['baz3']->gettype()->getName(), array('time', 'date', 'datetime'));
313
        self::assertEquals(true,   $columns['baz3']->getnotnull());
314
        self::assertEquals(null,   $columns['baz3']->getdefault());
315
        self::assertInternalType('array',  $columns['baz3']->getPlatformOptions());
316
    }
317
318
    /**
319
     * @group DBAL-1078
320
     */
321
    public function testListTableColumnsWithFixedStringColumn()
322
    {
323
        $tableName = 'test_list_table_fixed_string';
324
325
        $table = new Table($tableName);
326
        $table->addColumn('column_char', 'string', array('fixed' => true, 'length' => 2));
327
328
        $this->_sm->createTable($table);
329
330
        $columns = $this->_sm->listTableColumns($tableName);
331
332
        self::assertArrayHasKey('column_char', $columns);
333
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['column_char']->getType());
334
        self::assertTrue($columns['column_char']->getFixed());
335
        self::assertSame(2, $columns['column_char']->getLength());
336
    }
337
338
    public function testListTableColumnsDispatchEvent()
339
    {
340
        $table = $this->createListTableColumns();
341
342
        $this->_sm->dropAndCreateTable($table);
343
344
        $listenerMock = $this
345
            ->getMockBuilder('ListTableColumnsDispatchEventListener')
346
            ->setMethods(['onSchemaColumnDefinition'])
347
            ->getMock();
348
        $listenerMock
349
            ->expects($this->exactly(7))
350
            ->method('onSchemaColumnDefinition');
351
352
        $oldEventManager = $this->_sm->getDatabasePlatform()->getEventManager();
353
354
        $eventManager = new EventManager();
355
        $eventManager->addEventListener(array(Events::onSchemaColumnDefinition), $listenerMock);
356
357
        $this->_sm->getDatabasePlatform()->setEventManager($eventManager);
358
359
        $this->_sm->listTableColumns('list_table_columns');
360
361
        $this->_sm->getDatabasePlatform()->setEventManager($oldEventManager);
362
    }
363
364
    public function testListTableIndexesDispatchEvent()
365
    {
366
        $table = $this->getTestTable('list_table_indexes_test');
367
        $table->addUniqueIndex(array('test'), 'test_index_name');
368
        $table->addIndex(array('id', 'test'), 'test_composite_idx');
369
370
        $this->_sm->dropAndCreateTable($table);
371
372
        $listenerMock = $this
373
            ->getMockBuilder('ListTableIndexesDispatchEventListener')
374
            ->setMethods(['onSchemaIndexDefinition'])
375
            ->getMock();
376
        $listenerMock
377
            ->expects($this->exactly(3))
378
            ->method('onSchemaIndexDefinition');
379
380
        $oldEventManager = $this->_sm->getDatabasePlatform()->getEventManager();
381
382
        $eventManager = new EventManager();
383
        $eventManager->addEventListener(array(Events::onSchemaIndexDefinition), $listenerMock);
384
385
        $this->_sm->getDatabasePlatform()->setEventManager($eventManager);
386
387
        $this->_sm->listTableIndexes('list_table_indexes_test');
388
389
        $this->_sm->getDatabasePlatform()->setEventManager($oldEventManager);
390
    }
391
392
    public function testDiffListTableColumns()
393
    {
394
        if ($this->_sm->getDatabasePlatform()->getName() == 'oracle') {
395
            $this->markTestSkipped('Does not work with Oracle, since it cannot detect DateTime, Date and Time differenecs (at the moment).');
396
        }
397
398
        $offlineTable = $this->createListTableColumns();
399
        $this->_sm->dropAndCreateTable($offlineTable);
400
        $onlineTable = $this->_sm->listTableDetails('list_table_columns');
401
402
        $comparator = new \Doctrine\DBAL\Schema\Comparator();
403
        $diff = $comparator->diffTable($offlineTable, $onlineTable);
404
405
        self::assertFalse($diff, "No differences should be detected with the offline vs online schema.");
406
    }
407
408
    public function testListTableIndexes()
409
    {
410
        $table = $this->getTestCompositeTable('list_table_indexes_test');
411
        $table->addUniqueIndex(array('test'), 'test_index_name');
412
        $table->addIndex(array('id', 'test'), 'test_composite_idx');
413
414
        $this->_sm->dropAndCreateTable($table);
415
416
        $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test');
417
418
        self::assertEquals(3, count($tableIndexes));
419
420
        self::assertArrayHasKey('primary', $tableIndexes, 'listTableIndexes() has to return a "primary" array key.');
421
        self::assertEquals(array('id', 'other_id'), array_map('strtolower', $tableIndexes['primary']->getColumns()));
422
        self::assertTrue($tableIndexes['primary']->isUnique());
423
        self::assertTrue($tableIndexes['primary']->isPrimary());
424
425
        self::assertEquals('test_index_name', strtolower($tableIndexes['test_index_name']->getName()));
426
        self::assertEquals(array('test'), array_map('strtolower', $tableIndexes['test_index_name']->getColumns()));
427
        self::assertTrue($tableIndexes['test_index_name']->isUnique());
428
        self::assertFalse($tableIndexes['test_index_name']->isPrimary());
429
430
        self::assertEquals('test_composite_idx', strtolower($tableIndexes['test_composite_idx']->getName()));
431
        self::assertEquals(array('id', 'test'), array_map('strtolower', $tableIndexes['test_composite_idx']->getColumns()));
432
        self::assertFalse($tableIndexes['test_composite_idx']->isUnique());
433
        self::assertFalse($tableIndexes['test_composite_idx']->isPrimary());
434
    }
435
436
    public function testDropAndCreateIndex()
437
    {
438
        $table = $this->getTestTable('test_create_index');
439
        $table->addUniqueIndex(array('test'), 'test');
440
        $this->_sm->dropAndCreateTable($table);
441
442
        $this->_sm->dropAndCreateIndex($table->getIndex('test'), $table);
443
        $tableIndexes = $this->_sm->listTableIndexes('test_create_index');
444
        self::assertInternalType('array', $tableIndexes);
445
446
        self::assertEquals('test',        strtolower($tableIndexes['test']->getName()));
447
        self::assertEquals(array('test'), array_map('strtolower', $tableIndexes['test']->getColumns()));
448
        self::assertTrue($tableIndexes['test']->isUnique());
449
        self::assertFalse($tableIndexes['test']->isPrimary());
450
    }
451
452
    public function testCreateTableWithForeignKeys()
453
    {
454
        if(!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
455
            $this->markTestSkipped('Platform does not support foreign keys.');
456
        }
457
458
        $tableB = $this->getTestTable('test_foreign');
459
460
        $this->_sm->dropAndCreateTable($tableB);
461
462
        $tableA = $this->getTestTable('test_create_fk');
463
        $tableA->addForeignKeyConstraint('test_foreign', array('foreign_key_test'), array('id'));
464
465
        $this->_sm->dropAndCreateTable($tableA);
466
467
        $fkTable = $this->_sm->listTableDetails('test_create_fk');
468
        $fkConstraints = $fkTable->getForeignKeys();
469
        self::assertEquals(1, count($fkConstraints), "Table 'test_create_fk1' has to have one foreign key.");
470
471
        $fkConstraint = current($fkConstraints);
472
        self::assertInstanceOf('\Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkConstraint);
473
        self::assertEquals('test_foreign',             strtolower($fkConstraint->getForeignTableName()));
474
        self::assertEquals(array('foreign_key_test'),  array_map('strtolower', $fkConstraint->getColumns()));
475
        self::assertEquals(array('id'),                array_map('strtolower', $fkConstraint->getForeignColumns()));
476
477
        self::assertTrue($fkTable->columnsAreIndexed($fkConstraint->getColumns()), "The columns of a foreign key constraint should always be indexed.");
478
    }
479
480
    public function testListForeignKeys()
481
    {
482
        if(!$this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
483
            $this->markTestSkipped('Does not support foreign key constraints.');
484
        }
485
486
        $this->createTestTable('test_create_fk1');
487
        $this->createTestTable('test_create_fk2');
488
489
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
490
            array('foreign_key_test'), 'test_create_fk2', array('id'), 'foreign_key_test_fk', array('onDelete' => 'CASCADE')
491
        );
492
493
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk1');
494
495
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk1');
496
497
        self::assertEquals(1, count($fkeys), "Table 'test_create_fk1' has to have one foreign key.");
498
499
        self::assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
500
        self::assertEquals(array('foreign_key_test'),  array_map('strtolower', $fkeys[0]->getLocalColumns()));
501
        self::assertEquals(array('id'),                array_map('strtolower', $fkeys[0]->getForeignColumns()));
502
        self::assertEquals('test_create_fk2',          strtolower($fkeys[0]->getForeignTableName()));
503
504
        if($fkeys[0]->hasOption('onDelete')) {
505
            self::assertEquals('CASCADE', $fkeys[0]->getOption('onDelete'));
506
        }
507
    }
508
509
    protected function getCreateExampleViewSql()
510
    {
511
        $this->markTestSkipped('No Create Example View SQL was defined for this SchemaManager');
512
    }
513
514
    public function testCreateSchema()
515
    {
516
        $this->createTestTable('test_table');
517
518
        $schema = $this->_sm->createSchema();
519
        self::assertTrue($schema->hasTable('test_table'));
520
    }
521
522
    public function testAlterTableScenario()
523
    {
524
        if(!$this->_sm->getDatabasePlatform()->supportsAlterTable()) {
525
            $this->markTestSkipped('Alter Table is not supported by this platform.');
526
        }
527
528
        $alterTable = $this->createTestTable('alter_table');
529
        $this->createTestTable('alter_table_foreign');
530
531
        $table = $this->_sm->listTableDetails('alter_table');
532
        self::assertTrue($table->hasColumn('id'));
533
        self::assertTrue($table->hasColumn('test'));
534
        self::assertTrue($table->hasColumn('foreign_key_test'));
535
        self::assertEquals(0, count($table->getForeignKeys()));
536
        self::assertEquals(1, count($table->getIndexes()));
537
538
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
539
        $tableDiff->fromTable = $alterTable;
540
        $tableDiff->addedColumns['foo'] = new \Doctrine\DBAL\Schema\Column('foo', Type::getType('integer'));
541
        $tableDiff->removedColumns['test'] = $table->getColumn('test');
542
543
        $this->_sm->alterTable($tableDiff);
544
545
        $table = $this->_sm->listTableDetails('alter_table');
546
        self::assertFalse($table->hasColumn('test'));
547
        self::assertTrue($table->hasColumn('foo'));
548
549
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
550
        $tableDiff->fromTable = $table;
551
        $tableDiff->addedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo'));
552
553
        $this->_sm->alterTable($tableDiff);
554
555
        $table = $this->_sm->listTableDetails('alter_table');
556
        self::assertEquals(2, count($table->getIndexes()));
557
        self::assertTrue($table->hasIndex('foo_idx'));
558
        self::assertEquals(array('foo'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
559
        self::assertFalse($table->getIndex('foo_idx')->isPrimary());
560
        self::assertFalse($table->getIndex('foo_idx')->isUnique());
561
562
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
563
        $tableDiff->fromTable = $table;
564
        $tableDiff->changedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo', 'foreign_key_test'));
565
566
        $this->_sm->alterTable($tableDiff);
567
568
        $table = $this->_sm->listTableDetails('alter_table');
569
        self::assertEquals(2, count($table->getIndexes()));
570
        self::assertTrue($table->hasIndex('foo_idx'));
571
        self::assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
572
573
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
574
        $tableDiff->fromTable = $table;
575
        $tableDiff->renamedIndexes['foo_idx'] = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
576
577
        $this->_sm->alterTable($tableDiff);
578
579
        $table = $this->_sm->listTableDetails('alter_table');
580
        self::assertEquals(2, count($table->getIndexes()));
581
        self::assertTrue($table->hasIndex('bar_idx'));
582
        self::assertFalse($table->hasIndex('foo_idx'));
583
        self::assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('bar_idx')->getColumns()));
584
        self::assertFalse($table->getIndex('bar_idx')->isPrimary());
585
        self::assertFalse($table->getIndex('bar_idx')->isUnique());
586
587
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
588
        $tableDiff->fromTable = $table;
589
        $tableDiff->removedIndexes[] = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
590
        $fk = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(array('foreign_key_test'), 'alter_table_foreign', array('id'));
591
        $tableDiff->addedForeignKeys[] = $fk;
592
593
        $this->_sm->alterTable($tableDiff);
594
        $table = $this->_sm->listTableDetails('alter_table');
595
596
        // dont check for index size here, some platforms automatically add indexes for foreign keys.
597
        self::assertFalse($table->hasIndex('bar_idx'));
598
599
        if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
600
            $fks = $table->getForeignKeys();
601
            self::assertCount(1, $fks);
602
            $foreignKey = current($fks);
603
            self::assertEquals('alter_table_foreign', strtolower($foreignKey->getForeignTableName()));
604
            self::assertEquals(array('foreign_key_test'), array_map('strtolower', $foreignKey->getColumns()));
605
            self::assertEquals(array('id'), array_map('strtolower', $foreignKey->getForeignColumns()));
606
        }
607
    }
608
609
610
    public function testTableInNamespace()
611
    {
612
        if (! $this->_sm->getDatabasePlatform()->supportsSchemas()) {
613
            $this->markTestSkipped('Schema definition is not supported by this platform.');
614
        }
615
616
        //create schema
617
        $diff                  = new SchemaDiff();
618
        $diff->newNamespaces[] = 'testschema';
619
620
        foreach ($diff->toSql($this->_sm->getDatabasePlatform()) as $sql) {
621
            $this->_conn->exec($sql);
622
        }
623
624
        //test if table is create in namespace
625
        $this->createTestTable('testschema.my_table_in_namespace');
626
        self::assertContains('testschema.my_table_in_namespace', $this->_sm->listTableNames());
627
628
        //tables without namespace should be created in default namespace
629
        //default namespaces are ignored in table listings
630
        $this->createTestTable('my_table_not_in_namespace');
631
        self::assertContains('my_table_not_in_namespace', $this->_sm->listTableNames());
632
    }
633
634
    public function testCreateAndListViews()
635
    {
636
        if (!$this->_sm->getDatabasePlatform()->supportsViews()) {
637
            $this->markTestSkipped('Views is not supported by this platform.');
638
        }
639
640
        $this->createTestTable('view_test_table');
641
642
        $name = "doctrine_test_view";
643
        $sql = "SELECT * FROM view_test_table";
644
645
        $view = new \Doctrine\DBAL\Schema\View($name, $sql);
646
647
        $this->_sm->dropAndCreateView($view);
648
649
        self::assertTrue($this->hasElementWithName($this->_sm->listViews(), $name));
650
    }
651
652
    public function testAutoincrementDetection()
653
    {
654
        if (!$this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
655
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
656
        }
657
658
        $table = new Table('test_autoincrement');
659
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
660
        $table->addColumn('id', 'integer', array('autoincrement' => true));
661
        $table->setPrimaryKey(array('id'));
662
663
        $this->_sm->createTable($table);
664
665
        $inferredTable = $this->_sm->listTableDetails('test_autoincrement');
666
        self::assertTrue($inferredTable->hasColumn('id'));
667
        self::assertTrue($inferredTable->getColumn('id')->getAutoincrement());
668
    }
669
670
    /**
671
     * @group DBAL-792
672
     */
673
    public function testAutoincrementDetectionMulticolumns()
674
    {
675
        if (!$this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
676
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
677
        }
678
679
        $table = new Table('test_not_autoincrement');
680
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
681
        $table->addColumn('id', 'integer');
682
        $table->addColumn('other_id', 'integer');
683
        $table->setPrimaryKey(array('id', 'other_id'));
684
685
        $this->_sm->createTable($table);
686
687
        $inferredTable = $this->_sm->listTableDetails('test_not_autoincrement');
688
        self::assertTrue($inferredTable->hasColumn('id'));
689
        self::assertFalse($inferredTable->getColumn('id')->getAutoincrement());
690
    }
691
692
    /**
693
     * @group DDC-887
694
     */
695
    public function testUpdateSchemaWithForeignKeyRenaming()
696
    {
697
        if (!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
698
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
699
        }
700
701
        $table = new Table('test_fk_base');
702
        $table->addColumn('id', 'integer');
703
        $table->setPrimaryKey(array('id'));
704
705
        $tableFK = new Table('test_fk_rename');
706
        $tableFK->setSchemaConfig($this->_sm->createSchemaConfig());
707
        $tableFK->addColumn('id', 'integer');
708
        $tableFK->addColumn('fk_id', 'integer');
709
        $tableFK->setPrimaryKey(array('id'));
710
        $tableFK->addIndex(array('fk_id'), 'fk_idx');
711
        $tableFK->addForeignKeyConstraint('test_fk_base', array('fk_id'), array('id'));
712
713
        $this->_sm->createTable($table);
714
        $this->_sm->createTable($tableFK);
715
716
        $tableFKNew = new Table('test_fk_rename');
717
        $tableFKNew->setSchemaConfig($this->_sm->createSchemaConfig());
718
        $tableFKNew->addColumn('id', 'integer');
719
        $tableFKNew->addColumn('rename_fk_id', 'integer');
720
        $tableFKNew->setPrimaryKey(array('id'));
721
        $tableFKNew->addIndex(array('rename_fk_id'), 'fk_idx');
722
        $tableFKNew->addForeignKeyConstraint('test_fk_base', array('rename_fk_id'), array('id'));
723
724
        $c = new \Doctrine\DBAL\Schema\Comparator();
725
        $tableDiff = $c->diffTable($tableFK, $tableFKNew);
726
727
        $this->_sm->alterTable($tableDiff);
0 ignored issues
show
Bug introduced by
It seems like $tableDiff can also be of type false; however, parameter $tableDiff of Doctrine\DBAL\Schema\Abs...maManager::alterTable() does only seem to accept Doctrine\DBAL\Schema\TableDiff, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

727
        $this->_sm->alterTable(/** @scrutinizer ignore-type */ $tableDiff);
Loading history...
728
729
        $table       = $this->_sm->listTableDetails('test_fk_rename');
730
        $foreignKeys = $table->getForeignKeys();
731
732
        self::assertTrue($table->hasColumn('rename_fk_id'));
733
        self::assertCount(1, $foreignKeys);
734
        self::assertSame(['rename_fk_id'], array_map('strtolower', current($foreignKeys)->getColumns()));
735
    }
736
737
    /**
738
     * @group DBAL-1062
739
     */
740
    public function testRenameIndexUsedInForeignKeyConstraint()
741
    {
742
        if (! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
743
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
744
        }
745
746
        $primaryTable = new Table('test_rename_index_primary');
747
        $primaryTable->addColumn('id', 'integer');
748
        $primaryTable->setPrimaryKey(array('id'));
749
750
        $foreignTable = new Table('test_rename_index_foreign');
751
        $foreignTable->addColumn('fk', 'integer');
752
        $foreignTable->addIndex(array('fk'), 'rename_index_fk_idx');
753
        $foreignTable->addForeignKeyConstraint(
754
            'test_rename_index_primary',
755
            array('fk'),
756
            array('id'),
757
            array(),
758
            'fk_constraint'
759
        );
760
761
        $this->_sm->dropAndCreateTable($primaryTable);
762
        $this->_sm->dropAndCreateTable($foreignTable);
763
764
        $foreignTable2 = clone $foreignTable;
765
        $foreignTable2->renameIndex('rename_index_fk_idx', 'renamed_index_fk_idx');
766
767
        $comparator = new Comparator();
768
769
        $this->_sm->alterTable($comparator->diffTable($foreignTable, $foreignTable2));
0 ignored issues
show
Bug introduced by
It seems like $comparator->diffTable($...nTable, $foreignTable2) can also be of type false; however, parameter $tableDiff of Doctrine\DBAL\Schema\Abs...maManager::alterTable() does only seem to accept Doctrine\DBAL\Schema\TableDiff, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

769
        $this->_sm->alterTable(/** @scrutinizer ignore-type */ $comparator->diffTable($foreignTable, $foreignTable2));
Loading history...
770
771
        $foreignTable = $this->_sm->listTableDetails('test_rename_index_foreign');
772
773
        self::assertFalse($foreignTable->hasIndex('rename_index_fk_idx'));
774
        self::assertTrue($foreignTable->hasIndex('renamed_index_fk_idx'));
775
        self::assertTrue($foreignTable->hasForeignKey('fk_constraint'));
776
    }
777
778
    /**
779
     * @group DBAL-42
780
     */
781
    public function testGetColumnComment()
782
    {
783
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
784
             ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
785
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
786
            $this->markTestSkipped('Database does not support column comments.');
787
        }
788
789
        $table = new Table('column_comment_test');
790
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
791
        $table->setPrimaryKey(array('id'));
792
793
        $this->_sm->createTable($table);
794
795
        $columns = $this->_sm->listTableColumns("column_comment_test");
796
        self::assertEquals(1, count($columns));
797
        self::assertEquals('This is a comment', $columns['id']->getComment());
798
799
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff('column_comment_test');
800
        $tableDiff->fromTable = $table;
801
        $tableDiff->changedColumns['id'] = new \Doctrine\DBAL\Schema\ColumnDiff(
802
            'id', new \Doctrine\DBAL\Schema\Column(
803
                'id', \Doctrine\DBAL\Types\Type::getType('integer')
804
            ),
805
            array('comment'),
806
            new \Doctrine\DBAL\Schema\Column(
807
                'id', \Doctrine\DBAL\Types\Type::getType('integer'), array('comment' => 'This is a comment')
808
            )
809
        );
810
811
        $this->_sm->alterTable($tableDiff);
812
813
        $columns = $this->_sm->listTableColumns("column_comment_test");
814
        self::assertEquals(1, count($columns));
815
        self::assertEmpty($columns['id']->getComment());
816
    }
817
818
    /**
819
     * @group DBAL-42
820
     */
821
    public function testAutomaticallyAppendCommentOnMarkedColumns()
822
    {
823
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
824
             ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
825
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
826
            $this->markTestSkipped('Database does not support column comments.');
827
        }
828
829
        $table = new Table('column_comment_test2');
830
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
831
        $table->addColumn('obj', 'object', array('comment' => 'This is a comment'));
832
        $table->addColumn('arr', 'array', array('comment' => 'This is a comment'));
833
        $table->setPrimaryKey(array('id'));
834
835
        $this->_sm->createTable($table);
836
837
        $columns = $this->_sm->listTableColumns("column_comment_test2");
838
        self::assertEquals(3, count($columns));
839
        self::assertEquals('This is a comment', $columns['id']->getComment());
840
        self::assertEquals('This is a comment', $columns['obj']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
841
        self::assertInstanceOf('Doctrine\DBAL\Types\ObjectType', $columns['obj']->getType(), "The Doctrine2 should be detected from comment hint.");
842
        self::assertEquals('This is a comment', $columns['arr']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
843
        self::assertInstanceOf('Doctrine\DBAL\Types\ArrayType', $columns['arr']->getType(), "The Doctrine2 should be detected from comment hint.");
844
    }
845
846
    /**
847
     * @group DBAL-1228
848
     */
849
    public function testCommentHintOnDateIntervalTypeColumn()
850
    {
851
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
852
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
853
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
854
            $this->markTestSkipped('Database does not support column comments.');
855
        }
856
857
        $table = new Table('column_dateinterval_comment');
858
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
859
        $table->addColumn('date_interval', 'dateinterval', array('comment' => 'This is a comment'));
860
        $table->setPrimaryKey(array('id'));
861
862
        $this->_sm->createTable($table);
863
864
        $columns = $this->_sm->listTableColumns("column_dateinterval_comment");
865
        self::assertEquals(2, count($columns));
866
        self::assertEquals('This is a comment', $columns['id']->getComment());
867
        self::assertEquals('This is a comment', $columns['date_interval']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
868
        self::assertInstanceOf('Doctrine\DBAL\Types\DateIntervalType', $columns['date_interval']->getType(), "The Doctrine2 should be detected from comment hint.");
869
    }
870
871
    /**
872
     * @group DBAL-825
873
     */
874
    public function testChangeColumnsTypeWithDefaultValue()
875
    {
876
        $tableName = 'column_def_change_type';
877
        $table     = new Table($tableName);
878
879
        $table->addColumn('col_int', 'smallint', array('default' => 666));
880
        $table->addColumn('col_string', 'string', array('default' => 'foo'));
881
882
        $this->_sm->dropAndCreateTable($table);
883
884
        $tableDiff = new TableDiff($tableName);
885
        $tableDiff->fromTable = $table;
886
        $tableDiff->changedColumns['col_int'] = new ColumnDiff(
887
            'col_int',
888
            new Column('col_int', Type::getType('integer'), array('default' => 666)),
889
            array('type'),
890
            new Column('col_int', Type::getType('smallint'), array('default' => 666))
891
        );
892
893
        $tableDiff->changedColumns['col_string'] = new ColumnDiff(
894
            'col_string',
895
            new Column('col_string', Type::getType('string'), array('default' => 'foo', 'fixed' => true)),
896
            array('fixed'),
897
            new Column('col_string', Type::getType('string'), array('default' => 'foo'))
898
        );
899
900
        $this->_sm->alterTable($tableDiff);
901
902
        $columns = $this->_sm->listTableColumns($tableName);
903
904
        self::assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['col_int']->getType());
905
        self::assertEquals(666, $columns['col_int']->getDefault());
906
907
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['col_string']->getType());
908
        self::assertEquals('foo', $columns['col_string']->getDefault());
909
    }
910
911
    /**
912
     * @group DBAL-197
913
     */
914
    public function testListTableWithBlob()
915
    {
916
        $table = new Table('test_blob_table');
917
        $table->addColumn('id', 'integer', ['comment' => 'This is a comment']);
918
        $table->addColumn('binarydata', 'blob', []);
919
        $table->setPrimaryKey(['id']);
920
921
        $this->_sm->createTable($table);
922
923
        $created = $this->_sm->listTableDetails('test_blob_table');
924
925
        self::assertTrue($created->hasColumn('id'));
926
        self::assertTrue($created->hasColumn('binarydata'));
927
        self::assertTrue($created->hasPrimaryKey());
928
    }
929
930
    /**
931
     * @param string $name
932
     * @param array  $data
933
     * @return Table
934
     */
935
    protected function createTestTable($name = 'test_table', $data = array())
936
    {
937
        $options = $data['options'] ?? [];
938
939
        $table = $this->getTestTable($name, $options);
940
941
        $this->_sm->dropAndCreateTable($table);
942
943
        return $table;
944
    }
945
946
    protected function getTestTable($name, $options=array())
947
    {
948
        $table = new Table($name, array(), array(), array(), false, $options);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type integer expected by parameter $idGeneratorType of Doctrine\DBAL\Schema\Table::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

948
        $table = new Table($name, array(), array(), array(), /** @scrutinizer ignore-type */ false, $options);
Loading history...
949
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
950
        $table->addColumn('id', 'integer', array('notnull' => true));
951
        $table->setPrimaryKey(array('id'));
952
        $table->addColumn('test', 'string', array('length' => 255));
953
        $table->addColumn('foreign_key_test', 'integer');
954
        return $table;
955
    }
956
957
    protected function getTestCompositeTable($name)
958
    {
959
        $table = new Table($name, array(), array(), array(), false, array());
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type integer expected by parameter $idGeneratorType of Doctrine\DBAL\Schema\Table::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

959
        $table = new Table($name, array(), array(), array(), /** @scrutinizer ignore-type */ false, array());
Loading history...
960
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
961
        $table->addColumn('id', 'integer', array('notnull' => true));
962
        $table->addColumn('other_id', 'integer', array('notnull' => true));
963
        $table->setPrimaryKey(array('id', 'other_id'));
964
        $table->addColumn('test', 'string', array('length' => 255));
965
        return $table;
966
    }
967
968
    protected function assertHasTable($tables, $tableName)
0 ignored issues
show
Unused Code introduced by
The parameter $tableName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

968
    protected function assertHasTable($tables, /** @scrutinizer ignore-unused */ $tableName)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
969
    {
970
        $foundTable = false;
971
        foreach ($tables as $table) {
972
            self::assertInstanceOf('Doctrine\DBAL\Schema\Table', $table, 'No Table instance was found in tables array.');
973
            if (strtolower($table->getName()) == 'list_tables_test_new_name') {
974
                $foundTable = true;
975
            }
976
        }
977
        self::assertTrue($foundTable, "Could not find new table");
978
    }
979
980
    public function testListForeignKeysComposite()
981
    {
982
        if(!$this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
983
            $this->markTestSkipped('Does not support foreign key constraints.');
984
        }
985
986
        $this->_sm->createTable($this->getTestTable('test_create_fk3'));
987
        $this->_sm->createTable($this->getTestCompositeTable('test_create_fk4'));
988
989
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
990
            array('id', 'foreign_key_test'), 'test_create_fk4', array('id', 'other_id'), 'foreign_key_test_fk2'
991
        );
992
993
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk3');
994
995
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk3');
996
997
        self::assertEquals(1, count($fkeys), "Table 'test_create_fk3' has to have one foreign key.");
998
999
        self::assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
1000
        self::assertEquals(array('id', 'foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns()));
1001
        self::assertEquals(array('id', 'other_id'),         array_map('strtolower', $fkeys[0]->getForeignColumns()));
1002
    }
1003
1004
    /**
1005
     * @group DBAL-44
1006
     */
1007
    public function testColumnDefaultLifecycle()
1008
    {
1009
        $table = new Table("col_def_lifecycle");
1010
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1011
        $table->addColumn('column1', 'string', array('default' => null));
1012
        $table->addColumn('column2', 'string', array('default' => false));
1013
        $table->addColumn('column3', 'string', array('default' => true));
1014
        $table->addColumn('column4', 'string', array('default' => 0));
1015
        $table->addColumn('column5', 'string', array('default' => ''));
1016
        $table->addColumn('column6', 'string', array('default' => 'def'));
1017
        $table->addColumn('column7', 'integer', array('default' => 0));
1018
        $table->setPrimaryKey(array('id'));
1019
1020
        $this->_sm->dropAndCreateTable($table);
1021
1022
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
1023
1024
        self::assertNull($columns['id']->getDefault());
1025
        self::assertNull($columns['column1']->getDefault());
1026
        self::assertSame('', $columns['column2']->getDefault());
1027
        self::assertSame('1', $columns['column3']->getDefault());
1028
        self::assertSame('0', $columns['column4']->getDefault());
1029
        self::assertSame('', $columns['column5']->getDefault());
1030
        self::assertSame('def', $columns['column6']->getDefault());
1031
        self::assertSame('0', $columns['column7']->getDefault());
1032
1033
        $diffTable = clone $table;
1034
1035
        $diffTable->changeColumn('column1', array('default' => false));
1036
        $diffTable->changeColumn('column2', array('default' => null));
1037
        $diffTable->changeColumn('column3', array('default' => false));
1038
        $diffTable->changeColumn('column4', array('default' => null));
1039
        $diffTable->changeColumn('column5', array('default' => false));
1040
        $diffTable->changeColumn('column6', array('default' => 666));
1041
        $diffTable->changeColumn('column7', array('default' => null));
1042
1043
        $comparator = new Comparator();
1044
1045
        $this->_sm->alterTable($comparator->diffTable($table, $diffTable));
1046
1047
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
1048
1049
        self::assertSame('', $columns['column1']->getDefault());
1050
        self::assertNull($columns['column2']->getDefault());
1051
        self::assertSame('', $columns['column3']->getDefault());
1052
        self::assertNull($columns['column4']->getDefault());
1053
        self::assertSame('', $columns['column5']->getDefault());
1054
        self::assertSame('666', $columns['column6']->getDefault());
1055
        self::assertNull($columns['column7']->getDefault());
1056
    }
1057
1058
    public function testListTableWithBinary()
1059
    {
1060
        $tableName = 'test_binary_table';
1061
1062
        $table = new Table($tableName);
1063
        $table->addColumn('id', 'integer');
1064
        $table->addColumn('column_varbinary', 'binary', array());
1065
        $table->addColumn('column_binary', 'binary', array('fixed' => true));
1066
        $table->setPrimaryKey(array('id'));
1067
1068
        $this->_sm->createTable($table);
1069
1070
        $table = $this->_sm->listTableDetails($tableName);
1071
1072
        self::assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_varbinary')->getType());
1073
        self::assertFalse($table->getColumn('column_varbinary')->getFixed());
1074
1075
        self::assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_binary')->getType());
1076
        self::assertTrue($table->getColumn('column_binary')->getFixed());
1077
    }
1078
1079
    public function testListTableDetailsWithFullQualifiedTableName()
1080
    {
1081
        if ( ! $this->_sm->getDatabasePlatform()->supportsSchemas()) {
1082
            $this->markTestSkipped('Test only works on platforms that support schemas.');
1083
        }
1084
1085
        $defaultSchemaName = $this->_sm->getDatabasePlatform()->getDefaultSchemaName();
1086
        $primaryTableName  = 'primary_table';
1087
        $foreignTableName  = 'foreign_table';
1088
1089
        $table = new Table($foreignTableName);
1090
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1091
        $table->setPrimaryKey(array('id'));
1092
1093
        $this->_sm->dropAndCreateTable($table);
1094
1095
        $table = new Table($primaryTableName);
1096
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1097
        $table->addColumn('foo', 'integer');
1098
        $table->addColumn('bar', 'string');
1099
        $table->addForeignKeyConstraint($foreignTableName, array('foo'), array('id'));
1100
        $table->addIndex(array('bar'));
1101
        $table->setPrimaryKey(array('id'));
1102
1103
        $this->_sm->dropAndCreateTable($table);
1104
1105
        self::assertEquals(
1106
            $this->_sm->listTableColumns($primaryTableName),
1107
            $this->_sm->listTableColumns($defaultSchemaName . '.' . $primaryTableName)
1108
        );
1109
        self::assertEquals(
1110
            $this->_sm->listTableIndexes($primaryTableName),
1111
            $this->_sm->listTableIndexes($defaultSchemaName . '.' . $primaryTableName)
1112
        );
1113
        self::assertEquals(
1114
            $this->_sm->listTableForeignKeys($primaryTableName),
1115
            $this->_sm->listTableForeignKeys($defaultSchemaName . '.' . $primaryTableName)
1116
        );
1117
    }
1118
1119
    public function testCommentStringsAreQuoted()
1120
    {
1121
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
1122
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
1123
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1124
            $this->markTestSkipped('Database does not support column comments.');
1125
        }
1126
1127
        $table = new Table('my_table');
1128
        $table->addColumn('id', 'integer', array('comment' => "It's a comment with a quote"));
1129
        $table->setPrimaryKey(array('id'));
1130
1131
        $this->_sm->createTable($table);
1132
1133
        $columns = $this->_sm->listTableColumns("my_table");
1134
        self::assertEquals("It's a comment with a quote", $columns['id']->getComment());
1135
    }
1136
1137
    public function testCommentNotDuplicated()
1138
    {
1139
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments()) {
1140
            $this->markTestSkipped('Database does not support column comments.');
1141
        }
1142
1143
        $options = array(
1144
            'type' => Type::getType('integer'),
1145
            'default' => 0,
1146
            'notnull' => true,
1147
            'comment' => 'expected+column+comment',
1148
        );
1149
        $columnDefinition = substr($this->_conn->getDatabasePlatform()->getColumnDeclarationSQL('id', $options), strlen('id') + 1);
1150
1151
        $table = new Table('my_table');
1152
        $table->addColumn('id', 'integer', array('columnDefinition' => $columnDefinition, 'comment' => 'unexpected_column_comment'));
1153
        $sql = $this->_conn->getDatabasePlatform()->getCreateTableSQL($table);
1154
1155
        self::assertContains('expected+column+comment', $sql[0]);
1156
        self::assertNotContains('unexpected_column_comment', $sql[0]);
1157
    }
1158
1159
    /**
1160
     * @group DBAL-1009
1161
     *
1162
     * @dataProvider getAlterColumnComment
1163
     */
1164
    public function testAlterColumnComment($comment1, $expectedComment1, $comment2, $expectedComment2)
1165
    {
1166
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
1167
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
1168
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1169
            $this->markTestSkipped('Database does not support column comments.');
1170
        }
1171
1172
        $offlineTable = new Table('alter_column_comment_test');
1173
        $offlineTable->addColumn('comment1', 'integer', array('comment' => $comment1));
1174
        $offlineTable->addColumn('comment2', 'integer', array('comment' => $comment2));
1175
        $offlineTable->addColumn('no_comment1', 'integer');
1176
        $offlineTable->addColumn('no_comment2', 'integer');
1177
        $this->_sm->dropAndCreateTable($offlineTable);
1178
1179
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1180
1181
        self::assertSame($expectedComment1, $onlineTable->getColumn('comment1')->getComment());
1182
        self::assertSame($expectedComment2, $onlineTable->getColumn('comment2')->getComment());
1183
        self::assertNull($onlineTable->getColumn('no_comment1')->getComment());
1184
        self::assertNull($onlineTable->getColumn('no_comment2')->getComment());
1185
1186
        $onlineTable->changeColumn('comment1', array('comment' => $comment2));
1187
        $onlineTable->changeColumn('comment2', array('comment' => $comment1));
1188
        $onlineTable->changeColumn('no_comment1', array('comment' => $comment1));
1189
        $onlineTable->changeColumn('no_comment2', array('comment' => $comment2));
1190
1191
        $comparator = new Comparator();
1192
1193
        $tableDiff = $comparator->diffTable($offlineTable, $onlineTable);
1194
1195
        self::assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
1196
1197
        $this->_sm->alterTable($tableDiff);
1198
1199
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1200
1201
        self::assertSame($expectedComment2, $onlineTable->getColumn('comment1')->getComment());
1202
        self::assertSame($expectedComment1, $onlineTable->getColumn('comment2')->getComment());
1203
        self::assertSame($expectedComment1, $onlineTable->getColumn('no_comment1')->getComment());
1204
        self::assertSame($expectedComment2, $onlineTable->getColumn('no_comment2')->getComment());
1205
    }
1206
1207
    public function getAlterColumnComment()
1208
    {
1209
        return array(
1210
            array(null, null, ' ', ' '),
1211
            array(null, null, '0', '0'),
1212
            array(null, null, 'foo', 'foo'),
1213
1214
            array('', null, ' ', ' '),
1215
            array('', null, '0', '0'),
1216
            array('', null, 'foo', 'foo'),
1217
1218
            array(' ', ' ', '0', '0'),
1219
            array(' ', ' ', 'foo', 'foo'),
1220
1221
            array('0', '0', 'foo', 'foo'),
1222
        );
1223
    }
1224
1225
    /**
1226
     * @group DBAL-1095
1227
     */
1228
    public function testDoesNotListIndexesImplicitlyCreatedByForeignKeys()
1229
    {
1230
        if (! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
1231
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
1232
        }
1233
1234
        $primaryTable = new Table('test_list_index_impl_primary');
1235
        $primaryTable->addColumn('id', 'integer');
1236
        $primaryTable->setPrimaryKey(array('id'));
1237
1238
        $foreignTable = new Table('test_list_index_impl_foreign');
1239
        $foreignTable->addColumn('fk1', 'integer');
1240
        $foreignTable->addColumn('fk2', 'integer');
1241
        $foreignTable->addIndex(array('fk1'), 'explicit_fk1_idx');
1242
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk1'), array('id'));
1243
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk2'), array('id'));
1244
1245
        $this->_sm->dropAndCreateTable($primaryTable);
1246
        $this->_sm->dropAndCreateTable($foreignTable);
1247
1248
        $indexes = $this->_sm->listTableIndexes('test_list_index_impl_foreign');
1249
1250
        self::assertCount(2, $indexes);
1251
        self::assertArrayHasKey('explicit_fk1_idx', $indexes);
1252
        self::assertArrayHasKey('idx_3d6c147fdc58d6c', $indexes);
1253
    }
1254
1255
    /**
1256
     * @after
1257
     */
1258
    public function removeJsonArrayTable() : void
1259
    {
1260
        if ($this->_sm->tablesExist(['json_array_test'])) {
1261
            $this->_sm->dropTable('json_array_test');
1262
        }
1263
    }
1264
1265
    /**
1266
     * @group 2782
1267
     * @group 6654
1268
     */
1269
    public function testComparatorShouldReturnFalseWhenLegacyJsonArrayColumnHasComment() : void
1270
    {
1271
        $table = new Table('json_array_test');
1272
        $table->addColumn('parameters', 'json_array');
1273
1274
        $this->_sm->createTable($table);
1275
1276
        $comparator = new Comparator();
1277
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1278
1279
        self::assertFalse($tableDiff);
1280
    }
1281
1282
    /**
1283
     * @group 2782
1284
     * @group 6654
1285
     */
1286
    public function testComparatorShouldModifyOnlyTheCommentWhenUpdatingFromJsonArrayTypeOnLegacyPlatforms() : void
1287
    {
1288
        if ($this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1289
            $this->markTestSkipped('This test is only supported on platforms that do not have native JSON type.');
1290
        }
1291
1292
        $table = new Table('json_array_test');
1293
        $table->addColumn('parameters', 'json_array');
1294
1295
        $this->_sm->createTable($table);
1296
1297
        $table = new Table('json_array_test');
1298
        $table->addColumn('parameters', 'json');
1299
1300
        $comparator = new Comparator();
1301
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1302
1303
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1304
1305
        $changedColumn = $tableDiff->changedColumns['parameters'] ?? $tableDiff->changedColumns['PARAMETERS'];
1306
1307
        self::assertSame(['comment'], $changedColumn->changedProperties);
1308
    }
1309
1310
    /**
1311
     * @group 2782
1312
     * @group 6654
1313
     */
1314
    public function testComparatorShouldAddCommentToLegacyJsonArrayTypeThatDoesNotHaveIt() : void
1315
    {
1316
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1317
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1318
        }
1319
1320
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON NOT NULL)');
1321
1322
        $table = new Table('json_array_test');
1323
        $table->addColumn('parameters', 'json_array');
1324
1325
        $comparator = new Comparator();
1326
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1327
1328
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1329
        self::assertSame(['comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1330
    }
1331
1332
    /**
1333
     * @group 2782
1334
     * @group 6654
1335
     */
1336
    public function testComparatorShouldReturnAllChangesWhenUsingLegacyJsonArrayType() : void
1337
    {
1338
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1339
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1340
        }
1341
1342
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON DEFAULT NULL)');
1343
1344
        $table = new Table('json_array_test');
1345
        $table->addColumn('parameters', 'json_array');
1346
1347
        $comparator = new Comparator();
1348
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1349
1350
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1351
        self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1352
    }
1353
1354
    /**
1355
     * @group 2782
1356
     * @group 6654
1357
     */
1358
    public function testComparatorShouldReturnAllChangesWhenUsingLegacyJsonArrayTypeEvenWhenPlatformHasJsonSupport() : void
1359
    {
1360
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1361
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1362
        }
1363
1364
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON DEFAULT NULL)');
1365
1366
        $table = new Table('json_array_test');
1367
        $table->addColumn('parameters', 'json_array');
1368
1369
        $comparator = new Comparator();
1370
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1371
1372
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1373
        self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1374
    }
1375
1376
    /**
1377
     * @group 2782
1378
     * @group 6654
1379
     */
1380
    public function testComparatorShouldNotAddCommentToJsonTypeSinceItIsTheDefaultNow() : void
1381
    {
1382
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1383
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1384
        }
1385
1386
        $this->_conn->executeQuery('CREATE TABLE json_test (parameters JSON NOT NULL)');
1387
1388
        $table = new Table('json_test');
1389
        $table->addColumn('parameters', 'json');
1390
1391
        $comparator = new Comparator();
1392
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_test'), $table);
1393
1394
        self::assertFalse($tableDiff);
1395
    }
1396
1397
    /**
1398
     * @dataProvider commentsProvider
1399
     *
1400
     * @group 2596
1401
     */
1402
    public function testExtractDoctrineTypeFromComment(string $comment, string $expected, string $currentType) : void
1403
    {
1404
        $result = $this->_sm->extractDoctrineTypeFromComment($comment, $currentType);
1405
1406
        self::assertSame($expected, $result);
1407
    }
1408
1409
    public function commentsProvider() : array
1410
    {
1411
        $currentType = 'current type';
1412
1413
        return [
1414
            'invalid custom type comments'      => ['should.return.current.type', $currentType, $currentType],
1415
            'valid doctrine type'               => ['(DC2Type:guid)', 'guid', $currentType],
1416
            'valid with dots'                   => ['(DC2Type:type.should.return)', 'type.should.return', $currentType],
1417
            'valid with namespace'              => ['(DC2Type:Namespace\Class)', 'Namespace\Class', $currentType],
1418
            'valid with extra closing bracket'  => ['(DC2Type:should.stop)).before)', 'should.stop', $currentType],
1419
            'valid with extra opening brackets' => ['(DC2Type:should((.stop)).before)', 'should((.stop', $currentType],
1420
        ];
1421
    }
1422
1423
    public function testCreateAndListSequences() : void
1424
    {
1425
        if ( ! $this->_sm->getDatabasePlatform()->supportsSequences()) {
1426
            self::markTestSkipped('This test is only supported on platforms that support sequences.');
1427
        }
1428
1429
        $sequence1Name           = 'sequence_1';
1430
        $sequence1AllocationSize = 1;
1431
        $sequence1InitialValue   = 2;
1432
        $sequence2Name           = 'sequence_2';
1433
        $sequence2AllocationSize = 3;
1434
        $sequence2InitialValue   = 4;
1435
        $sequence1               = new Sequence($sequence1Name, $sequence1AllocationSize, $sequence1InitialValue);
1436
        $sequence2               = new Sequence($sequence2Name, $sequence2AllocationSize, $sequence2InitialValue);
1437
1438
        $this->_sm->createSequence($sequence1);
1439
        $this->_sm->createSequence($sequence2);
1440
1441
        /** @var Sequence[] $actualSequences */
1442
        $actualSequences = [];
1443
        foreach ($this->_sm->listSequences() as $sequence) {
1444
            $actualSequences[$sequence->getName()] = $sequence;
1445
        }
1446
1447
        $actualSequence1 = $actualSequences[$sequence1Name];
1448
        $actualSequence2 = $actualSequences[$sequence2Name];
1449
1450
        self::assertSame($sequence1Name, $actualSequence1->getName());
1451
        self::assertEquals($sequence1AllocationSize, $actualSequence1->getAllocationSize());
1452
        self::assertEquals($sequence1InitialValue, $actualSequence1->getInitialValue());
1453
1454
        self::assertSame($sequence2Name, $actualSequence2->getName());
1455
        self::assertEquals($sequence2AllocationSize, $actualSequence2->getAllocationSize());
1456
        self::assertEquals($sequence2InitialValue, $actualSequence2->getInitialValue());
1457
    }
1458
1459
    /**
1460
     * @group #3086
1461
     */
1462
    public function testComparisonWithAutoDetectedSequenceDefinition() : void
1463
    {
1464
        if (! $this->_sm->getDatabasePlatform()->supportsSequences()) {
1465
            self::markTestSkipped('This test is only supported on platforms that support sequences.');
1466
        }
1467
1468
        $sequenceName           = 'sequence_auto_detect_test';
1469
        $sequenceAllocationSize = 5;
1470
        $sequenceInitialValue   = 10;
1471
        $sequence               = new Sequence($sequenceName, $sequenceAllocationSize, $sequenceInitialValue);
1472
1473
        $this->_sm->dropAndCreateSequence($sequence);
1474
1475
        $createdSequence = array_values(
1476
            array_filter(
1477
                $this->_sm->listSequences(),
1478
                function (Sequence $sequence) use ($sequenceName) : bool {
1479
                    return $sequence->getName() === $sequenceName;
1480
                }
1481
            )
1482
        )[0] ?? null;
1483
1484
        self::assertNotNull($createdSequence);
1485
1486
        $comparator = new Comparator();
1487
        $tableDiff  = $comparator->diffSequence($createdSequence, $sequence);
1488
1489
        self::assertFalse($tableDiff);
1490
    }
1491
}
1492