Failed Conditions
Push — master ( 0c7452...fcc00d )
by Marco
14:49 queued 14:40
created

testCreateAndListSequences()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 34
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 23
nc 4
nop 0
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\Sequence;
12
use Doctrine\DBAL\Schema\Table;
13
use Doctrine\DBAL\Schema\TableDiff;
14
use Doctrine\DBAL\Types\Type;
15
16
class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTestCase
17
{
18
    /**
19
     * @var \Doctrine\DBAL\Schema\AbstractSchemaManager
20
     */
21
    protected $_sm;
22
23
    protected function getPlatformName()
24
    {
25
        $class = get_class($this);
26
        $e = explode('\\', $class);
27
        $testClass = end($e);
28
        $dbms = strtolower(str_replace('SchemaManagerTest', null, $testClass));
29
        return $dbms;
30
    }
31
32
    protected function setUp()
33
    {
34
        parent::setUp();
35
36
        $dbms = $this->getPlatformName();
37
38
        if ($this->_conn->getDatabasePlatform()->getName() !== $dbms) {
39
            $this->markTestSkipped(get_class($this) . ' requires the use of ' . $dbms);
40
        }
41
42
        $this->_sm = $this->_conn->getSchemaManager();
43
    }
44
45
    /**
46
     * @group DBAL-1220
47
     */
48
    public function testDropsDatabaseWithActiveConnections()
49
    {
50
        if (! $this->_sm->getDatabasePlatform()->supportsCreateDropDatabase()) {
51
            $this->markTestSkipped('Cannot drop Database client side with this Driver.');
52
        }
53
54
        $this->_sm->dropAndCreateDatabase('test_drop_database');
55
56
        $knownDatabases = $this->_sm->listDatabases();
57
        if ($this->_conn->getDatabasePlatform() instanceof OraclePlatform) {
58
            self::assertContains('TEST_DROP_DATABASE', $knownDatabases);
59
        } else {
60
            self::assertContains('test_drop_database', $knownDatabases);
61
        }
62
63
        $params = $this->_conn->getParams();
64
        if ($this->_conn->getDatabasePlatform() instanceof OraclePlatform) {
65
            $params['user'] = 'test_drop_database';
66
        } else {
67
            $params['dbname'] = 'test_drop_database';
68
        }
69
70
        $user = $params['user'] ?? null;
71
        $password = $params['password'] ?? null;
72
73
        $connection = $this->_conn->getDriver()->connect($params, $user, $password);
74
75
        self::assertInstanceOf('Doctrine\DBAL\Driver\Connection', $connection);
76
77
        $this->_sm->dropDatabase('test_drop_database');
78
79
        self::assertNotContains('test_drop_database', $this->_sm->listDatabases());
80
    }
81
82
    /**
83
     * @group DBAL-195
84
     */
85
    public function testDropAndCreateSequence()
86
    {
87
        if ( ! $this->_conn->getDatabasePlatform()->supportsSequences()) {
88
            $this->markTestSkipped($this->_conn->getDriver()->getName().' does not support sequences.');
89
        }
90
91
        $name = 'dropcreate_sequences_test_seq';
92
93
        $this->_sm->dropAndCreateSequence(new \Doctrine\DBAL\Schema\Sequence($name, 20, 10));
94
95
        self::assertTrue($this->hasElementWithName($this->_sm->listSequences(), $name));
96
    }
97
98
    private function hasElementWithName(array $items, string $name) : bool
99
    {
100
        $filteredList = array_filter(
101
            $items,
102
            function (\Doctrine\DBAL\Schema\AbstractAsset $item) use ($name) : bool {
103
                return $item->getShortestName($item->getNamespaceName()) === $name;
104
            }
105
        );
106
107
        return count($filteredList) === 1;
108
    }
109
110
    public function testListSequences()
111
    {
112
        if(!$this->_conn->getDatabasePlatform()->supportsSequences()) {
113
            $this->markTestSkipped($this->_conn->getDriver()->getName().' does not support sequences.');
114
        }
115
116
        $sequence = new \Doctrine\DBAL\Schema\Sequence('list_sequences_test_seq', 20, 10);
117
        $this->_sm->createSequence($sequence);
118
119
        $sequences = $this->_sm->listSequences();
120
121
        self::assertInternalType('array', $sequences, 'listSequences() should return an array.');
122
123
        $foundSequence = null;
124
        foreach($sequences as $sequence) {
125
            self::assertInstanceOf('Doctrine\DBAL\Schema\Sequence', $sequence, 'Array elements of listSequences() should be Sequence instances.');
126
            if(strtolower($sequence->getName()) == 'list_sequences_test_seq') {
127
                $foundSequence = $sequence;
128
            }
129
        }
130
131
        self::assertNotNull($foundSequence, "Sequence with name 'list_sequences_test_seq' was not found.");
132
        self::assertEquals(20, $foundSequence->getAllocationSize(), "Allocation Size is expected to be 20.");
0 ignored issues
show
Bug introduced by
The method getAllocationSize() does not exist on null. ( Ignorable by Annotation )

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

132
        self::assertEquals(20, $foundSequence->/** @scrutinizer ignore-call */ getAllocationSize(), "Allocation Size is expected to be 20.");

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
133
        self::assertEquals(10, $foundSequence->getInitialValue(), "Initial Value is expected to be 10.");
134
    }
135
136
    public function testListDatabases()
137
    {
138
        if (!$this->_sm->getDatabasePlatform()->supportsCreateDropDatabase()) {
139
            $this->markTestSkipped('Cannot drop Database client side with this Driver.');
140
        }
141
142
        $this->_sm->dropAndCreateDatabase('test_create_database');
143
        $databases = $this->_sm->listDatabases();
144
145
        $databases = array_map('strtolower', $databases);
146
147
        self::assertContains('test_create_database', $databases);
148
    }
149
150
    /**
151
     * @group DBAL-1058
152
     */
153
    public function testListNamespaceNames()
154
    {
155
        if (!$this->_sm->getDatabasePlatform()->supportsSchemas()) {
156
            $this->markTestSkipped('Platform does not support schemas.');
157
        }
158
159
        // Currently dropping schemas is not supported, so we have to workaround here.
160
        $namespaces = $this->_sm->listNamespaceNames();
161
        $namespaces = array_map('strtolower', $namespaces);
162
163
        if (!in_array('test_create_schema', $namespaces)) {
164
            $this->_conn->executeUpdate($this->_sm->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema'));
165
166
            $namespaces = $this->_sm->listNamespaceNames();
167
            $namespaces = array_map('strtolower', $namespaces);
168
        }
169
170
        self::assertContains('test_create_schema', $namespaces);
171
    }
172
173
    public function testListTables()
174
    {
175
        $this->createTestTable('list_tables_test');
176
        $tables = $this->_sm->listTables();
177
178
        self::assertInternalType('array', $tables);
179
        self::assertTrue(count($tables) > 0, "List Tables has to find at least one table named 'list_tables_test'.");
180
181
        $foundTable = false;
182
        foreach ($tables as $table) {
183
            self::assertInstanceOf('Doctrine\DBAL\Schema\Table', $table);
184
            if (strtolower($table->getName()) == 'list_tables_test') {
185
                $foundTable = true;
186
187
                self::assertTrue($table->hasColumn('id'));
188
                self::assertTrue($table->hasColumn('test'));
189
                self::assertTrue($table->hasColumn('foreign_key_test'));
190
            }
191
        }
192
193
        self::assertTrue( $foundTable , "The 'list_tables_test' table has to be found.");
194
    }
195
196
    public function createListTableColumns()
197
    {
198
        $table = new Table('list_table_columns');
199
        $table->addColumn('id', 'integer', array('notnull' => true));
200
        $table->addColumn('test', 'string', array('length' => 255, 'notnull' => false, 'default' => 'expected default'));
201
        $table->addColumn('foo', 'text', array('notnull' => true));
202
        $table->addColumn('bar', 'decimal', array('precision' => 10, 'scale' => 4, 'notnull' => false));
203
        $table->addColumn('baz1', 'datetime');
204
        $table->addColumn('baz2', 'time');
205
        $table->addColumn('baz3', 'date');
206
        $table->setPrimaryKey(array('id'));
207
208
        return $table;
209
    }
210
211
    public function testListTableColumns()
212
    {
213
        $table = $this->createListTableColumns();
214
215
        $this->_sm->dropAndCreateTable($table);
216
217
        $columns = $this->_sm->listTableColumns('list_table_columns');
218
        $columnsKeys = array_keys($columns);
219
220
        self::assertArrayHasKey('id', $columns);
221
        self::assertEquals(0, array_search('id', $columnsKeys));
222
        self::assertEquals('id',   strtolower($columns['id']->getname()));
223
        self::assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['id']->gettype());
224
        self::assertEquals(false,  $columns['id']->getunsigned());
225
        self::assertEquals(true,   $columns['id']->getnotnull());
226
        self::assertEquals(null,   $columns['id']->getdefault());
227
        self::assertInternalType('array',  $columns['id']->getPlatformOptions());
228
229
        self::assertArrayHasKey('test', $columns);
230
        self::assertEquals(1, array_search('test', $columnsKeys));
231
        self::assertEquals('test', strtolower($columns['test']->getname()));
232
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['test']->gettype());
233
        self::assertEquals(255,    $columns['test']->getlength());
234
        self::assertEquals(false,  $columns['test']->getfixed());
235
        self::assertEquals(false,  $columns['test']->getnotnull());
236
        self::assertEquals('expected default',   $columns['test']->getdefault());
237
        self::assertInternalType('array',  $columns['test']->getPlatformOptions());
238
239
        self::assertEquals('foo',  strtolower($columns['foo']->getname()));
240
        self::assertEquals(2, array_search('foo', $columnsKeys));
241
        self::assertInstanceOf('Doctrine\DBAL\Types\TextType', $columns['foo']->gettype());
242
        self::assertEquals(false,  $columns['foo']->getunsigned());
243
        self::assertEquals(false,  $columns['foo']->getfixed());
244
        self::assertEquals(true,   $columns['foo']->getnotnull());
245
        self::assertEquals(null,   $columns['foo']->getdefault());
246
        self::assertInternalType('array',  $columns['foo']->getPlatformOptions());
247
248
        self::assertEquals('bar',  strtolower($columns['bar']->getname()));
249
        self::assertEquals(3, array_search('bar', $columnsKeys));
250
        self::assertInstanceOf('Doctrine\DBAL\Types\DecimalType', $columns['bar']->gettype());
251
        self::assertEquals(null,   $columns['bar']->getlength());
252
        self::assertEquals(10,     $columns['bar']->getprecision());
253
        self::assertEquals(4,      $columns['bar']->getscale());
254
        self::assertEquals(false,  $columns['bar']->getunsigned());
255
        self::assertEquals(false,  $columns['bar']->getfixed());
256
        self::assertEquals(false,  $columns['bar']->getnotnull());
257
        self::assertEquals(null,   $columns['bar']->getdefault());
258
        self::assertInternalType('array',  $columns['bar']->getPlatformOptions());
259
260
        self::assertEquals('baz1', strtolower($columns['baz1']->getname()));
261
        self::assertEquals(4, array_search('baz1', $columnsKeys));
262
        self::assertInstanceOf('Doctrine\DBAL\Types\DateTimeType', $columns['baz1']->gettype());
263
        self::assertEquals(true,   $columns['baz1']->getnotnull());
264
        self::assertEquals(null,   $columns['baz1']->getdefault());
265
        self::assertInternalType('array',  $columns['baz1']->getPlatformOptions());
266
267
        self::assertEquals('baz2', strtolower($columns['baz2']->getname()));
268
        self::assertEquals(5, array_search('baz2', $columnsKeys));
269
        self::assertContains($columns['baz2']->gettype()->getName(), array('time', 'date', 'datetime'));
270
        self::assertEquals(true,   $columns['baz2']->getnotnull());
271
        self::assertEquals(null,   $columns['baz2']->getdefault());
272
        self::assertInternalType('array',  $columns['baz2']->getPlatformOptions());
273
274
        self::assertEquals('baz3', strtolower($columns['baz3']->getname()));
275
        self::assertEquals(6, array_search('baz3', $columnsKeys));
276
        self::assertContains($columns['baz3']->gettype()->getName(), array('time', 'date', 'datetime'));
277
        self::assertEquals(true,   $columns['baz3']->getnotnull());
278
        self::assertEquals(null,   $columns['baz3']->getdefault());
279
        self::assertInternalType('array',  $columns['baz3']->getPlatformOptions());
280
    }
