Completed
Push — master ( c7757e...39cb21 )
by Luís
16s
created

Schema/SchemaManagerFunctionalTestCase.php (2 issues)

1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional\Schema;
4
5
use Doctrine\Common\EventManager;
6
use Doctrine\DBAL\Events;
7
use Doctrine\DBAL\Platforms\OraclePlatform;
8
use Doctrine\DBAL\Schema\Column;
9
use Doctrine\DBAL\Schema\ColumnDiff;
10
use Doctrine\DBAL\Schema\Comparator;
11
use Doctrine\DBAL\Schema\Table;
12
use Doctrine\DBAL\Schema\TableDiff;
13
use Doctrine\DBAL\Types\Type;
14
15
class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTestCase
16
{
17
    /**
18
     * @var \Doctrine\DBAL\Schema\AbstractSchemaManager
19
     */
20
    protected $_sm;
21
22
    protected function getPlatformName()
23
    {
24
        $class = get_class($this);
25
        $e = explode('\\', $class);
26
        $testClass = end($e);
27
        $dbms = strtolower(str_replace('SchemaManagerTest', null, $testClass));
28
        return $dbms;
29
    }
30
31
    protected function setUp()
32
    {
33
        parent::setUp();
34
35
        $dbms = $this->getPlatformName();
36
37
        if ($this->_conn->getDatabasePlatform()->getName() !== $dbms) {
38
            $this->markTestSkipped(get_class($this) . ' requires the use of ' . $dbms);
39
        }
40
41
        $this->_sm = $this->_conn->getSchemaManager();
42
    }
43
44
    /**
45
     * @group DBAL-1220
46
     */
47
    public function testDropsDatabaseWithActiveConnections()
48
    {
49
        if (! $this->_sm->getDatabasePlatform()->supportsCreateDropDatabase()) {
50
            $this->markTestSkipped('Cannot drop Database client side with this Driver.');
51
        }
52
53
        $this->_sm->dropAndCreateDatabase('test_drop_database');
54
55
        $knownDatabases = $this->_sm->listDatabases();
56
        if ($this->_conn->getDatabasePlatform() instanceof OraclePlatform) {
57
            self::assertContains('TEST_DROP_DATABASE', $knownDatabases);
58
        } else {
59
            self::assertContains('test_drop_database', $knownDatabases);
60
        }
61
62
        $params = $this->_conn->getParams();
63
        if ($this->_conn->getDatabasePlatform() instanceof OraclePlatform) {
64
            $params['user'] = 'test_drop_database';
65
        } else {
66
            $params['dbname'] = 'test_drop_database';
67
        }
68
69
        $user = $params['user'] ?? null;
70
        $password = $params['password'] ?? null;
71
72
        $connection = $this->_conn->getDriver()->connect($params, $user, $password);
73
74
        self::assertInstanceOf('Doctrine\DBAL\Driver\Connection', $connection);
75
76
        $this->_sm->dropDatabase('test_drop_database');
77
78
        self::assertNotContains('test_drop_database', $this->_sm->listDatabases());
79
    }
80
81
    /**
82
     * @group DBAL-195
83
     */
84
    public function testDropAndCreateSequence()
85
    {
86
        if ( ! $this->_conn->getDatabasePlatform()->supportsSequences()) {
87
            $this->markTestSkipped($this->_conn->getDriver()->getName().' does not support sequences.');
88
        }
89
90
        $name = 'dropcreate_sequences_test_seq';
91
92
        $this->_sm->dropAndCreateSequence(new \Doctrine\DBAL\Schema\Sequence($name, 20, 10));
93
94
        self::assertTrue($this->hasElementWithName($this->_sm->listSequences(), $name));
95
    }
96
97
    private function hasElementWithName(array $items, string $name) : bool
98
    {
99
        $filteredList = array_filter(
100
            $items,
101
            function (\Doctrine\DBAL\Schema\AbstractAsset $item) use ($name) : bool {
102
                return $item->getShortestName($item->getNamespaceName()) === $name;
103
            }
104
        );
105
106
        return count($filteredList) === 1;
107
    }
108
109
    public function testListSequences()
110
    {
111
        if(!$this->_conn->getDatabasePlatform()->supportsSequences()) {
112
            $this->markTestSkipped($this->_conn->getDriver()->getName().' does not support sequences.');
113
        }
114
115
        $sequence = new \Doctrine\DBAL\Schema\Sequence('list_sequences_test_seq', 20, 10);
116
        $this->_sm->createSequence($sequence);
117
118
        $sequences = $this->_sm->listSequences();
119
120
        self::assertInternalType('array', $sequences, 'listSequences() should return an array.');
121
122
        $foundSequence = null;
123
        foreach($sequences as $sequence) {
124
            self::assertInstanceOf('Doctrine\DBAL\Schema\Sequence', $sequence, 'Array elements of listSequences() should be Sequence instances.');
125
            if(strtolower($sequence->getName()) == 'list_sequences_test_seq') {
126
                $foundSequence = $sequence;
127
            }
128
        }
129
130
        self::assertNotNull($foundSequence, "Sequence with name 'list_sequences_test_seq' was not found.");
131
        self::assertEquals(20, $foundSequence->getAllocationSize(), "Allocation Size is expected to be 20.");
132
        self::assertEquals(10, $foundSequence->getInitialValue(), "Initial Value is expected to be 10.");
133
    }
134
135
    public function testListDatabases()
136
    {
137
        if (!$this->_sm->getDatabasePlatform()->supportsCreateDropDatabase()) {
138
            $this->markTestSkipped('Cannot drop Database client side with this Driver.');
139
        }
140
141
        $this->_sm->dropAndCreateDatabase('test_create_database');
142
        $databases = $this->_sm->listDatabases();
143
144
        $databases = array_map('strtolower', $databases);
145
146
        self::assertContains('test_create_database', $databases);
147
    }
148
149
    /**
150
     * @group DBAL-1058
151
     */
152
    public function testListNamespaceNames()
153
    {
154
        if (!$this->_sm->getDatabasePlatform()->supportsSchemas()) {
155
            $this->markTestSkipped('Platform does not support schemas.');
156
        }
157
158
        // Currently dropping schemas is not supported, so we have to workaround here.
159
        $namespaces = $this->_sm->listNamespaceNames();
160
        $namespaces = array_map('strtolower', $namespaces);
161
162
        if (!in_array('test_create_schema', $namespaces)) {
163
            $this->_conn->executeUpdate($this->_sm->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema'));
164
165
            $namespaces = $this->_sm->listNamespaceNames();
166
            $namespaces = array_map('strtolower', $namespaces);
167
        }
168
169
        self::assertContains('test_create_schema', $namespaces);
170
    }
171
172
    public function testListTables()
173
    {
174
        $this->createTestTable('list_tables_test');
175
        $tables = $this->_sm->listTables();
176
177
        self::assertInternalType('array', $tables);
178
        self::assertTrue(count($tables) > 0, "List Tables has to find at least one table named 'list_tables_test'.");
179
180
        $foundTable = false;
181
        foreach ($tables as $table) {
182
            self::assertInstanceOf('Doctrine\DBAL\Schema\Table', $table);
183
            if (strtolower($table->getName()) == 'list_tables_test') {
184
                $foundTable = true;
185
186
                self::assertTrue($table->hasColumn('id'));
187
                self::assertTrue($table->hasColumn('test'));
188
                self::assertTrue($table->hasColumn('foreign_key_test'));
189
            }
190
        }
191
192
        self::assertTrue( $foundTable , "The 'list_tables_test' table has to be found.");
193
    }
194
195
    public function createListTableColumns()
196
    {
197
        $table = new Table('list_table_columns');
198
        $table->addColumn('id', 'integer', array('notnull' => true));
199
        $table->addColumn('test', 'string', array('length' => 255, 'notnull' => false, 'default' => 'expected default'));
200
        $table->addColumn('foo', 'text', array('notnull' => true));
201
        $table->addColumn('bar', 'decimal', array('precision' => 10, 'scale' => 4, 'notnull' => false));
202
        $table->addColumn('baz1', 'datetime');
203
        $table->addColumn('baz2', 'time');
204
        $table->addColumn('baz3', 'date');
205
        $table->setPrimaryKey(array('id'));
206
207
        return $table;
208
    }
209
210
    public function testListTableColumns()
211
    {
212
        $table = $this->createListTableColumns();
213
214
        $this->_sm->dropAndCreateTable($table);
215
216
        $columns = $this->_sm->listTableColumns('list_table_columns');
217
        $columnsKeys = array_keys($columns);
218
219
        self::assertArrayHasKey('id', $columns);
220
        self::assertEquals(0, array_search('id', $columnsKeys));
221
        self::assertEquals('id',   strtolower($columns['id']->getname()));
222
        self::assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['id']->gettype());
223
        self::assertEquals(false,  $columns['id']->getunsigned());
224
        self::assertEquals(true,   $columns['id']->getnotnull());
225
        self::assertEquals(null,   $columns['id']->getdefault());
226
        self::assertInternalType('array',  $columns['id']->getPlatformOptions());
227
228
        self::assertArrayHasKey('test', $columns);
229
        self::assertEquals(1, array_search('test', $columnsKeys));
230
        self::assertEquals('test', strtolower($columns['test']->getname()));
231
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['test']->gettype());
232
        self::assertEquals(255,    $columns['test']->getlength());
233
        self::assertEquals(false,  $columns['test']->getfixed());
234
        self::assertEquals(false,  $columns['test']->getnotnull());
235
        self::assertEquals('expected default',   $columns['test']->getdefault());
236
        self::assertInternalType('array',  $columns['test']->getPlatformOptions());
237
238
        self::assertEquals('foo',  strtolower($columns['foo']->getname()));
239
        self::assertEquals(2, array_search('foo', $columnsKeys));
240
        self::assertInstanceOf('Doctrine\DBAL\Types\TextType', $columns['foo']->gettype());
241
        self::assertEquals(false,  $columns['foo']->getunsigned());
242
        self::assertEquals(false,  $columns['foo']->getfixed());
243
        self::assertEquals(true,   $columns['foo']->getnotnull());
244
        self::assertEquals(null,   $columns['foo']->getdefault());
245
        self::assertInternalType('array',  $columns['foo']->getPlatformOptions());
246
247
        self::assertEquals('bar',  strtolower($columns['bar']->getname()));
248
        self::assertEquals(3, array_search('bar', $columnsKeys));
249
        self::assertInstanceOf('Doctrine\DBAL\Types\DecimalType', $columns['bar']->gettype());
250
        self::assertEquals(null,   $columns['bar']->getlength());
251
        self::assertEquals(10,     $columns['bar']->getprecision());
252
        self::assertEquals(4,      $columns['bar']->getscale());
253
        self::assertEquals(false,  $columns['bar']->getunsigned());
254
        self::assertEquals(false,  $columns['bar']->getfixed());
255
        self::assertEquals(false,  $columns['bar']->getnotnull());
256
        self::assertEquals(null,   $columns['bar']->getdefault());
257
        self::assertInternalType('array',  $columns['bar']->getPlatformOptions());
258
259
        self::assertEquals('baz1', strtolower($columns['baz1']->getname()));
260
        self::assertEquals(4, array_search('baz1', $columnsKeys));
261
        self::assertInstanceOf('Doctrine\DBAL\Types\DateTimeType', $columns['baz1']->gettype());
262
        self::assertEquals(true,   $columns['baz1']->getnotnull());
263
        self::assertEquals(null,   $columns['baz1']->getdefault());
264
        self::assertInternalType('array',  $columns['baz1']->getPlatformOptions());
265
266
        self::assertEquals('baz2', strtolower($columns['baz2']->getname()));
267
        self::assertEquals(5, array_search('baz2', $columnsKeys));
268
        self::assertContains($columns['baz2']->gettype()->getName(), array('time', 'date', 'datetime'));
269
        self::assertEquals(true,   $columns['baz2']->getnotnull());
270
        self::assertEquals(null,   $columns['baz2']->getdefault());
271
        self::assertInternalType('array',  $columns['baz2']->getPlatformOptions());
272
273
        self::assertEquals('baz3', strtolower($columns['baz3']->getname()));
274
        self::assertEquals(6, array_search('baz3', $columnsKeys));
275
        self::assertContains($columns['baz3']->gettype()->getName(), array('time', 'date', 'datetime'));
276
        self::assertEquals(true,   $columns['baz3']->getnotnull());
277
        self::assertEquals(null,   $columns['baz3']->getdefault());
278
        self::assertInternalType('array',  $columns['baz3']->getPlatformOptions());
279
    }