281
282
    /**
283
     * @group DBAL-1078
284
     */
285 View Code Duplication
    public function testListTableColumnsWithFixedStringColumn()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
286
    {
287
        $tableName = 'test_list_table_fixed_string';
288
289
        $table = new Table($tableName);
290
        $table->addColumn('column_char', 'string', array('fixed' => true, 'length' => 2));
291
292
        $this->_sm->createTable($table);
293
294
        $columns = $this->_sm->listTableColumns($tableName);
295
296
        self::assertArrayHasKey('column_char', $columns);
297
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['column_char']->getType());
298
        self::assertTrue($columns['column_char']->getFixed());
299
        self::assertSame(2, $columns['column_char']->getLength());
300
    }
301
302
    public function testListTableColumnsDispatchEvent()
303
    {
304
        $table = $this->createListTableColumns();
305
306
        $this->_sm->dropAndCreateTable($table);
307
308
        $listenerMock = $this
309
            ->getMockBuilder('ListTableColumnsDispatchEventListener')
310
            ->setMethods(['onSchemaColumnDefinition'])
311
            ->getMock();
312
        $listenerMock
313
            ->expects($this->exactly(7))
314
            ->method('onSchemaColumnDefinition');
315
316
        $oldEventManager = $this->_sm->getDatabasePlatform()->getEventManager();
317
318
        $eventManager = new EventManager();
319
        $eventManager->addEventListener(array(Events::onSchemaColumnDefinition), $listenerMock);
320
321
        $this->_sm->getDatabasePlatform()->setEventManager($eventManager);
322
323
        $this->_sm->listTableColumns('list_table_columns');
324
325
        $this->_sm->getDatabasePlatform()->setEventManager($oldEventManager);
326
    }
327
328
    public function testListTableIndexesDispatchEvent()
329
    {
330
        $table = $this->getTestTable('list_table_indexes_test');
331
        $table->addUniqueIndex(array('test'), 'test_index_name');
332
        $table->addIndex(array('id', 'test'), 'test_composite_idx');
333
334
        $this->_sm->dropAndCreateTable($table);
335
336
        $listenerMock = $this
337
            ->getMockBuilder('ListTableIndexesDispatchEventListener')
338
            ->setMethods(['onSchemaIndexDefinition'])
339
            ->getMock();
340
        $listenerMock
341
            ->expects($this->exactly(3))
342
            ->method('onSchemaIndexDefinition');
343
344
        $oldEventManager = $this->_sm->getDatabasePlatform()->getEventManager();
345
346
        $eventManager = new EventManager();
347
        $eventManager->addEventListener(array(Events::onSchemaIndexDefinition), $listenerMock);
348
349
        $this->_sm->getDatabasePlatform()->setEventManager($eventManager);
350
351
        $this->_sm->listTableIndexes('list_table_indexes_test');
352
353
        $this->_sm->getDatabasePlatform()->setEventManager($oldEventManager);
354
    }
355
356
    public function testDiffListTableColumns()
357
    {
358
        if ($this->_sm->getDatabasePlatform()->getName() == 'oracle') {
359
            $this->markTestSkipped('Does not work with Oracle, since it cannot detect DateTime, Date and Time differenecs (at the moment).');
360
        }
361
362
        $offlineTable = $this->createListTableColumns();
363
        $this->_sm->dropAndCreateTable($offlineTable);
364
        $onlineTable = $this->_sm->listTableDetails('list_table_columns');
365
366
        $comparator = new \Doctrine\DBAL\Schema\Comparator();
367
        $diff = $comparator->diffTable($offlineTable, $onlineTable);
368
369
        self::assertFalse($diff, "No differences should be detected with the offline vs online schema.");
0 ignored issues
show
Bug introduced by
$diff of type Doctrine\DBAL\Schema\TableDiff is incompatible with the type boolean expected by parameter $condition of PHPUnit\Framework\Assert::assertFalse(). ( Ignorable by Annotation )

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

369
        self::assertFalse(/** @scrutinizer ignore-type */ $diff, "No differences should be detected with the offline vs online schema.");
Loading history...
370
    }
371
372
    public function testListTableIndexes()
373
    {
374
        $table = $this->getTestCompositeTable('list_table_indexes_test');
375
        $table->addUniqueIndex(array('test'), 'test_index_name');
376
        $table->addIndex(array('id', 'test'), 'test_composite_idx');
377
378
        $this->_sm->dropAndCreateTable($table);
379
380
        $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test');
381
382
        self::assertEquals(3, count($tableIndexes));
383
384
        self::assertArrayHasKey('primary', $tableIndexes, 'listTableIndexes() has to return a "primary" array key.');
385
        self::assertEquals(array('id', 'other_id'), array_map('strtolower', $tableIndexes['primary']->getColumns()));
386
        self::assertTrue($tableIndexes['primary']->isUnique());
387
        self::assertTrue($tableIndexes['primary']->isPrimary());
388
389
        self::assertEquals('test_index_name', strtolower($tableIndexes['test_index_name']->getName()));
390
        self::assertEquals(array('test'), array_map('strtolower', $tableIndexes['test_index_name']->getColumns()));
391
        self::assertTrue($tableIndexes['test_index_name']->isUnique());
392
        self::assertFalse($tableIndexes['test_index_name']->isPrimary());
393
394
        self::assertEquals('test_composite_idx', strtolower($tableIndexes['test_composite_idx']->getName()));
395
        self::assertEquals(array('id', 'test'), array_map('strtolower', $tableIndexes['test_composite_idx']->getColumns()));
396
        self::assertFalse($tableIndexes['test_composite_idx']->isUnique());
397
        self::assertFalse($tableIndexes['test_composite_idx']->isPrimary());
398
    }
399
400
    public function testDropAndCreateIndex()
401
    {
402
        $table = $this->getTestTable('test_create_index');
403
        $table->addUniqueIndex(array('test'), 'test');
404
        $this->_sm->dropAndCreateTable($table);
405
406
        $this->_sm->dropAndCreateIndex($table->getIndex('test'), $table);
407
        $tableIndexes = $this->_sm->listTableIndexes('test_create_index');
408
        self::assertInternalType('array', $tableIndexes);
409
410
        self::assertEquals('test',        strtolower($tableIndexes['test']->getName()));
411
        self::assertEquals(array('test'), array_map('strtolower', $tableIndexes['test']->getColumns()));
412
        self::assertTrue($tableIndexes['test']->isUnique());
413
        self::assertFalse($tableIndexes['test']->isPrimary());
414
    }
415
416
    public function testCreateTableWithForeignKeys()
417
    {
418
        if(!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
419
            $this->markTestSkipped('Platform does not support foreign keys.');
420
        }
421
422
        $tableB = $this->getTestTable('test_foreign');
423
424
        $this->_sm->dropAndCreateTable($tableB);
425
426
        $tableA = $this->getTestTable('test_create_fk');
427
        $tableA->addForeignKeyConstraint('test_foreign', array('foreign_key_test'), array('id'));
428
429
        $this->_sm->dropAndCreateTable($tableA);
430
431
        $fkTable = $this->_sm->listTableDetails('test_create_fk');
432
        $fkConstraints = $fkTable->getForeignKeys();
433
        self::assertEquals(1, count($fkConstraints), "Table 'test_create_fk1' has to have one foreign key.");
434
435
        $fkConstraint = current($fkConstraints);
436
        self::assertInstanceOf('\Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkConstraint);
437
        self::assertEquals('test_foreign',             strtolower($fkConstraint->getForeignTableName()));
438
        self::assertEquals(array('foreign_key_test'),  array_map('strtolower', $fkConstraint->getColumns()));
439
        self::assertEquals(array('id'),                array_map('strtolower', $fkConstraint->getForeignColumns()));
440
441
        self::assertTrue($fkTable->columnsAreIndexed($fkConstraint->getColumns()), "The columns of a foreign key constraint should always be indexed.");
442
    }
443
444
    public function testListForeignKeys()
445
    {
446
        if(!$this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
447
            $this->markTestSkipped('Does not support foreign key constraints.');
448
        }
449
450
        $this->createTestTable('test_create_fk1');
451
        $this->createTestTable('test_create_fk2');
452
453
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
454
            array('foreign_key_test'), 'test_create_fk2', array('id'), 'foreign_key_test_fk', array('onDelete' => 'CASCADE')
455
        );
456
457
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk1');
458
459
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk1');
460
461
        self::assertEquals(1, count($fkeys), "Table 'test_create_fk1' has to have one foreign key.");
462
463
        self::assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
464
        self::assertEquals(array('foreign_key_test'),  array_map('strtolower', $fkeys[0]->getLocalColumns()));
465
        self::assertEquals(array('id'),                array_map('strtolower', $fkeys[0]->getForeignColumns()));
466
        self::assertEquals('test_create_fk2',          strtolower($fkeys[0]->getForeignTableName()));
467
468
        if($fkeys[0]->hasOption('onDelete')) {
469
            self::assertEquals('CASCADE', $fkeys[0]->getOption('onDelete'));
470
        }
471
    }
472
473
    protected function getCreateExampleViewSql()
474
    {
475
        $this->markTestSkipped('No Create Example View SQL was defined for this SchemaManager');
476
    }
477
478
    public function testCreateSchema()
479
    {
480
        $this->createTestTable('test_table');
481
482
        $schema = $this->_sm->createSchema();
483
        self::assertTrue($schema->hasTable('test_table'));
484
    }
485
486
    public function testAlterTableScenario()