280
281
    /**
282
     * @group DBAL-1078
283
     */
284 View Code Duplication
    public function testListTableColumnsWithFixedStringColumn()
285
    {
286
        $tableName = 'test_list_table_fixed_string';
287
288
        $table = new Table($tableName);
289
        $table->addColumn('column_char', 'string', array('fixed' => true, 'length' => 2));
290
291
        $this->_sm->createTable($table);
292
293
        $columns = $this->_sm->listTableColumns($tableName);
294
295
        self::assertArrayHasKey('column_char', $columns);
296
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['column_char']->getType());
297
        self::assertTrue($columns['column_char']->getFixed());
298
        self::assertSame(2, $columns['column_char']->getLength());
299
    }
300
301
    public function testListTableColumnsDispatchEvent()
302
    {
303
        $table = $this->createListTableColumns();
304
305
        $this->_sm->dropAndCreateTable($table);
306
307
        $listenerMock = $this
308
            ->getMockBuilder('ListTableColumnsDispatchEventListener')
309
            ->setMethods(['onSchemaColumnDefinition'])
310
            ->getMock();
311
        $listenerMock
312
            ->expects($this->exactly(7))
313
            ->method('onSchemaColumnDefinition');
314
315
        $oldEventManager = $this->_sm->getDatabasePlatform()->getEventManager();
316
317
        $eventManager = new EventManager();
318
        $eventManager->addEventListener(array(Events::onSchemaColumnDefinition), $listenerMock);
319
320
        $this->_sm->getDatabasePlatform()->setEventManager($eventManager);
321
322
        $this->_sm->listTableColumns('list_table_columns');
323
324
        $this->_sm->getDatabasePlatform()->setEventManager($oldEventManager);
325
    }