487
    {
488
        if(!$this->_sm->getDatabasePlatform()->supportsAlterTable()) {
489
            $this->markTestSkipped('Alter Table is not supported by this platform.');
490
        }
491
492
        $alterTable = $this->createTestTable('alter_table');
493
        $this->createTestTable('alter_table_foreign');
494
495
        $table = $this->_sm->listTableDetails('alter_table');
496
        self::assertTrue($table->hasColumn('id'));
497
        self::assertTrue($table->hasColumn('test'));
498
        self::assertTrue($table->hasColumn('foreign_key_test'));
499
        self::assertEquals(0, count($table->getForeignKeys()));
500
        self::assertEquals(1, count($table->getIndexes()));
501
502
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
503
        $tableDiff->fromTable = $alterTable;
504
        $tableDiff->addedColumns['foo'] = new \Doctrine\DBAL\Schema\Column('foo', Type::getType('integer'));
505
        $tableDiff->removedColumns['test'] = $table->getColumn('test');
506
507
        $this->_sm->alterTable($tableDiff);
508
509
        $table = $this->_sm->listTableDetails('alter_table');
510
        self::assertFalse($table->hasColumn('test'));
511
        self::assertTrue($table->hasColumn('foo'));
512
513
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
514
        $tableDiff->fromTable = $table;
515
        $tableDiff->addedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo'));
516
517
        $this->_sm->alterTable($tableDiff);
518
519
        $table = $this->_sm->listTableDetails('alter_table');
520
        self::assertEquals(2, count($table->getIndexes()));
521
        self::assertTrue($table->hasIndex('foo_idx'));
522
        self::assertEquals(array('foo'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
523
        self::assertFalse($table->getIndex('foo_idx')->isPrimary());
524
        self::assertFalse($table->getIndex('foo_idx')->isUnique());
525
526
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
527
        $tableDiff->fromTable = $table;
528
        $tableDiff->changedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo', 'foreign_key_test'));
529
530
        $this->_sm->alterTable($tableDiff);
531
532
        $table = $this->_sm->listTableDetails('alter_table');
533
        self::assertEquals(2, count($table->getIndexes()));
534
        self::assertTrue($table->hasIndex('foo_idx'));
535
        self::assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
536
537
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
538
        $tableDiff->fromTable = $table;
539
        $tableDiff->renamedIndexes['foo_idx'] = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
540
541
        $this->_sm->alterTable($tableDiff);
542
543
        $table = $this->_sm->listTableDetails('alter_table');
544
        self::assertEquals(2, count($table->getIndexes()));
545
        self::assertTrue($table->hasIndex('bar_idx'));
546
        self::assertFalse($table->hasIndex('foo_idx'));
547
        self::assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('bar_idx')->getColumns()));
548
        self::assertFalse($table->getIndex('bar_idx')->isPrimary());
549
        self::assertFalse($table->getIndex('bar_idx')->isUnique());
550
551
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
552
        $tableDiff->fromTable = $table;
553
        $tableDiff->removedIndexes[] = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
554
        $fk = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(array('foreign_key_test'), 'alter_table_foreign', array('id'));
555
        $tableDiff->addedForeignKeys[] = $fk;
556
557
        $this->_sm->alterTable($tableDiff);
558
        $table = $this->_sm->listTableDetails('alter_table');
559
560
        // dont check for index size here, some platforms automatically add indexes for foreign keys.
561
        self::assertFalse($table->hasIndex('bar_idx'));
562
563
        if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
564
            $fks = $table->getForeignKeys();
565
            self::assertCount(1, $fks);
566
            $foreignKey = current($fks);
567
            self::assertEquals('alter_table_foreign', strtolower($foreignKey->getForeignTableName()));
568
            self::assertEquals(array('foreign_key_test'), array_map('strtolower', $foreignKey->getColumns()));
569
            self::assertEquals(array('id'), array_map('strtolower', $foreignKey->getForeignColumns()));
570
        }
571
    }
572
573
    public function testCreateAndListViews()
574
    {
575
        if (!$this->_sm->getDatabasePlatform()->supportsViews()) {
576
            $this->markTestSkipped('Views is not supported by this platform.');
577
        }
578
579
        $this->createTestTable('view_test_table');
580
581
        $name = "doctrine_test_view";
582
        $sql = "SELECT * FROM view_test_table";
583
584
        $view = new \Doctrine\DBAL\Schema\View($name, $sql);
585
586
        $this->_sm->dropAndCreateView($view);
587
588
        self::assertTrue($this->hasElementWithName($this->_sm->listViews(), $name));
589
    }
590
591 View Code Duplication
    public function testAutoincrementDetection()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
592
    {
593
        if (!$this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
594
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
595
        }
596
597
        $table = new Table('test_autoincrement');
598
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
599
        $table->addColumn('id', 'integer', array('autoincrement' => true));
600
        $table->setPrimaryKey(array('id'));
601
602
        $this->_sm->createTable($table);
603
604
        $inferredTable = $this->_sm->listTableDetails('test_autoincrement');
605
        self::assertTrue($inferredTable->hasColumn('id'));
606
        self::assertTrue($inferredTable->getColumn('id')->getAutoincrement());
607
    }
608
609
    /**
610
     * @group DBAL-792
611
     */
612 View Code Duplication
    public function testAutoincrementDetectionMulticolumns()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
613
    {
614
        if (!$this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
615
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
616
        }
617
618
        $table = new Table('test_not_autoincrement');
619
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
620
        $table->addColumn('id', 'integer');
621
        $table->addColumn('other_id', 'integer');
622
        $table->setPrimaryKey(array('id', 'other_id'));
623
624
        $this->_sm->createTable($table);
625
626
        $inferredTable = $this->_sm->listTableDetails('test_not_autoincrement');
627
        self::assertTrue($inferredTable->hasColumn('id'));
628
        self::assertFalse($inferredTable->getColumn('id')->getAutoincrement());
629
    }
630
631
    /**
632
     * @group DDC-887
633
     */
634
    public function testUpdateSchemaWithForeignKeyRenaming()
635
    {
636
        if (!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
637
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
638
        }
639
640
        $table = new Table('test_fk_base');
641
        $table->addColumn('id', 'integer');
642
        $table->setPrimaryKey(array('id'));
643
644
        $tableFK = new Table('test_fk_rename');
645
        $tableFK->setSchemaConfig($this->_sm->createSchemaConfig());
646
        $tableFK->addColumn('id', 'integer');
647
        $tableFK->addColumn('fk_id', 'integer');
648
        $tableFK->setPrimaryKey(array('id'));
649
        $tableFK->addIndex(array('fk_id'), 'fk_idx');
650
        $tableFK->addForeignKeyConstraint('test_fk_base', array('fk_id'), array('id'));
651
652
        $this->_sm->createTable($table);
653
        $this->_sm->createTable($tableFK);
654
655
        $tableFKNew = new Table('test_fk_rename');
656
        $tableFKNew->setSchemaConfig($this->_sm->createSchemaConfig());
657
        $tableFKNew->addColumn('id', 'integer');
658
        $tableFKNew->addColumn('rename_fk_id', 'integer');
659
        $tableFKNew->setPrimaryKey(array('id'));
660
        $tableFKNew->addIndex(array('rename_fk_id'), 'fk_idx');
661
        $tableFKNew->addForeignKeyConstraint('test_fk_base', array('rename_fk_id'), array('id'));
662
663
        $c = new \Doctrine\DBAL\Schema\Comparator();
664
        $tableDiff = $c->diffTable($tableFK, $tableFKNew);
665
666
        $this->_sm->alterTable($tableDiff);
667
668
        $table       = $this->_sm->listTableDetails('test_fk_rename');
669
        $foreignKeys = $table->getForeignKeys();
670
671
        self::assertTrue($table->hasColumn('rename_fk_id'));
672
        self::assertCount(1, $foreignKeys);
673
        self::assertSame(['rename_fk_id'], array_map('strtolower', current($foreignKeys)->getColumns()));
674
    }