326
327
    public function testListTableIndexesDispatchEvent()
328
    {
329
        $table = $this->getTestTable('list_table_indexes_test');
330
        $table->addUniqueIndex(array('test'), 'test_index_name');
331
        $table->addIndex(array('id', 'test'), 'test_composite_idx');
332
333
        $this->_sm->dropAndCreateTable($table);
334
335
        $listenerMock = $this
336
            ->getMockBuilder('ListTableIndexesDispatchEventListener')
337
            ->setMethods(['onSchemaIndexDefinition'])
338
            ->getMock();
339
        $listenerMock
340
            ->expects($this->exactly(3))
341
            ->method('onSchemaIndexDefinition');
342
343
        $oldEventManager = $this->_sm->getDatabasePlatform()->getEventManager();
344
345
        $eventManager = new EventManager();
346
        $eventManager->addEventListener(array(Events::onSchemaIndexDefinition), $listenerMock);
347
348
        $this->_sm->getDatabasePlatform()->setEventManager($eventManager);
349
350
        $this->_sm->listTableIndexes('list_table_indexes_test');
351
352
        $this->_sm->getDatabasePlatform()->setEventManager($oldEventManager);
353
    }
354
355
    public function testDiffListTableColumns()
356
    {
357
        if ($this->_sm->getDatabasePlatform()->getName() == 'oracle') {
358
            $this->markTestSkipped('Does not work with Oracle, since it cannot detect DateTime, Date and Time differenecs (at the moment).');
359
        }
360
361
        $offlineTable = $this->createListTableColumns();
362
        $this->_sm->dropAndCreateTable($offlineTable);
363
        $onlineTable = $this->_sm->listTableDetails('list_table_columns');
364
365
        $comparator = new \Doctrine\DBAL\Schema\Comparator();
366
        $diff = $comparator->diffTable($offlineTable, $onlineTable);
367
368
        self::assertFalse($diff, "No differences should be detected with the offline vs online schema.");
369
    }
370
371
    public function testListTableIndexes()
372
    {
373
        $table = $this->getTestCompositeTable('list_table_indexes_test');
374
        $table->addUniqueIndex(array('test'), 'test_index_name');
375
        $table->addIndex(array('id', 'test'), 'test_composite_idx');
376
377
        $this->_sm->dropAndCreateTable($table);
378
379
        $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test');
380
381
        self::assertEquals(3, count($tableIndexes));
382
383
        self::assertArrayHasKey('primary', $tableIndexes, 'listTableIndexes() has to return a "primary" array key.');
384
        self::assertEquals(array('id', 'other_id'), array_map('strtolower', $tableIndexes['primary']->getColumns()));
385
        self::assertTrue($tableIndexes['primary']->isUnique());
386
        self::assertTrue($tableIndexes['primary']->isPrimary());
387
388
        self::assertEquals('test_index_name', strtolower($tableIndexes['test_index_name']->getName()));
389
        self::assertEquals(array('test'), array_map('strtolower', $tableIndexes['test_index_name']->getColumns()));
390
        self::assertTrue($tableIndexes['test_index_name']->isUnique());
391
        self::assertFalse($tableIndexes['test_index_name']->isPrimary());
392
393
        self::assertEquals('test_composite_idx', strtolower($tableIndexes['test_composite_idx']->getName()));
394
        self::assertEquals(array('id', 'test'), array_map('strtolower', $tableIndexes['test_composite_idx']->getColumns()));
395
        self::assertFalse($tableIndexes['test_composite_idx']->isUnique());
396
        self::assertFalse($tableIndexes['test_composite_idx']->isPrimary());
397
    }
398
399
    public function testDropAndCreateIndex()
400
    {
401
        $table = $this->getTestTable('test_create_index');
402
        $table->addUniqueIndex(array('test'), 'test');
403
        $this->_sm->dropAndCreateTable($table);
404
405
        $this->_sm->dropAndCreateIndex($table->getIndex('test'), $table);
406
        $tableIndexes = $this->_sm->listTableIndexes('test_create_index');
407
        self::assertInternalType('array', $tableIndexes);
408
409
        self::assertEquals('test',        strtolower($tableIndexes['test']->getName()));
410
        self::assertEquals(array('test'), array_map('strtolower', $tableIndexes['test']->getColumns()));
411
        self::assertTrue($tableIndexes['test']->isUnique());
412
        self::assertFalse($tableIndexes['test']->isPrimary());
413
    }
414
415
    public function testCreateTableWithForeignKeys()
416
    {
417
        if(!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
418
            $this->markTestSkipped('Platform does not support foreign keys.');
419
        }
420
421
        $tableB = $this->getTestTable('test_foreign');
422
423
        $this->_sm->dropAndCreateTable($tableB);
424
425
        $tableA = $this->getTestTable('test_create_fk');
426
        $tableA->addForeignKeyConstraint('test_foreign', array('foreign_key_test'), array('id'));
427
428
        $this->_sm->dropAndCreateTable($tableA);
429
430
        $fkTable = $this->_sm->listTableDetails('test_create_fk');
431
        $fkConstraints = $fkTable->getForeignKeys();
432
        self::assertEquals(1, count($fkConstraints), "Table 'test_create_fk1' has to have one foreign key.");
433
434
        $fkConstraint = current($fkConstraints);
435
        self::assertInstanceOf('\Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkConstraint);
436
        self::assertEquals('test_foreign',             strtolower($fkConstraint->getForeignTableName()));
437
        self::assertEquals(array('foreign_key_test'),  array_map('strtolower', $fkConstraint->getColumns()));
438
        self::assertEquals(array('id'),                array_map('strtolower', $fkConstraint->getForeignColumns()));
439
440
        self::assertTrue($fkTable->columnsAreIndexed($fkConstraint->getColumns()), "The columns of a foreign key constraint should always be indexed.");
441
    }
442
443
    public function testListForeignKeys()
444
    {
445
        if(!$this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
446
            $this->markTestSkipped('Does not support foreign key constraints.');
447
        }
448
449
        $this->createTestTable('test_create_fk1');
450
        $this->createTestTable('test_create_fk2');
451
452
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
453
            array('foreign_key_test'), 'test_create_fk2', array('id'), 'foreign_key_test_fk', array('onDelete' => 'CASCADE')
454
        );
455
456
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk1');
457
458
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk1');
459
460
        self::assertEquals(1, count($fkeys), "Table 'test_create_fk1' has to have one foreign key.");
461
462
        self::assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
463
        self::assertEquals(array('foreign_key_test'),  array_map('strtolower', $fkeys[0]->getLocalColumns()));
464
        self::assertEquals(array('id'),                array_map('strtolower', $fkeys[0]->getForeignColumns()));
465
        self::assertEquals('test_create_fk2',          strtolower($fkeys[0]->getForeignTableName()));
466
467
        if($fkeys[0]->hasOption('onDelete')) {
468
            self::assertEquals('CASCADE', $fkeys[0]->getOption('onDelete'));
469
        }
470
    }
471
472
    protected function getCreateExampleViewSql()
473
    {
474
        $this->markTestSkipped('No Create Example View SQL was defined for this SchemaManager');
475
    }
476
477
    public function testCreateSchema()
478
    {
479
        $this->createTestTable('test_table');
480
481
        $schema = $this->_sm->createSchema();
482
        self::assertTrue($schema->hasTable('test_table'));
483
    }
484
485
    public function testAlterTableScenario()
486
    {
487
        if(!$this->_sm->getDatabasePlatform()->supportsAlterTable()) {
488
            $this->markTestSkipped('Alter Table is not supported by this platform.');
489
        }
490
491
        $alterTable = $this->createTestTable('alter_table');
492
        $this->createTestTable('alter_table_foreign');
493
494
        $table = $this->_sm->listTableDetails('alter_table');
495
        self::assertTrue($table->hasColumn('id'));
496
        self::assertTrue($table->hasColumn('test'));
497
        self::assertTrue($table->hasColumn('foreign_key_test'));
498
        self::assertEquals(0, count($table->getForeignKeys()));
499
        self::assertEquals(1, count($table->getIndexes()));
500
501
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
502
        $tableDiff->fromTable = $alterTable;
503
        $tableDiff->addedColumns['foo'] = new \Doctrine\DBAL\Schema\Column('foo', Type::getType('integer'));
504
        $tableDiff->removedColumns['test'] = $table->getColumn('test');
505
506
        $this->_sm->alterTable($tableDiff);
507
508
        $table = $this->_sm->listTableDetails('alter_table');
509
        self::assertFalse($table->hasColumn('test'));
510
        self::assertTrue($table->hasColumn('foo'));
511
512
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
513
        $tableDiff->fromTable = $table;
514
        $tableDiff->addedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo'));
515
516
        $this->_sm->alterTable($tableDiff);
517
518
        $table = $this->_sm->listTableDetails('alter_table');
519
        self::assertEquals(2, count($table->getIndexes()));
520
        self::assertTrue($table->hasIndex('foo_idx'));
521
        self::assertEquals(array('foo'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
522
        self::assertFalse($table->getIndex('foo_idx')->isPrimary());
523
        self::assertFalse($table->getIndex('foo_idx')->isUnique());
524
525
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
526
        $tableDiff->fromTable = $table;
527
        $tableDiff->changedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo', 'foreign_key_test'));
528
529
        $this->_sm->alterTable($tableDiff);
530
531
        $table = $this->_sm->listTableDetails('alter_table');
532
        self::assertEquals(2, count($table->getIndexes()));
533
        self::assertTrue($table->hasIndex('foo_idx'));
534
        self::assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
535
536
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
537
        $tableDiff->fromTable = $table;
538
        $tableDiff->renamedIndexes['foo_idx'] = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
539
540
        $this->_sm->alterTable($tableDiff);
541
542
        $table = $this->_sm->listTableDetails('alter_table');
543
        self::assertEquals(2, count($table->getIndexes()));
544
        self::assertTrue($table->hasIndex('bar_idx'));
545
        self::assertFalse($table->hasIndex('foo_idx'));
546
        self::assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('bar_idx')->getColumns()));
547
        self::assertFalse($table->getIndex('bar_idx')->isPrimary());
548
        self::assertFalse($table->getIndex('bar_idx')->isUnique());
549
550
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
551
        $tableDiff->fromTable = $table;
552
        $tableDiff->removedIndexes[] = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
553
        $fk = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(array('foreign_key_test'), 'alter_table_foreign', array('id'));
554
        $tableDiff->addedForeignKeys[] = $fk;
555
556
        $this->_sm->alterTable($tableDiff);
557
        $table = $this->_sm->listTableDetails('alter_table');
558
559
        // dont check for index size here, some platforms automatically add indexes for foreign keys.
560
        self::assertFalse($table->hasIndex('bar_idx'));
561
562
        if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
563
            $fks = $table->getForeignKeys();
564
            self::assertCount(1, $fks);
565
            $foreignKey = current($fks);
566
            self::assertEquals('alter_table_foreign', strtolower($foreignKey->getForeignTableName()));
567
            self::assertEquals(array('foreign_key_test'), array_map('strtolower', $foreignKey->getColumns()));
568
            self::assertEquals(array('id'), array_map('strtolower', $foreignKey->getForeignColumns()));
569
        }
570
    }
571
572
    public function testCreateAndListViews()
573
    {
574
        if (!$this->_sm->getDatabasePlatform()->supportsViews()) {
575
            $this->markTestSkipped('Views is not supported by this platform.');
576
        }
577
578
        $this->createTestTable('view_test_table');
579
580
        $name = "doctrine_test_view";
581
        $sql = "SELECT * FROM view_test_table";
582
583
        $view = new \Doctrine\DBAL\Schema\View($name, $sql);
584
585
        $this->_sm->dropAndCreateView($view);
586
587
        self::assertTrue($this->hasElementWithName($this->_sm->listViews(), $name));
588
    }
589
590 View Code Duplication
    public function testAutoincrementDetection()
591
    {
592
        if (!$this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
593
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
594
        }
595
596
        $table = new Table('test_autoincrement');
597
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
598
        $table->addColumn('id', 'integer', array('autoincrement' => true));
599
        $table->setPrimaryKey(array('id'));
600
601
        $this->_sm->createTable($table);
602
603
        $inferredTable = $this->_sm->listTableDetails('test_autoincrement');
604
        self::assertTrue($inferredTable->hasColumn('id'));
605
        self::assertTrue($inferredTable->getColumn('id')->getAutoincrement());
606
    }
607
608
    /**
609
     * @group DBAL-792
610
     */
611 View Code Duplication
    public function testAutoincrementDetectionMulticolumns()
612
    {
613
        if (!$this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
614
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
615
        }
616
617
        $table = new Table('test_not_autoincrement');
618
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
619
        $table->addColumn('id', 'integer');
620
        $table->addColumn('other_id', 'integer');
621
        $table->setPrimaryKey(array('id', 'other_id'));
622
623
        $this->_sm->createTable($table);
624
625
        $inferredTable = $this->_sm->listTableDetails('test_not_autoincrement');
626
        self::assertTrue($inferredTable->hasColumn('id'));
627
        self::assertFalse($inferredTable->getColumn('id')->getAutoincrement());
628
    }
629
630
    /**
631
     * @group DDC-887
632
     */
633
    public function testUpdateSchemaWithForeignKeyRenaming()