675
676
    /**
677
     * @group DBAL-1062
678
     */
679
    public function testRenameIndexUsedInForeignKeyConstraint()
680
    {
681
        if (! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
682
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
683
        }
684
685
        $primaryTable = new Table('test_rename_index_primary');
686
        $primaryTable->addColumn('id', 'integer');
687
        $primaryTable->setPrimaryKey(array('id'));
688
689
        $foreignTable = new Table('test_rename_index_foreign');
690
        $foreignTable->addColumn('fk', 'integer');
691
        $foreignTable->addIndex(array('fk'), 'rename_index_fk_idx');
692
        $foreignTable->addForeignKeyConstraint(
693
            'test_rename_index_primary',
694
            array('fk'),
695
            array('id'),
696
            array(),
697
            'fk_constraint'
698
        );
699
700
        $this->_sm->dropAndCreateTable($primaryTable);
701
        $this->_sm->dropAndCreateTable($foreignTable);
702
703
        $foreignTable2 = clone $foreignTable;
704
        $foreignTable2->renameIndex('rename_index_fk_idx', 'renamed_index_fk_idx');
705
706
        $comparator = new Comparator();
707
708
        $this->_sm->alterTable($comparator->diffTable($foreignTable, $foreignTable2));
709
710
        $foreignTable = $this->_sm->listTableDetails('test_rename_index_foreign');
711
712
        self::assertFalse($foreignTable->hasIndex('rename_index_fk_idx'));
713
        self::assertTrue($foreignTable->hasIndex('renamed_index_fk_idx'));
714
        self::assertTrue($foreignTable->hasForeignKey('fk_constraint'));
715
    }
716
717
    /**
718
     * @group DBAL-42
719
     */
720
    public function testGetColumnComment()
721
    {
722 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
723
             ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
724
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
725
            $this->markTestSkipped('Database does not support column comments.');
726
        }
727
728
        $table = new Table('column_comment_test');
729
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
730
        $table->setPrimaryKey(array('id'));
731
732
        $this->_sm->createTable($table);
733
734
        $columns = $this->_sm->listTableColumns("column_comment_test");
735
        self::assertEquals(1, count($columns));
736
        self::assertEquals('This is a comment', $columns['id']->getComment());
737
738
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff('column_comment_test');
739
        $tableDiff->fromTable = $table;
740
        $tableDiff->changedColumns['id'] = new \Doctrine\DBAL\Schema\ColumnDiff(
741
            'id', new \Doctrine\DBAL\Schema\Column(
742
                'id', \Doctrine\DBAL\Types\Type::getType('integer')
743
            ),
744
            array('comment'),
745
            new \Doctrine\DBAL\Schema\Column(
746
                'id', \Doctrine\DBAL\Types\Type::getType('integer'), array('comment' => 'This is a comment')
747
            )
748
        );
749
750
        $this->_sm->alterTable($tableDiff);
751
752
        $columns = $this->_sm->listTableColumns("column_comment_test");
753
        self::assertEquals(1, count($columns));
754
        self::assertEmpty($columns['id']->getComment());
755
    }
756
757
    /**
758
     * @group DBAL-42
759
     */
760
    public function testAutomaticallyAppendCommentOnMarkedColumns()
761
    {
762 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
763
             ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
764
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
765
            $this->markTestSkipped('Database does not support column comments.');
766
        }
767
768
        $table = new Table('column_comment_test2');
769
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
770
        $table->addColumn('obj', 'object', array('comment' => 'This is a comment'));
771
        $table->addColumn('arr', 'array', array('comment' => 'This is a comment'));
772
        $table->setPrimaryKey(array('id'));
773
774
        $this->_sm->createTable($table);
775
776
        $columns = $this->_sm->listTableColumns("column_comment_test2");
777
        self::assertEquals(3, count($columns));
778
        self::assertEquals('This is a comment', $columns['id']->getComment());
779
        self::assertEquals('This is a comment', $columns['obj']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
780
        self::assertInstanceOf('Doctrine\DBAL\Types\ObjectType', $columns['obj']->getType(), "The Doctrine2 should be detected from comment hint.");
781
        self::assertEquals('This is a comment', $columns['arr']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
782
        self::assertInstanceOf('Doctrine\DBAL\Types\ArrayType', $columns['arr']->getType(), "The Doctrine2 should be detected from comment hint.");
783
    }
784
785
    /**
786
     * @group DBAL-1228
787
     */
788
    public function testCommentHintOnDateIntervalTypeColumn()
789
    {
790 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
791
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
792
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
793
            $this->markTestSkipped('Database does not support column comments.');
794
        }
795
796
        $table = new Table('column_dateinterval_comment');
797
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
798
        $table->addColumn('date_interval', 'dateinterval', array('comment' => 'This is a comment'));
799
        $table->setPrimaryKey(array('id'));
800
801
        $this->_sm->createTable($table);
802
803
        $columns = $this->_sm->listTableColumns("column_dateinterval_comment");
804
        self::assertEquals(2, count($columns));
805
        self::assertEquals('This is a comment', $columns['id']->getComment());
806
        self::assertEquals('This is a comment', $columns['date_interval']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
807
        self::assertInstanceOf('Doctrine\DBAL\Types\DateIntervalType', $columns['date_interval']->getType(), "The Doctrine2 should be detected from comment hint.");
808
    }
809
810
    /**
811
     * @group DBAL-825
812
     */
813
    public function testChangeColumnsTypeWithDefaultValue()
814
    {
815
        $tableName = 'column_def_change_type';
816
        $table     = new Table($tableName);
817
818
        $table->addColumn('col_int', 'smallint', array('default' => 666));
819
        $table->addColumn('col_string', 'string', array('default' => 'foo'));
820
821
        $this->_sm->dropAndCreateTable($table);
822
823
        $tableDiff = new TableDiff($tableName);
824
        $tableDiff->fromTable = $table;
825
        $tableDiff->changedColumns['col_int'] = new ColumnDiff(
826
            'col_int',
827
            new Column('col_int', Type::getType('integer'), array('default' => 666)),
828
            array('type'),
829
            new Column('col_int', Type::getType('smallint'), array('default' => 666))
830
        );
831
832
        $tableDiff->changedColumns['col_string'] = new ColumnDiff(
833
            'col_string',
834
            new Column('col_string', Type::getType('string'), array('default' => 'foo', 'fixed' => true)),
835
            array('fixed'),
836
            new Column('col_string', Type::getType('string'), array('default' => 'foo'))
837
        );
838
839
        $this->_sm->alterTable($tableDiff);
840
841
        $columns = $this->_sm->listTableColumns($tableName);
842
843
        self::assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['col_int']->getType());
844
        self::assertEquals(666, $columns['col_int']->getDefault());
845
846
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['col_string']->getType());
847
        self::assertEquals('foo', $columns['col_string']->getDefault());
848
    }
849
850
    /**
851
     * @group DBAL-197
852
     */