634
    {
635
        if (!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
636
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
637
        }
638
639
        $table = new Table('test_fk_base');
640
        $table->addColumn('id', 'integer');
641
        $table->setPrimaryKey(array('id'));
642
643
        $tableFK = new Table('test_fk_rename');
644
        $tableFK->setSchemaConfig($this->_sm->createSchemaConfig());
645
        $tableFK->addColumn('id', 'integer');
646
        $tableFK->addColumn('fk_id', 'integer');
647
        $tableFK->setPrimaryKey(array('id'));
648
        $tableFK->addIndex(array('fk_id'), 'fk_idx');
649
        $tableFK->addForeignKeyConstraint('test_fk_base', array('fk_id'), array('id'));
650
651
        $this->_sm->createTable($table);
652
        $this->_sm->createTable($tableFK);
653
654
        $tableFKNew = new Table('test_fk_rename');
655
        $tableFKNew->setSchemaConfig($this->_sm->createSchemaConfig());
656
        $tableFKNew->addColumn('id', 'integer');
657
        $tableFKNew->addColumn('rename_fk_id', 'integer');
658
        $tableFKNew->setPrimaryKey(array('id'));
659
        $tableFKNew->addIndex(array('rename_fk_id'), 'fk_idx');
660
        $tableFKNew->addForeignKeyConstraint('test_fk_base', array('rename_fk_id'), array('id'));
661
662
        $c = new \Doctrine\DBAL\Schema\Comparator();
663
        $tableDiff = $c->diffTable($tableFK, $tableFKNew);
664
665
        $this->_sm->alterTable($tableDiff);
666
667
        $table       = $this->_sm->listTableDetails('test_fk_rename');
668
        $foreignKeys = $table->getForeignKeys();
669
670
        self::assertTrue($table->hasColumn('rename_fk_id'));
671
        self::assertCount(1, $foreignKeys);
672
        self::assertSame(['rename_fk_id'], array_map('strtolower', current($foreignKeys)->getColumns()));
673
    }
674
675
    /**
676
     * @group DBAL-1062
677
     */
678
    public function testRenameIndexUsedInForeignKeyConstraint()
679
    {
680
        if (! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
681
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
682
        }
683
684
        $primaryTable = new Table('test_rename_index_primary');
685
        $primaryTable->addColumn('id', 'integer');
686
        $primaryTable->setPrimaryKey(array('id'));
687
688
        $foreignTable = new Table('test_rename_index_foreign');
689
        $foreignTable->addColumn('fk', 'integer');
690
        $foreignTable->addIndex(array('fk'), 'rename_index_fk_idx');
691
        $foreignTable->addForeignKeyConstraint(
692
            'test_rename_index_primary',
693
            array('fk'),
694
            array('id'),
695
            array(),
696
            'fk_constraint'
697
        );
698
699
        $this->_sm->dropAndCreateTable($primaryTable);
700
        $this->_sm->dropAndCreateTable($foreignTable);
701
702
        $foreignTable2 = clone $foreignTable;
703
        $foreignTable2->renameIndex('rename_index_fk_idx', 'renamed_index_fk_idx');
704
705
        $comparator = new Comparator();
706
707
        $this->_sm->alterTable($comparator->diffTable($foreignTable, $foreignTable2));
708
709
        $foreignTable = $this->_sm->listTableDetails('test_rename_index_foreign');
710
711
        self::assertFalse($foreignTable->hasIndex('rename_index_fk_idx'));
712
        self::assertTrue($foreignTable->hasIndex('renamed_index_fk_idx'));
713
        self::assertTrue($foreignTable->hasForeignKey('fk_constraint'));
714
    }
715
716
    /**
717
     * @group DBAL-42
718
     */
719
    public function testGetColumnComment()
720
    {
721 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
722
             ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
723
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
724
            $this->markTestSkipped('Database does not support column comments.');
725
        }
726
727
        $table = new Table('column_comment_test');
728
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
729
        $table->setPrimaryKey(array('id'));
730
731
        $this->_sm->createTable($table);
732
733
        $columns = $this->_sm->listTableColumns("column_comment_test");
734
        self::assertEquals(1, count($columns));
735
        self::assertEquals('This is a comment', $columns['id']->getComment());
736
737
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff('column_comment_test');
738
        $tableDiff->fromTable = $table;
739
        $tableDiff->changedColumns['id'] = new \Doctrine\DBAL\Schema\ColumnDiff(
740
            'id', new \Doctrine\DBAL\Schema\Column(
741
                'id', \Doctrine\DBAL\Types\Type::getType('integer'), array('primary' => true)
742
            ),
743
            array('comment'),
744
            new \Doctrine\DBAL\Schema\Column(
745
                'id', \Doctrine\DBAL\Types\Type::getType('integer'), array('comment' => 'This is a comment')
746
            )
747
        );
748
749
        $this->_sm->alterTable($tableDiff);
750
751
        $columns = $this->_sm->listTableColumns("column_comment_test");
752
        self::assertEquals(1, count($columns));
753
        self::assertEmpty($columns['id']->getComment());
754
    }
755
756
    /**
757
     * @group DBAL-42
758
     */
759
    public function testAutomaticallyAppendCommentOnMarkedColumns()
760
    {
761 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
762
             ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
763
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
764
            $this->markTestSkipped('Database does not support column comments.');
765
        }
766
767
        $table = new Table('column_comment_test2');
768
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
769
        $table->addColumn('obj', 'object', array('comment' => 'This is a comment'));
770
        $table->addColumn('arr', 'array', array('comment' => 'This is a comment'));
771
        $table->setPrimaryKey(array('id'));
772
773
        $this->_sm->createTable($table);
774
775
        $columns = $this->_sm->listTableColumns("column_comment_test2");
776
        self::assertEquals(3, count($columns));
777
        self::assertEquals('This is a comment', $columns['id']->getComment());