853
    public function testListTableWithBlob()
854
    {
855
        $table = new Table('test_blob_table');
856
        $table->addColumn('id', 'integer', ['comment' => 'This is a comment']);
857
        $table->addColumn('binarydata', 'blob', []);
858
        $table->setPrimaryKey(['id']);
859
860
        $this->_sm->createTable($table);
861
862
        $created = $this->_sm->listTableDetails('test_blob_table');
863
864
        self::assertTrue($created->hasColumn('id'));
865
        self::assertTrue($created->hasColumn('binarydata'));
866
        self::assertTrue($created->hasPrimaryKey());
867
    }
868
869
    /**
870
     * @param string $name
871
     * @param array $data
872
     * @return Table
873
     */
874
    protected function createTestTable($name = 'test_table', $data = array())
875
    {
876
        $options = array();
877
        if (isset($data['options'])) {
878
            $options = $data['options'];
879
        }
880
881
        $table = $this->getTestTable($name, $options);
882
883
        $this->_sm->dropAndCreateTable($table);
884
885
        return $table;
886
    }
887
888
    protected function getTestTable($name, $options=array())
889
    {
890
        $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

890
        $table = new Table($name, array(), array(), array(), /** @scrutinizer ignore-type */ false, $options);
Loading history...
891
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
892
        $table->addColumn('id', 'integer', array('notnull' => true));
893
        $table->setPrimaryKey(array('id'));
894
        $table->addColumn('test', 'string', array('length' => 255));
895
        $table->addColumn('foreign_key_test', 'integer');
896
        return $table;
897
    }
898
899
    protected function getTestCompositeTable($name)
900
    {
901
        $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

901
        $table = new Table($name, array(), array(), array(), /** @scrutinizer ignore-type */ false, array());
Loading history...
902
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
903
        $table->addColumn('id', 'integer', array('notnull' => true));
904
        $table->addColumn('other_id', 'integer', array('notnull' => true));
905
        $table->setPrimaryKey(array('id', 'other_id'));
906
        $table->addColumn('test', 'string', array('length' => 255));
907
        return $table;
908
    }
909
910
    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

910
    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...
911
    {
912
        $foundTable = false;
913 View Code Duplication
        foreach ($tables as $table) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
914
            self::assertInstanceOf('Doctrine\DBAL\Schema\Table', $table, 'No Table instance was found in tables array.');
915
            if (strtolower($table->getName()) == 'list_tables_test_new_name') {
916
                $foundTable = true;
917
            }
918
        }
919
        self::assertTrue($foundTable, "Could not find new table");
920
    }
921
922
    public function testListForeignKeysComposite()
923
    {
924
        if(!$this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
925
            $this->markTestSkipped('Does not support foreign key constraints.');
926
        }
927
928
        $this->_sm->createTable($this->getTestTable('test_create_fk3'));
929
        $this->_sm->createTable($this->getTestCompositeTable('test_create_fk4'));
930
931
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
932
            array('id', 'foreign_key_test'), 'test_create_fk4', array('id', 'other_id'), 'foreign_key_test_fk2'
933
        );
934
935
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk3');
936
937
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk3');
938
939
        self::assertEquals(1, count($fkeys), "Table 'test_create_fk3' has to have one foreign key.");
940
941
        self::assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
942
        self::assertEquals(array('id', 'foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns()));
943
        self::assertEquals(array('id', 'other_id'),         array_map('strtolower', $fkeys[0]->getForeignColumns()));
944
    }
945
946
    /**
947
     * @group DBAL-44
948
     */
949
    public function testColumnDefaultLifecycle()
950
    {
951
        $table = new Table("col_def_lifecycle");
952
        $table->addColumn('id', 'integer', array('autoincrement' => true));
953
        $table->addColumn('column1', 'string', array('default' => null));
954
        $table->addColumn('column2', 'string', array('default' => false));
955
        $table->addColumn('column3', 'string', array('default' => true));
956
        $table->addColumn('column4', 'string', array('default' => 0));
957
        $table->addColumn('column5', 'string', array('default' => ''));
958
        $table->addColumn('column6', 'string', array('default' => 'def'));
959
        $table->addColumn('column7', 'integer', array('default' => 0));
960
        $table->setPrimaryKey(array('id'));
961
962
        $this->_sm->dropAndCreateTable($table);
963
964
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
965
966
        self::assertNull($columns['id']->getDefault());
967
        self::assertNull($columns['column1']->getDefault());
968
        self::assertSame('', $columns['column2']->getDefault());
969
        self::assertSame('1', $columns['column3']->getDefault());
970
        self::assertSame('0', $columns['column4']->getDefault());
971
        self::assertSame('', $columns['column5']->getDefault());
972
        self::assertSame('def', $columns['column6']->getDefault());
973
        self::assertSame('0', $columns['column7']->getDefault());
974
975
        $diffTable = clone $table;
976
977
        $diffTable->changeColumn('column1', array('default' => false));
978
        $diffTable->changeColumn('column2', array('default' => null));
979
        $diffTable->changeColumn('column3', array('default' => false));
980
        $diffTable->changeColumn('column4', array('default' => null));
981
        $diffTable->changeColumn('column5', array('default' => false));
982
        $diffTable->changeColumn('column6', array('default' => 666));
983
        $diffTable->changeColumn('column7', array('default' => null));
984
985
        $comparator = new Comparator();
986
987
        $this->_sm->alterTable($comparator->diffTable($table, $diffTable));
988
989
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
990
991
        self::assertSame('', $columns['column1']->getDefault());
992
        self::assertNull($columns['column2']->getDefault());
993
        self::assertSame('', $columns['column3']->getDefault());
994
        self::assertNull($columns['column4']->getDefault());
995
        self::assertSame('', $columns['column5']->getDefault());
996
        self::assertSame('666', $columns['column6']->getDefault());
997
        self::assertNull($columns['column7']->getDefault());
998
    }
999
1000 View Code Duplication
    public function testListTableWithBinary()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1001
    {
1002
        $tableName = 'test_binary_table';
1003
1004
        $table = new Table($tableName);
1005
        $table->addColumn('id', 'integer');
1006
        $table->addColumn('column_varbinary', 'binary', array());
1007
        $table->addColumn('column_binary', 'binary', array('fixed' => true));
1008
        $table->setPrimaryKey(array('id'));
1009
1010
        $this->_sm->createTable($table);
1011
1012
        $table = $this->_sm->listTableDetails($tableName);
1013
1014
        self::assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_varbinary')->getType());
1015
        self::assertFalse($table->getColumn('column_varbinary')->getFixed());
1016
1017
        self::assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_binary')->getType());
1018
        self::assertTrue($table->getColumn('column_binary')->getFixed());
1019
    }
1020
1021
    public function testListTableDetailsWithFullQualifiedTableName()
1022
    {
1023
        if ( ! $this->_sm->getDatabasePlatform()->supportsSchemas()) {
1024
            $this->markTestSkipped('Test only works on platforms that support schemas.');
1025
        }
1026
1027
        $defaultSchemaName = $this->_sm->getDatabasePlatform()->getDefaultSchemaName();
1028
        $primaryTableName  = 'primary_table';
1029
        $foreignTableName  = 'foreign_table';
1030
1031
        $table = new Table($foreignTableName);
1032
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1033
        $table->setPrimaryKey(array('id'));
1034
1035
        $this->_sm->dropAndCreateTable($table);
1036
1037
        $table = new Table($primaryTableName);
1038
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1039
        $table->addColumn('foo', 'integer');
1040
        $table->addColumn('bar', 'string');
1041
        $table->addForeignKeyConstraint($foreignTableName, array('foo'), array('id'));
1042
        $table->addIndex(array('bar'));
1043
        $table->setPrimaryKey(array('id'));
1044
1045
        $this->_sm->dropAndCreateTable($table);
1046
1047
        self::assertEquals(
1048
            $this->_sm->listTableColumns($primaryTableName),
1049
            $this->_sm->listTableColumns($defaultSchemaName . '.' . $primaryTableName)
1050
        );
1051
        self::assertEquals(
1052
            $this->_sm->listTableIndexes($primaryTableName),
1053
            $this->_sm->listTableIndexes($defaultSchemaName . '.' . $primaryTableName)
1054
        );
1055
        self::assertEquals(
1056
            $this->_sm->listTableForeignKeys($primaryTableName),
1057
            $this->_sm->listTableForeignKeys($defaultSchemaName . '.' . $primaryTableName)
1058
        );
1059
    }
1060
1061
    public function testCommentStringsAreQuoted()
1062
    {
1063 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1064
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
1065
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1066
            $this->markTestSkipped('Database does not support column comments.');
1067
        }
1068
1069
        $table = new Table('my_table');
1070
        $table->addColumn('id', 'integer', array('comment' => "It's a comment with a quote"));
1071
        $table->setPrimaryKey(array('id'));
1072
1073
        $this->_sm->createTable($table);
1074
1075
        $columns = $this->_sm->listTableColumns("my_table");
1076
        self::assertEquals("It's a comment with a quote", $columns['id']->getComment());
1077
    }