778
        self::assertEquals('This is a comment', $columns['obj']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
779
        self::assertInstanceOf('Doctrine\DBAL\Types\ObjectType', $columns['obj']->getType(), "The Doctrine2 should be detected from comment hint.");
780
        self::assertEquals('This is a comment', $columns['arr']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
781
        self::assertInstanceOf('Doctrine\DBAL\Types\ArrayType', $columns['arr']->getType(), "The Doctrine2 should be detected from comment hint.");
782
    }
783
784
    /**
785
     * @group DBAL-1228
786
     */
787
    public function testCommentHintOnDateIntervalTypeColumn()
788
    {
789 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
790
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
791
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
792
            $this->markTestSkipped('Database does not support column comments.');
793
        }
794
795
        $table = new Table('column_dateinterval_comment');
796
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
797
        $table->addColumn('date_interval', 'dateinterval', array('comment' => 'This is a comment'));
798
        $table->setPrimaryKey(array('id'));
799
800
        $this->_sm->createTable($table);
801
802
        $columns = $this->_sm->listTableColumns("column_dateinterval_comment");
803
        self::assertEquals(2, count($columns));
804
        self::assertEquals('This is a comment', $columns['id']->getComment());
805
        self::assertEquals('This is a comment', $columns['date_interval']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
806
        self::assertInstanceOf('Doctrine\DBAL\Types\DateIntervalType', $columns['date_interval']->getType(), "The Doctrine2 should be detected from comment hint.");
807
    }
808
809
    /**
810
     * @group DBAL-825
811
     */
812
    public function testChangeColumnsTypeWithDefaultValue()
813
    {
814
        $tableName = 'column_def_change_type';
815
        $table     = new Table($tableName);
816
817
        $table->addColumn('col_int', 'smallint', array('default' => 666));
818
        $table->addColumn('col_string', 'string', array('default' => 'foo'));
819
820
        $this->_sm->dropAndCreateTable($table);
821
822
        $tableDiff = new TableDiff($tableName);
823
        $tableDiff->fromTable = $table;
824
        $tableDiff->changedColumns['col_int'] = new ColumnDiff(
825
            'col_int',
826
            new Column('col_int', Type::getType('integer'), array('default' => 666)),
827
            array('type'),
828
            new Column('col_int', Type::getType('smallint'), array('default' => 666))
829
        );
830
831
        $tableDiff->changedColumns['col_string'] = new ColumnDiff(
832
            'col_string',
833
            new Column('col_string', Type::getType('string'), array('default' => 'foo', 'fixed' => true)),
834
            array('fixed'),
835
            new Column('col_string', Type::getType('string'), array('default' => 'foo'))
836
        );
837
838
        $this->_sm->alterTable($tableDiff);
839
840
        $columns = $this->_sm->listTableColumns($tableName);
841
842
        self::assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['col_int']->getType());
843
        self::assertEquals(666, $columns['col_int']->getDefault());
844
845
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['col_string']->getType());
846
        self::assertEquals('foo', $columns['col_string']->getDefault());
847
    }
848
849
    /**
850
     * @group DBAL-197
851
     */
852
    public function testListTableWithBlob()
853
    {
854
        $table = new Table('test_blob_table');
855
        $table->addColumn('id', 'integer', ['comment' => 'This is a comment']);
856
        $table->addColumn('binarydata', 'blob', []);
857
        $table->setPrimaryKey(['id']);
858
859
        $this->_sm->createTable($table);
860
861
        $created = $this->_sm->listTableDetails('test_blob_table');
862
863
        self::assertTrue($created->hasColumn('id'));
864
        self::assertTrue($created->hasColumn('binarydata'));
865
        self::assertTrue($created->hasPrimaryKey());
866
    }
867
868
    /**
869
     * @param string $name
870
     * @param array $data
871
     * @return Table
872
     */
873
    protected function createTestTable($name = 'test_table', $data = array())
874
    {
875
        $options = array();
876
        if (isset($data['options'])) {
877
            $options = $data['options'];
878
        }
879
880
        $table = $this->getTestTable($name, $options);
881
882
        $this->_sm->dropAndCreateTable($table);
883
884
        return $table;
885
    }
886
887
    protected function getTestTable($name, $options=array())
888
    {
889
        $table = new Table($name, array(), array(), array(), false, $options);
890
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
891
        $table->addColumn('id', 'integer', array('notnull' => true));
892
        $table->setPrimaryKey(array('id'));
893
        $table->addColumn('test', 'string', array('length' => 255));
894
        $table->addColumn('foreign_key_test', 'integer');
895
        return $table;
896
    }
897
898
    protected function getTestCompositeTable($name)
899
    {
900
        $table = new Table($name, array(), array(), array(), false, array());
901
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
902
        $table->addColumn('id', 'integer', array('notnull' => true));
903
        $table->addColumn('other_id', 'integer', array('notnull' => true));
904
        $table->setPrimaryKey(array('id', 'other_id'));
905
        $table->addColumn('test', 'string', array('length' => 255));
906
        return $table;
907
    }
908
909
    protected function assertHasTable($tables, $tableName)
910
    {
911
        $foundTable = false;
912 View Code Duplication
        foreach ($tables as $table) {
913
            self::assertInstanceOf('Doctrine\DBAL\Schema\Table', $table, 'No Table instance was found in tables array.');
914
            if (strtolower($table->getName()) == 'list_tables_test_new_name') {
915
                $foundTable = true;
916
            }
917
        }
918
        self::assertTrue($foundTable, "Could not find new table");
919
    }
920
921
    public function testListForeignKeysComposite()
922
    {
923
        if(!$this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
924
            $this->markTestSkipped('Does not support foreign key constraints.');
925
        }
926
927
        $this->_sm->createTable($this->getTestTable('test_create_fk3'));
928
        $this->_sm->createTable($this->getTestCompositeTable('test_create_fk4'));
929
930
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
931
            array('id', 'foreign_key_test'), 'test_create_fk4', array('id', 'other_id'), 'foreign_key_test_fk2'
932
        );
933
934
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk3');
935
936
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk3');
937
938
        self::assertEquals(1, count($fkeys), "Table 'test_create_fk3' has to have one foreign key.");
939
940
        self::assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
941
        self::assertEquals(array('id', 'foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns()));
942
        self::assertEquals(array('id', 'other_id'),         array_map('strtolower', $fkeys[0]->getForeignColumns()));
943
    }
944
945
    /**
946
     * @group DBAL-44
947
     */
948
    public function testColumnDefaultLifecycle()
949
    {
950
        $table = new Table("col_def_lifecycle");
951
        $table->addColumn('id', 'integer', array('primary' => true, 'autoincrement' => true));
952
        $table->addColumn('column1', 'string', array('default' => null));
953
        $table->addColumn('column2', 'string', array('default' => false));
954
        $table->addColumn('column3', 'string', array('default' => true));
955
        $table->addColumn('column4', 'string', array('default' => 0));
956
        $table->addColumn('column5', 'string', array('default' => ''));
957
        $table->addColumn('column6', 'string', array('default' => 'def'));
958
        $table->addColumn('column7', 'integer', array('default' => 0));
959
        $table->setPrimaryKey(array('id'));
960
961
        $this->_sm->dropAndCreateTable($table);
962
963
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
964
965
        self::assertNull($columns['id']->getDefault());
966
        self::assertNull($columns['column1']->getDefault());
967
        self::assertSame('', $columns['column2']->getDefault());
968
        self::assertSame('1', $columns['column3']->getDefault());
969
        self::assertSame('0', $columns['column4']->getDefault());
970
        self::assertSame('', $columns['column5']->getDefault());
971
        self::assertSame('def', $columns['column6']->getDefault());
972
        self::assertSame('0', $columns['column7']->getDefault());
973
974
        $diffTable = clone $table;
975
976
        $diffTable->changeColumn('column1', array('default' => false));
977
        $diffTable->changeColumn('column2', array('default' => null));
978
        $diffTable->changeColumn('column3', array('default' => false));
979
        $diffTable->changeColumn('column4', array('default' => null));
980
        $diffTable->changeColumn('column5', array('default' => false));
981
        $diffTable->changeColumn('column6', array('default' => 666));
982
        $diffTable->changeColumn('column7', array('default' => null));
983
984
        $comparator = new Comparator();
985
986
        $this->_sm->alterTable($comparator->diffTable($table, $diffTable));
987
988
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
989
990
        self::assertSame('', $columns['column1']->getDefault());
991
        self::assertNull($columns['column2']->getDefault());
992
        self::assertSame('', $columns['column3']->getDefault());
993
        self::assertNull($columns['column4']->getDefault());
994
        self::assertSame('', $columns['column5']->getDefault());
995
        self::assertSame('666', $columns['column6']->getDefault());
996
        self::assertNull($columns['column7']->getDefault());
997
    }
998
999 View Code Duplication
    public function testListTableWithBinary()
1000
    {
1001
        $tableName = 'test_binary_table';
1002
1003
        $table = new Table($tableName);
1004
        $table->addColumn('id', 'integer');
1005
        $table->addColumn('column_varbinary', 'binary', array());
1006
        $table->addColumn('column_binary', 'binary', array('fixed' => true));
1007
        $table->setPrimaryKey(array('id'));
1008
1009
        $this->_sm->createTable($table);
1010
1011
        $table = $this->_sm->listTableDetails($tableName);
1012
1013
        self::assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_varbinary')->getType());
1014
        self::assertFalse($table->getColumn('column_varbinary')->getFixed());
1015
1016
        self::assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_binary')->getType());
1017
        self::assertTrue($table->getColumn('column_binary')->getFixed());
1018
    }
1019
1020
    public function testListTableDetailsWithFullQualifiedTableName()
1021
    {
1022
        if ( ! $this->_sm->getDatabasePlatform()->supportsSchemas()) {
1023
            $this->markTestSkipped('Test only works on platforms that support schemas.');
1024
        }
1025
1026
        $defaultSchemaName = $this->_sm->getDatabasePlatform()->getDefaultSchemaName();
1027
        $primaryTableName  = 'primary_table';
1028
        $foreignTableName  = 'foreign_table';
1029
1030
        $table = new Table($foreignTableName);
1031
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1032
        $table->setPrimaryKey(array('id'));
1033
1034
        $this->_sm->dropAndCreateTable($table);
1035
1036
        $table = new Table($primaryTableName);
1037
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1038
        $table->addColumn('foo', 'integer');
1039
        $table->addColumn('bar', 'string');
1040
        $table->addForeignKeyConstraint($foreignTableName, array('foo'), array('id'));
1041
        $table->addIndex(array('bar'));
1042
        $table->setPrimaryKey(array('id'));
1043
1044
        $this->_sm->dropAndCreateTable($table);
1045
1046
        self::assertEquals(
1047
            $this->_sm->listTableColumns($primaryTableName),
1048
            $this->_sm->listTableColumns($defaultSchemaName . '.' . $primaryTableName)
1049
        );
1050
        self::assertEquals(
1051
            $this->_sm->listTableIndexes($primaryTableName),
1052
            $this->_sm->listTableIndexes($defaultSchemaName . '.' . $primaryTableName)
1053
        );
1054
        self::assertEquals(
1055
            $this->_sm->listTableForeignKeys($primaryTableName),
1056
            $this->_sm->listTableForeignKeys($defaultSchemaName . '.' . $primaryTableName)
1057
        );
1058
    }
1059
1060
    public function testCommentStringsAreQuoted()
1061
    {
1062 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
1063
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
1064
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1065
            $this->markTestSkipped('Database does not support column comments.');
1066
        }
1067
1068
        $table = new Table('my_table');
1069
        $table->addColumn('id', 'integer', array('comment' => "It's a comment with a quote"));
1070
        $table->setPrimaryKey(array('id'));
1071
1072
        $this->_sm->createTable($table);
1073
1074
        $columns = $this->_sm->listTableColumns("my_table");
1075
        self::assertEquals("It's a comment with a quote", $columns['id']->getComment());
1076
    }
1077
1078
    public function testCommentNotDuplicated()
1079
    {
1080
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments()) {
1081
            $this->markTestSkipped('Database does not support column comments.');
1082
        }
1083
1084
        $options = array(
1085
            'type' => Type::getType('integer'),
1086
            'default' => 0,
1087
            'notnull' => true,
1088
            'comment' => 'expected+column+comment',
1089
        );
1090
        $columnDefinition = substr($this->_conn->getDatabasePlatform()->getColumnDeclarationSQL('id', $options), strlen('id') + 1);
1091
1092
        $table = new Table('my_table');
1093
        $table->addColumn('id', 'integer', array('columnDefinition' => $columnDefinition, 'comment' => 'unexpected_column_comment'));
1094
        $sql = $this->_conn->getDatabasePlatform()->getCreateTableSQL($table);
1095
1096
        self::assertContains('expected+column+comment', $sql[0]);
1097
        self::assertNotContains('unexpected_column_comment', $sql[0]);
1098
    }
1099
1100
    /**
1101
     * @group DBAL-1009
1102
     *
1103
     * @dataProvider getAlterColumnComment
1104
     */
1105
    public function testAlterColumnComment($comment1, $expectedComment1, $comment2, $expectedComment2)
1106
    {
1107 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
1108
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
1109
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1110
            $this->markTestSkipped('Database does not support column comments.');
1111
        }
1112
1113
        $offlineTable = new Table('alter_column_comment_test');
1114
        $offlineTable->addColumn('comment1', 'integer', array('comment' => $comment1));
1115
        $offlineTable->addColumn('comment2', 'integer', array('comment' => $comment2));
1116
        $offlineTable->addColumn('no_comment1', 'integer');
1117
        $offlineTable->addColumn('no_comment2', 'integer');
1118
        $this->_sm->dropAndCreateTable($offlineTable);
1119
1120
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1121
1122
        self::assertSame($expectedComment1, $onlineTable->getColumn('comment1')->getComment());
1123
        self::assertSame($expectedComment2, $onlineTable->getColumn('comment2')->getComment());
1124
        self::assertNull($onlineTable->getColumn('no_comment1')->getComment());
1125
        self::assertNull($onlineTable->getColumn('no_comment2')->getComment());
1126
1127
        $onlineTable->changeColumn('comment1', array('comment' => $comment2));
1128
        $onlineTable->changeColumn('comment2', array('comment' => $comment1));
1129
        $onlineTable->changeColumn('no_comment1', array('comment' => $comment1));
1130
        $onlineTable->changeColumn('no_comment2', array('comment' => $comment2));
1131
1132
        $comparator = new Comparator();
1133
1134
        $tableDiff = $comparator->diffTable($offlineTable, $onlineTable);
1135
1136
        self::assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
1137
1138
        $this->_sm->alterTable($tableDiff);
1139
1140
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1141
1142
        self::assertSame($expectedComment2, $onlineTable->getColumn('comment1')->getComment());