1078
1079
    public function testCommentNotDuplicated()
1080
    {
1081
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments()) {
1082
            $this->markTestSkipped('Database does not support column comments.');
1083
        }
1084
1085
        $options = array(
1086
            'type' => Type::getType('integer'),
1087
            'default' => 0,
1088
            'notnull' => true,
1089
            'comment' => 'expected+column+comment',
1090
        );
1091
        $columnDefinition = substr($this->_conn->getDatabasePlatform()->getColumnDeclarationSQL('id', $options), strlen('id') + 1);
1092
1093
        $table = new Table('my_table');
1094
        $table->addColumn('id', 'integer', array('columnDefinition' => $columnDefinition, 'comment' => 'unexpected_column_comment'));
1095
        $sql = $this->_conn->getDatabasePlatform()->getCreateTableSQL($table);
1096
1097
        self::assertContains('expected+column+comment', $sql[0]);
1098
        self::assertNotContains('unexpected_column_comment', $sql[0]);
1099
    }
1100
1101
    /**
1102
     * @group DBAL-1009
1103
     *
1104
     * @dataProvider getAlterColumnComment
1105
     */
1106
    public function testAlterColumnComment($comment1, $expectedComment1, $comment2, $expectedComment2)
1107
    {
1108 View Code Duplication
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1109
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
1110
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1111
            $this->markTestSkipped('Database does not support column comments.');
1112
        }
1113
1114
        $offlineTable = new Table('alter_column_comment_test');
1115
        $offlineTable->addColumn('comment1', 'integer', array('comment' => $comment1));
1116
        $offlineTable->addColumn('comment2', 'integer', array('comment' => $comment2));
1117
        $offlineTable->addColumn('no_comment1', 'integer');
1118
        $offlineTable->addColumn('no_comment2', 'integer');
1119
        $this->_sm->dropAndCreateTable($offlineTable);
1120
1121
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1122
1123
        self::assertSame($expectedComment1, $onlineTable->getColumn('comment1')->getComment());
1124
        self::assertSame($expectedComment2, $onlineTable->getColumn('comment2')->getComment());
1125
        self::assertNull($onlineTable->getColumn('no_comment1')->getComment());
1126
        self::assertNull($onlineTable->getColumn('no_comment2')->getComment());
1127
1128
        $onlineTable->changeColumn('comment1', array('comment' => $comment2));
1129
        $onlineTable->changeColumn('comment2', array('comment' => $comment1));
1130
        $onlineTable->changeColumn('no_comment1', array('comment' => $comment1));
1131
        $onlineTable->changeColumn('no_comment2', array('comment' => $comment2));
1132
1133
        $comparator = new Comparator();
1134
1135
        $tableDiff = $comparator->diffTable($offlineTable, $onlineTable);
1136
1137
        self::assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
1138
1139
        $this->_sm->alterTable($tableDiff);
1140
1141
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1142
1143
        self::assertSame($expectedComment2, $onlineTable->getColumn('comment1')->getComment());
1144
        self::assertSame($expectedComment1, $onlineTable->getColumn('comment2')->getComment());
1145
        self::assertSame($expectedComment1, $onlineTable->getColumn('no_comment1')->getComment());
1146
        self::assertSame($expectedComment2, $onlineTable->getColumn('no_comment2')->getComment());
1147
    }
1148
1149
    public function getAlterColumnComment()
1150
    {
1151
        return array(
1152
            array(null, null, ' ', ' '),
1153
            array(null, null, '0', '0'),
1154
            array(null, null, 'foo', 'foo'),
1155
1156
            array('', null, ' ', ' '),
1157
            array('', null, '0', '0'),
1158
            array('', null, 'foo', 'foo'),
1159
1160
            array(' ', ' ', '0', '0'),
1161
            array(' ', ' ', 'foo', 'foo'),
1162
1163
            array('0', '0', 'foo', 'foo'),
1164
        );
1165
    }
1166
1167
    /**
1168
     * @group DBAL-1095
1169
     */
1170
    public function testDoesNotListIndexesImplicitlyCreatedByForeignKeys()
1171
    {
1172
        if (! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
1173
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
1174
        }
1175
1176
        $primaryTable = new Table('test_list_index_impl_primary');
1177
        $primaryTable->addColumn('id', 'integer');
1178
        $primaryTable->setPrimaryKey(array('id'));
1179
1180
        $foreignTable = new Table('test_list_index_impl_foreign');
1181
        $foreignTable->addColumn('fk1', 'integer');
1182
        $foreignTable->addColumn('fk2', 'integer');
1183
        $foreignTable->addIndex(array('fk1'), 'explicit_fk1_idx');
1184
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk1'), array('id'));
1185
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk2'), array('id'));
1186
1187
        $this->_sm->dropAndCreateTable($primaryTable);
1188
        $this->_sm->dropAndCreateTable($foreignTable);
1189
1190
        $indexes = $this->_sm->listTableIndexes('test_list_index_impl_foreign');
1191
1192
        self::assertCount(2, $indexes);
1193
        self::assertArrayHasKey('explicit_fk1_idx', $indexes);
1194
        self::assertArrayHasKey('idx_3d6c147fdc58d6c', $indexes);
1195
    }
1196
1197
    /**
1198
     * @after
1199
     */
1200
    public function removeJsonArrayTable() : void
1201
    {
1202
        if ($this->_sm->tablesExist(['json_array_test'])) {
1203
            $this->_sm->dropTable('json_array_test');
1204
        }
1205
    }
1206
1207
    /**
1208
     * @group 2782
1209
     * @group 6654
1210
     */