1143
        self::assertSame($expectedComment1, $onlineTable->getColumn('comment2')->getComment());
1144
        self::assertSame($expectedComment1, $onlineTable->getColumn('no_comment1')->getComment());
1145
        self::assertSame($expectedComment2, $onlineTable->getColumn('no_comment2')->getComment());
1146
    }
1147
1148
    public function getAlterColumnComment()
1149
    {
1150
        return array(
1151
            array(null, null, ' ', ' '),
1152
            array(null, null, '0', '0'),
1153
            array(null, null, 'foo', 'foo'),
1154
1155
            array('', null, ' ', ' '),
1156
            array('', null, '0', '0'),
1157
            array('', null, 'foo', 'foo'),
1158
1159
            array(' ', ' ', '0', '0'),
1160
            array(' ', ' ', 'foo', 'foo'),
1161
1162
            array('0', '0', 'foo', 'foo'),
1163
        );
1164
    }
1165
1166
    /**
1167
     * @group DBAL-1095
1168
     */
1169
    public function testDoesNotListIndexesImplicitlyCreatedByForeignKeys()
1170
    {
1171
        if (! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
1172
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
1173
        }
1174
1175
        $primaryTable = new Table('test_list_index_impl_primary');
1176
        $primaryTable->addColumn('id', 'integer');
1177
        $primaryTable->setPrimaryKey(array('id'));
1178
1179
        $foreignTable = new Table('test_list_index_impl_foreign');
1180
        $foreignTable->addColumn('fk1', 'integer');
1181
        $foreignTable->addColumn('fk2', 'integer');
1182
        $foreignTable->addIndex(array('fk1'), 'explicit_fk1_idx');
1183
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk1'), array('id'));
1184
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk2'), array('id'));
1185
1186
        $this->_sm->dropAndCreateTable($primaryTable);
1187
        $this->_sm->dropAndCreateTable($foreignTable);
1188
1189
        $indexes = $this->_sm->listTableIndexes('test_list_index_impl_foreign');
1190
1191
        self::assertCount(2, $indexes);
1192
        self::assertArrayHasKey('explicit_fk1_idx', $indexes);
1193
        self::assertArrayHasKey('idx_3d6c147fdc58d6c', $indexes);
1194
    }
1195
1196
    /**
1197
     * @after
1198
     */
1199
    public function removeJsonArrayTable() : void
1200
    {
1201
        if ($this->_sm->tablesExist(['json_array_test'])) {
1202
            $this->_sm->dropTable('json_array_test');
1203
        }
1204
    }
1205
1206
    /**
1207
     * @group 2782
1208
     * @group 6654
1209
     */
1210 View Code Duplication
    public function testComparatorShouldReturnFalseWhenLegacyJsonArrayColumnHasComment() : void
1211
    {
1212
        $table = new Table('json_array_test');
1213
        $table->addColumn('parameters', 'json_array');
1214
1215
        $this->_sm->createTable($table);
1216
1217
        $comparator = new Comparator();
1218
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1219
1220
        self::assertFalse($tableDiff);
1 ignored issue
show
It seems like $tableDiff can also be of type Doctrine\DBAL\Schema\TableDiff; however, parameter $condition of PHPUnit\Framework\Assert::assertFalse() does only seem to accept boolean, 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

1220
        self::assertFalse(/** @scrutinizer ignore-type */ $tableDiff);
Loading history...
1221
    }
1222
1223
    /**
1224
     * @group 2782
1225
     * @group 6654
1226
     */
1227
    public function testComparatorShouldModifyOnlyTheCommentWhenUpdatingFromJsonArrayTypeOnLegacyPlatforms() : void
1228
    {
1229
        if ($this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1230
            $this->markTestSkipped('This test is only supported on platforms that do not have native JSON type.');
1231
        }
1232
1233
        $table = new Table('json_array_test');
1234
        $table->addColumn('parameters', 'json_array');
1235
1236
        $this->_sm->createTable($table);
1237
1238
        $table = new Table('json_array_test');
1239
        $table->addColumn('parameters', 'json');
1240
1241
        $comparator = new Comparator();
1242
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1243
1244
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1245
1246
        $changedColumn = $tableDiff->changedColumns['parameters'] ?? $tableDiff->changedColumns['PARAMETERS'];
1247
1248
        self::assertSame(['comment'], $changedColumn->changedProperties);
1249
    }
1250
1251
    /**
1252
     * @group 2782
1253
     * @group 6654
1254
     */
1255 View Code Duplication
    public function testComparatorShouldAddCommentToLegacyJsonArrayTypeThatDoesNotHaveIt() : void
1256
    {
1257
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1258
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1259
        }
1260
1261
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON NOT NULL)');
1262
1263
        $table = new Table('json_array_test');
1264
        $table->addColumn('parameters', 'json_array');
1265
1266
        $comparator = new Comparator();
1267
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1268
1269
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1270
        self::assertSame(['comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1271
    }
1272
1273
    /**
1274
     * @group 2782
1275
     * @group 6654
1276
     */
1277 View Code Duplication
    public function testComparatorShouldReturnAllChangesWhenUsingLegacyJsonArrayType() : void
1278
    {
1279
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1280
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1281
        }
1282
1283
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON DEFAULT NULL)');
1284
1285
        $table = new Table('json_array_test');
1286
        $table->addColumn('parameters', 'json_array');
1287
1288
        $comparator = new Comparator();
1289
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1290
1291
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1292
        self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1293
    }
1294
1295
    /**
1296
     * @group 2782
1297
     * @group 6654
1298
     */
1299 View Code Duplication
    public function testComparatorShouldReturnAllChangesWhenUsingLegacyJsonArrayTypeEvenWhenPlatformHasJsonSupport() : void
1300
    {
1301
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1302
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1303
        }
1304
1305
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON DEFAULT NULL)');
1306
1307
        $table = new Table('json_array_test');
1308
        $table->addColumn('parameters', 'json_array');
1309
1310
        $comparator = new Comparator();
1311
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1312
1313
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1314
        self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1315
    }
1316
1317
    /**
1318
     * @group 2782
1319
     * @group 6654
1320
     */
1321
    public function testComparatorShouldNotAddCommentToJsonTypeSinceItIsTheDefaultNow() : void
1322
    {
1323
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1324
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1325
        }
1326
1327
        $this->_conn->executeQuery('CREATE TABLE json_test (parameters JSON NOT NULL)');
1328
1329
        $table = new Table('json_test');
1330
        $table->addColumn('parameters', 'json');
1331
1332
        $comparator = new Comparator();
1333
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_test'), $table);
1334
1335
        self::assertFalse($tableDiff);
1 ignored issue
show
It seems like $tableDiff can also be of type Doctrine\DBAL\Schema\TableDiff; however, parameter $condition of PHPUnit\Framework\Assert::assertFalse() does only seem to accept boolean, 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

1335
        self::assertFalse(/** @scrutinizer ignore-type */ $tableDiff);
Loading history...
1336
    }
1337
}
1338