1211 View Code Duplication
    public function testComparatorShouldReturnFalseWhenLegacyJsonArrayColumnHasComment() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1212
    {
1213
        $table = new Table('json_array_test');
1214
        $table->addColumn('parameters', 'json_array');
1215
1216
        $this->_sm->createTable($table);
1217
1218
        $comparator = new Comparator();
1219
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1220
1221
        self::assertFalse($tableDiff);
0 ignored issues
show
Bug introduced by
$tableDiff of type Doctrine\DBAL\Schema\TableDiff is incompatible with the type boolean expected by parameter $condition of PHPUnit\Framework\Assert::assertFalse(). ( Ignorable by Annotation )

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

1221
        self::assertFalse(/** @scrutinizer ignore-type */ $tableDiff);
Loading history...
1222
    }
1223
1224
    /**
1225
     * @group 2782
1226
     * @group 6654
1227
     */
1228
    public function testComparatorShouldModifyOnlyTheCommentWhenUpdatingFromJsonArrayTypeOnLegacyPlatforms() : void
1229
    {
1230
        if ($this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1231
            $this->markTestSkipped('This test is only supported on platforms that do not have native JSON type.');
1232
        }
1233
1234
        $table = new Table('json_array_test');
1235
        $table->addColumn('parameters', 'json_array');
1236
1237
        $this->_sm->createTable($table);
1238
1239
        $table = new Table('json_array_test');
1240
        $table->addColumn('parameters', 'json');
1241
1242
        $comparator = new Comparator();
1243
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1244
1245
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1246
1247
        $changedColumn = $tableDiff->changedColumns['parameters'] ?? $tableDiff->changedColumns['PARAMETERS'];
1248
1249
        self::assertSame(['comment'], $changedColumn->changedProperties);
1250
    }
1251
1252
    /**
1253
     * @group 2782
1254
     * @group 6654
1255
     */
1256 View Code Duplication
    public function testComparatorShouldAddCommentToLegacyJsonArrayTypeThatDoesNotHaveIt() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1257
    {
1258
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1259
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1260
        }
1261
1262
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON NOT NULL)');
1263
1264
        $table = new Table('json_array_test');
1265
        $table->addColumn('parameters', 'json_array');
1266
1267
        $comparator = new Comparator();
1268
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1269
1270
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1271
        self::assertSame(['comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1272
    }
1273
1274
    /**
1275
     * @group 2782
1276
     * @group 6654
1277
     */
1278 View Code Duplication
    public function testComparatorShouldReturnAllChangesWhenUsingLegacyJsonArrayType() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1279
    {
1280
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1281
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1282
        }
1283
1284
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON DEFAULT NULL)');
1285
1286
        $table = new Table('json_array_test');
1287
        $table->addColumn('parameters', 'json_array');
1288
1289
        $comparator = new Comparator();
1290
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1291
1292
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1293
        self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1294
    }
1295
1296
    /**
1297
     * @group 2782
1298
     * @group 6654
1299
     */
1300 View Code Duplication
    public function testComparatorShouldReturnAllChangesWhenUsingLegacyJsonArrayTypeEvenWhenPlatformHasJsonSupport() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1301
    {
1302
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1303
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1304
        }
1305
1306
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON DEFAULT NULL)');
1307
1308
        $table = new Table('json_array_test');
1309
        $table->addColumn('parameters', 'json_array');
1310
1311
        $comparator = new Comparator();
1312
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1313
1314
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1315
        self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1316
    }
1317
1318
    /**
1319
     * @group 2782
1320
     * @group 6654
1321
     */
1322
    public function testComparatorShouldNotAddCommentToJsonTypeSinceItIsTheDefaultNow() : void
1323
    {
1324
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1325
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1326
        }
1327
1328
        $this->_conn->executeQuery('CREATE TABLE json_test (parameters JSON NOT NULL)');
1329
1330
        $table = new Table('json_test');
1331
        $table->addColumn('parameters', 'json');
1332
1333
        $comparator = new Comparator();
1334
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_test'), $table);
1335
1336
        self::assertFalse($tableDiff);
0 ignored issues
show
Bug introduced by
$tableDiff of type Doctrine\DBAL\Schema\TableDiff is incompatible with the type boolean expected by parameter $condition of PHPUnit\Framework\Assert::assertFalse(). ( Ignorable by Annotation )

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

1336
        self::assertFalse(/** @scrutinizer ignore-type */ $tableDiff);
Loading history...
1337
    }
1338
1339
    /**
1340
     * @dataProvider commentsProvider
1341
     *
1342
     * @group 2596
1343
     */
1344
    public function testExtractDoctrineTypeFromComment(string $comment, string $expected, string $currentType) : void
1345
    {
1346
        $result = $this->_sm->extractDoctrineTypeFromComment($comment, $currentType);
1347
1348
        self::assertSame($expected, $result);
1349
    }
1350
1351
    public function commentsProvider() : array
1352
    {
1353
        $currentType = 'current type';
1354
1355
        return [
1356
            'invalid custom type comments'      => ['should.return.current.type', $currentType, $currentType],
1357
            'valid doctrine type'               => ['(DC2Type:guid)', 'guid', $currentType],
1358
            'valid with dots'                   => ['(DC2Type:type.should.return)', 'type.should.return', $currentType],
1359
            'valid with namespace'              => ['(DC2Type:Namespace\Class)', 'Namespace\Class', $currentType],
1360
            'valid with extra closing bracket'  => ['(DC2Type:should.stop)).before)', 'should.stop', $currentType],
1361
            'valid with extra opening brackets' => ['(DC2Type:should((.stop)).before)', 'should((.stop', $currentType],
1362
        ];
1363
    }
1364
1365
    public function testCreateAndListSequences() : void
1366
    {
1367
        if ( ! $this->_sm->getDatabasePlatform()->supportsSequences()) {
1368
            self::markTestSkipped('This test is only supported on platforms that support sequences.');
1369
        }
1370
1371
        $sequence1Name           = 'sequence_1';
1372
        $sequence1AllocationSize = 1;
1373
        $sequence1InitialValue   = 2;
1374
        $sequence2Name           = 'sequence_2';
1375
        $sequence2AllocationSize = 3;
1376
        $sequence2InitialValue   = 4;
1377
        $sequence1               = new Sequence($sequence1Name, $sequence1AllocationSize, $sequence1InitialValue);
1378
        $sequence2               = new Sequence($sequence2Name, $sequence2AllocationSize, $sequence2InitialValue);
1379
1380
        $this->_sm->createSequence($sequence1);
1381
        $this->_sm->createSequence($sequence2);
1382
1383
        /** @var Sequence[] $actualSequences */
1384
        $actualSequences = [];
1385
        foreach ($this->_sm->listSequences() as $sequence) {
1386
            $actualSequences[$sequence->getName()] = $sequence;
1387
        }
1388
1389
        $actualSequence1 = $actualSequences[$sequence1Name];
1390
        $actualSequence2 = $actualSequences[$sequence2Name];
1391
1392
        self::assertSame($sequence1Name, $actualSequence1->getName());
1393
        self::assertEquals($sequence1AllocationSize, $actualSequence1->getAllocationSize());
1394
        self::assertEquals($sequence1InitialValue, $actualSequence1->getInitialValue());
1395
1396
        self::assertSame($sequence2Name, $actualSequence2->getName());
1397
        self::assertEquals($sequence2AllocationSize, $actualSequence2->getAllocationSize());
1398
        self::assertEquals($sequence2InitialValue, $actualSequence2->getInitialValue());
1399
    }
1400
}
1401