Passed
Push — 2.6 ( 0b32c9...1595a4 )
by Luís
05:36
created

removeJsonArrayTable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
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\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
            $this->assertContains('TEST_DROP_DATABASE', $knownDatabases);
58
        } else {
59
            $this->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 = isset($params['user']) ? $params['user'] : null;
70
        $password = isset($params['password']) ? $params['password'] : null;
71
72
        $connection = $this->_conn->getDriver()->connect($params, $user, $password);
73
74
        $this->assertInstanceOf('Doctrine\DBAL\Driver\Connection', $connection);
75
76
        $this->_sm->dropDatabase('test_drop_database');
77
78
        $this->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
        $sequence = new \Doctrine\DBAL\Schema\Sequence('dropcreate_sequences_test_seq', 20, 10);
91
        $this->_sm->dropAndCreateSequence($sequence);
92
    }
93
94
    public function testListSequences()
95
    {
96
        if(!$this->_conn->getDatabasePlatform()->supportsSequences()) {
97
            $this->markTestSkipped($this->_conn->getDriver()->getName().' does not support sequences.');
98
        }
99
100
        $sequence = new \Doctrine\DBAL\Schema\Sequence('list_sequences_test_seq', 20, 10);
101
        $this->_sm->createSequence($sequence);
102
103
        $sequences = $this->_sm->listSequences();
104
105
        $this->assertInternalType('array', $sequences, 'listSequences() should return an array.');
106
107
        $foundSequence = null;
108
        foreach($sequences as $sequence) {
109
            $this->assertInstanceOf('Doctrine\DBAL\Schema\Sequence', $sequence, 'Array elements of listSequences() should be Sequence instances.');
110
            if(strtolower($sequence->getName()) == 'list_sequences_test_seq') {
111
                $foundSequence = $sequence;
112
            }
113
        }
114
115
        $this->assertNotNull($foundSequence, "Sequence with name 'list_sequences_test_seq' was not found.");
116
        $this->assertEquals(20, $foundSequence->getAllocationSize(), "Allocation Size is expected to be 20.");
117
        $this->assertEquals(10, $foundSequence->getInitialValue(), "Initial Value is expected to be 10.");
118
    }
119
120
    public function testListDatabases()
121
    {
122
        if (!$this->_sm->getDatabasePlatform()->supportsCreateDropDatabase()) {
123
            $this->markTestSkipped('Cannot drop Database client side with this Driver.');
124
        }
125
126
        $this->_sm->dropAndCreateDatabase('test_create_database');
127
        $databases = $this->_sm->listDatabases();
128
129
        $databases = array_map('strtolower', $databases);
130
131
        $this->assertContains('test_create_database', $databases);
132
    }
133
134
    /**
135
     * @group DBAL-1058
136
     */
137
    public function testListNamespaceNames()
138
    {
139
        if (!$this->_sm->getDatabasePlatform()->supportsSchemas()) {
140
            $this->markTestSkipped('Platform does not support schemas.');
141
        }
142
143
        // Currently dropping schemas is not supported, so we have to workaround here.
144
        $namespaces = $this->_sm->listNamespaceNames();
145
        $namespaces = array_map('strtolower', $namespaces);
146
147
        if (!in_array('test_create_schema', $namespaces)) {
148
            $this->_conn->executeUpdate($this->_sm->getDatabasePlatform()->getCreateSchemaSQL('test_create_schema'));
149
150
            $namespaces = $this->_sm->listNamespaceNames();
151
            $namespaces = array_map('strtolower', $namespaces);
152
        }
153
154
        $this->assertContains('test_create_schema', $namespaces);
155
    }
156
157
    public function testListTables()
158
    {
159
        $this->createTestTable('list_tables_test');
160
        $tables = $this->_sm->listTables();
161
162
        $this->assertInternalType('array', $tables);
163
        $this->assertTrue(count($tables) > 0, "List Tables has to find at least one table named 'list_tables_test'.");
164
165
        $foundTable = false;
166
        foreach ($tables as $table) {
167
            $this->assertInstanceOf('Doctrine\DBAL\Schema\Table', $table);
168
            if (strtolower($table->getName()) == 'list_tables_test') {
169
                $foundTable = true;
170
171
                $this->assertTrue($table->hasColumn('id'));
172
                $this->assertTrue($table->hasColumn('test'));
173
                $this->assertTrue($table->hasColumn('foreign_key_test'));
174
            }
175
        }
176
177
        $this->assertTrue( $foundTable , "The 'list_tables_test' table has to be found.");
178
    }
179
180
    public function createListTableColumns()
181
    {
182
        $table = new Table('list_table_columns');
183
        $table->addColumn('id', 'integer', array('notnull' => true));
184
        $table->addColumn('test', 'string', array('length' => 255, 'notnull' => false, 'default' => 'expected default'));
185
        $table->addColumn('foo', 'text', array('notnull' => true));
186
        $table->addColumn('bar', 'decimal', array('precision' => 10, 'scale' => 4, 'notnull' => false));
187
        $table->addColumn('baz1', 'datetime');
188
        $table->addColumn('baz2', 'time');
189
        $table->addColumn('baz3', 'date');
190
        $table->setPrimaryKey(array('id'));
191
192
        return $table;
193
    }
194
195
    public function testListTableColumns()
196
    {
197
        $table = $this->createListTableColumns();
198
199
        $this->_sm->dropAndCreateTable($table);
200
201
        $columns = $this->_sm->listTableColumns('list_table_columns');
202
        $columnsKeys = array_keys($columns);
203
204
        $this->assertArrayHasKey('id', $columns);
205
        $this->assertEquals(0, array_search('id', $columnsKeys));
206
        $this->assertEquals('id',   strtolower($columns['id']->getname()));
207
        $this->assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['id']->gettype());
208
        $this->assertEquals(false,  $columns['id']->getunsigned());
209
        $this->assertEquals(true,   $columns['id']->getnotnull());
210
        $this->assertEquals(null,   $columns['id']->getdefault());
211
        $this->assertInternalType('array',  $columns['id']->getPlatformOptions());
212
213
        $this->assertArrayHasKey('test', $columns);
214
        $this->assertEquals(1, array_search('test', $columnsKeys));
215
        $this->assertEquals('test', strtolower($columns['test']->getname()));
216
        $this->assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['test']->gettype());
217
        $this->assertEquals(255,    $columns['test']->getlength());
218
        $this->assertEquals(false,  $columns['test']->getfixed());
219
        $this->assertEquals(false,  $columns['test']->getnotnull());
220
        $this->assertEquals('expected default',   $columns['test']->getdefault());
221
        $this->assertInternalType('array',  $columns['test']->getPlatformOptions());
222
223
        $this->assertEquals('foo',  strtolower($columns['foo']->getname()));
224
        $this->assertEquals(2, array_search('foo', $columnsKeys));
225
        $this->assertInstanceOf('Doctrine\DBAL\Types\TextType', $columns['foo']->gettype());
226
        $this->assertEquals(false,  $columns['foo']->getunsigned());
227
        $this->assertEquals(false,  $columns['foo']->getfixed());
228
        $this->assertEquals(true,   $columns['foo']->getnotnull());
229
        $this->assertEquals(null,   $columns['foo']->getdefault());
230
        $this->assertInternalType('array',  $columns['foo']->getPlatformOptions());
231
232
        $this->assertEquals('bar',  strtolower($columns['bar']->getname()));
233
        $this->assertEquals(3, array_search('bar', $columnsKeys));
234
        $this->assertInstanceOf('Doctrine\DBAL\Types\DecimalType', $columns['bar']->gettype());
235
        $this->assertEquals(null,   $columns['bar']->getlength());
236
        $this->assertEquals(10,     $columns['bar']->getprecision());
237
        $this->assertEquals(4,      $columns['bar']->getscale());
238
        $this->assertEquals(false,  $columns['bar']->getunsigned());
239
        $this->assertEquals(false,  $columns['bar']->getfixed());
240
        $this->assertEquals(false,  $columns['bar']->getnotnull());
241
        $this->assertEquals(null,   $columns['bar']->getdefault());
242
        $this->assertInternalType('array',  $columns['bar']->getPlatformOptions());
243
244
        $this->assertEquals('baz1', strtolower($columns['baz1']->getname()));
245
        $this->assertEquals(4, array_search('baz1', $columnsKeys));
246
        $this->assertInstanceOf('Doctrine\DBAL\Types\DateTimeType', $columns['baz1']->gettype());
247
        $this->assertEquals(true,   $columns['baz1']->getnotnull());
248
        $this->assertEquals(null,   $columns['baz1']->getdefault());
249
        $this->assertInternalType('array',  $columns['baz1']->getPlatformOptions());
250
251
        $this->assertEquals('baz2', strtolower($columns['baz2']->getname()));
252
        $this->assertEquals(5, array_search('baz2', $columnsKeys));
253
        $this->assertContains($columns['baz2']->gettype()->getName(), array('time', 'date', 'datetime'));
254
        $this->assertEquals(true,   $columns['baz2']->getnotnull());
255
        $this->assertEquals(null,   $columns['baz2']->getdefault());
256
        $this->assertInternalType('array',  $columns['baz2']->getPlatformOptions());
257
258
        $this->assertEquals('baz3', strtolower($columns['baz3']->getname()));
259
        $this->assertEquals(6, array_search('baz3', $columnsKeys));
260
        $this->assertContains($columns['baz3']->gettype()->getName(), array('time', 'date', 'datetime'));
261
        $this->assertEquals(true,   $columns['baz3']->getnotnull());
262
        $this->assertEquals(null,   $columns['baz3']->getdefault());
263
        $this->assertInternalType('array',  $columns['baz3']->getPlatformOptions());
264
    }
265
266
    /**
267
     * @group DBAL-1078
268
     */
269 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...
270
    {
271
        $tableName = 'test_list_table_fixed_string';
272
273
        $table = new Table($tableName);
274
        $table->addColumn('column_char', 'string', array('fixed' => true, 'length' => 2));
275
276
        $this->_sm->createTable($table);
277
278
        $columns = $this->_sm->listTableColumns($tableName);
279
280
        $this->assertArrayHasKey('column_char', $columns);
281
        $this->assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['column_char']->getType());
282
        $this->assertTrue($columns['column_char']->getFixed());
283
        $this->assertSame(2, $columns['column_char']->getLength());
284
    }
285
286
    public function testListTableColumnsDispatchEvent()
287
    {
288
        $table = $this->createListTableColumns();
289
290
        $this->_sm->dropAndCreateTable($table);
291
292
        $listenerMock = $this
293
            ->getMockBuilder('ListTableColumnsDispatchEventListener')
294
            ->setMethods(['onSchemaColumnDefinition'])
295
            ->getMock();
296
        $listenerMock
297
            ->expects($this->exactly(7))
298
            ->method('onSchemaColumnDefinition');
299
300
        $oldEventManager = $this->_sm->getDatabasePlatform()->getEventManager();
301
302
        $eventManager = new EventManager();
303
        $eventManager->addEventListener(array(Events::onSchemaColumnDefinition), $listenerMock);
304
305
        $this->_sm->getDatabasePlatform()->setEventManager($eventManager);
306
307
        $this->_sm->listTableColumns('list_table_columns');
308
309
        $this->_sm->getDatabasePlatform()->setEventManager($oldEventManager);
310
    }
311
312
    public function testListTableIndexesDispatchEvent()
313
    {
314
        $table = $this->getTestTable('list_table_indexes_test');
315
        $table->addUniqueIndex(array('test'), 'test_index_name');
316
        $table->addIndex(array('id', 'test'), 'test_composite_idx');
317
318
        $this->_sm->dropAndCreateTable($table);
319
320
        $listenerMock = $this
321
            ->getMockBuilder('ListTableIndexesDispatchEventListener')
322
            ->setMethods(['onSchemaIndexDefinition'])
323
            ->getMock();
324
        $listenerMock
325
            ->expects($this->exactly(3))
326
            ->method('onSchemaIndexDefinition');
327
328
        $oldEventManager = $this->_sm->getDatabasePlatform()->getEventManager();
329
330
        $eventManager = new EventManager();
331
        $eventManager->addEventListener(array(Events::onSchemaIndexDefinition), $listenerMock);
332
333
        $this->_sm->getDatabasePlatform()->setEventManager($eventManager);
334
335
        $this->_sm->listTableIndexes('list_table_indexes_test');
336
337
        $this->_sm->getDatabasePlatform()->setEventManager($oldEventManager);
338
    }
339
340
    public function testDiffListTableColumns()
341
    {
342
        if ($this->_sm->getDatabasePlatform()->getName() == 'oracle') {
343
            $this->markTestSkipped('Does not work with Oracle, since it cannot detect DateTime, Date and Time differenecs (at the moment).');
344
        }
345
346
        $offlineTable = $this->createListTableColumns();
347
        $this->_sm->dropAndCreateTable($offlineTable);
348
        $onlineTable = $this->_sm->listTableDetails('list_table_columns');
349
350
        $comparator = new \Doctrine\DBAL\Schema\Comparator();
351
        $diff = $comparator->diffTable($offlineTable, $onlineTable);
352
353
        $this->assertFalse($diff, "No differences should be detected with the offline vs online schema.");
354
    }
355
356
    public function testListTableIndexes()
357
    {
358
        $table = $this->getTestCompositeTable('list_table_indexes_test');
359
        $table->addUniqueIndex(array('test'), 'test_index_name');
360
        $table->addIndex(array('id', 'test'), 'test_composite_idx');
361
362
        $this->_sm->dropAndCreateTable($table);
363
364
        $tableIndexes = $this->_sm->listTableIndexes('list_table_indexes_test');
365
366
        $this->assertEquals(3, count($tableIndexes));
367
368
        $this->assertArrayHasKey('primary', $tableIndexes, 'listTableIndexes() has to return a "primary" array key.');
369
        $this->assertEquals(array('id', 'other_id'), array_map('strtolower', $tableIndexes['primary']->getColumns()));
370
        $this->assertTrue($tableIndexes['primary']->isUnique());
371
        $this->assertTrue($tableIndexes['primary']->isPrimary());
372
373
        $this->assertEquals('test_index_name', strtolower($tableIndexes['test_index_name']->getName()));
374
        $this->assertEquals(array('test'), array_map('strtolower', $tableIndexes['test_index_name']->getColumns()));
375
        $this->assertTrue($tableIndexes['test_index_name']->isUnique());
376
        $this->assertFalse($tableIndexes['test_index_name']->isPrimary());
377
378
        $this->assertEquals('test_composite_idx', strtolower($tableIndexes['test_composite_idx']->getName()));
379
        $this->assertEquals(array('id', 'test'), array_map('strtolower', $tableIndexes['test_composite_idx']->getColumns()));
380
        $this->assertFalse($tableIndexes['test_composite_idx']->isUnique());
381
        $this->assertFalse($tableIndexes['test_composite_idx']->isPrimary());
382
    }
383
384
    public function testDropAndCreateIndex()
385
    {
386
        $table = $this->getTestTable('test_create_index');
387
        $table->addUniqueIndex(array('test'), 'test');
388
        $this->_sm->dropAndCreateTable($table);
389
390
        $this->_sm->dropAndCreateIndex($table->getIndex('test'), $table);
391
        $tableIndexes = $this->_sm->listTableIndexes('test_create_index');
392
        $this->assertInternalType('array', $tableIndexes);
393
394
        $this->assertEquals('test',        strtolower($tableIndexes['test']->getName()));
395
        $this->assertEquals(array('test'), array_map('strtolower', $tableIndexes['test']->getColumns()));
396
        $this->assertTrue($tableIndexes['test']->isUnique());
397
        $this->assertFalse($tableIndexes['test']->isPrimary());
398
    }
399
400
    public function testCreateTableWithForeignKeys()
401
    {
402
        if(!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
403
            $this->markTestSkipped('Platform does not support foreign keys.');
404
        }
405
406
        $tableB = $this->getTestTable('test_foreign');
407
408
        $this->_sm->dropAndCreateTable($tableB);
409
410
        $tableA = $this->getTestTable('test_create_fk');
411
        $tableA->addForeignKeyConstraint('test_foreign', array('foreign_key_test'), array('id'));
412
413
        $this->_sm->dropAndCreateTable($tableA);
414
415
        $fkTable = $this->_sm->listTableDetails('test_create_fk');
416
        $fkConstraints = $fkTable->getForeignKeys();
417
        $this->assertEquals(1, count($fkConstraints), "Table 'test_create_fk1' has to have one foreign key.");
418
419
        $fkConstraint = current($fkConstraints);
420
        $this->assertInstanceOf('\Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkConstraint);
421
        $this->assertEquals('test_foreign',             strtolower($fkConstraint->getForeignTableName()));
422
        $this->assertEquals(array('foreign_key_test'),  array_map('strtolower', $fkConstraint->getColumns()));
423
        $this->assertEquals(array('id'),                array_map('strtolower', $fkConstraint->getForeignColumns()));
424
425
        $this->assertTrue($fkTable->columnsAreIndexed($fkConstraint->getColumns()), "The columns of a foreign key constraint should always be indexed.");
426
    }
427
428
    public function testListForeignKeys()
429
    {
430
        if(!$this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
431
            $this->markTestSkipped('Does not support foreign key constraints.');
432
        }
433
434
        $this->createTestTable('test_create_fk1');
435
        $this->createTestTable('test_create_fk2');
436
437
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
438
            array('foreign_key_test'), 'test_create_fk2', array('id'), 'foreign_key_test_fk', array('onDelete' => 'CASCADE')
439
        );
440
441
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk1');
442
443
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk1');
444
445
        $this->assertEquals(1, count($fkeys), "Table 'test_create_fk1' has to have one foreign key.");
446
447
        $this->assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
448
        $this->assertEquals(array('foreign_key_test'),  array_map('strtolower', $fkeys[0]->getLocalColumns()));
449
        $this->assertEquals(array('id'),                array_map('strtolower', $fkeys[0]->getForeignColumns()));
450
        $this->assertEquals('test_create_fk2',          strtolower($fkeys[0]->getForeignTableName()));
451
452
        if($fkeys[0]->hasOption('onDelete')) {
453
            $this->assertEquals('CASCADE', $fkeys[0]->getOption('onDelete'));
454
        }
455
    }
456
457
    protected function getCreateExampleViewSql()
458
    {
459
        $this->markTestSkipped('No Create Example View SQL was defined for this SchemaManager');
460
    }
461
462
    public function testCreateSchema()
463
    {
464
        $this->createTestTable('test_table');
465
466
        $schema = $this->_sm->createSchema();
467
        $this->assertTrue($schema->hasTable('test_table'));
468
    }
469
470
    public function testAlterTableScenario()
471
    {
472
        if(!$this->_sm->getDatabasePlatform()->supportsAlterTable()) {
473
            $this->markTestSkipped('Alter Table is not supported by this platform.');
474
        }
475
476
        $alterTable = $this->createTestTable('alter_table');
477
        $this->createTestTable('alter_table_foreign');
478
479
        $table = $this->_sm->listTableDetails('alter_table');
480
        $this->assertTrue($table->hasColumn('id'));
481
        $this->assertTrue($table->hasColumn('test'));
482
        $this->assertTrue($table->hasColumn('foreign_key_test'));
483
        $this->assertEquals(0, count($table->getForeignKeys()));
484
        $this->assertEquals(1, count($table->getIndexes()));
485
486
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
487
        $tableDiff->fromTable = $alterTable;
488
        $tableDiff->addedColumns['foo'] = new \Doctrine\DBAL\Schema\Column('foo', Type::getType('integer'));
489
        $tableDiff->removedColumns['test'] = $table->getColumn('test');
490
491
        $this->_sm->alterTable($tableDiff);
492
493
        $table = $this->_sm->listTableDetails('alter_table');
494
        $this->assertFalse($table->hasColumn('test'));
495
        $this->assertTrue($table->hasColumn('foo'));
496
497
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
498
        $tableDiff->fromTable = $table;
499
        $tableDiff->addedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo'));
500
501
        $this->_sm->alterTable($tableDiff);
502
503
        $table = $this->_sm->listTableDetails('alter_table');
504
        $this->assertEquals(2, count($table->getIndexes()));
505
        $this->assertTrue($table->hasIndex('foo_idx'));
506
        $this->assertEquals(array('foo'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
507
        $this->assertFalse($table->getIndex('foo_idx')->isPrimary());
508
        $this->assertFalse($table->getIndex('foo_idx')->isUnique());
509
510
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
511
        $tableDiff->fromTable = $table;
512
        $tableDiff->changedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo', 'foreign_key_test'));
513
514
        $this->_sm->alterTable($tableDiff);
515
516
        $table = $this->_sm->listTableDetails('alter_table');
517
        $this->assertEquals(2, count($table->getIndexes()));
518
        $this->assertTrue($table->hasIndex('foo_idx'));
519
        $this->assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
520
521
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
522
        $tableDiff->fromTable = $table;
523
        $tableDiff->renamedIndexes['foo_idx'] = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
524
525
        $this->_sm->alterTable($tableDiff);
526
527
        $table = $this->_sm->listTableDetails('alter_table');
528
        $this->assertEquals(2, count($table->getIndexes()));
529
        $this->assertTrue($table->hasIndex('bar_idx'));
530
        $this->assertFalse($table->hasIndex('foo_idx'));
531
        $this->assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('bar_idx')->getColumns()));
532
        $this->assertFalse($table->getIndex('bar_idx')->isPrimary());
533
        $this->assertFalse($table->getIndex('bar_idx')->isUnique());
534
535
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
536
        $tableDiff->fromTable = $table;
537
        $tableDiff->removedIndexes[] = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
538
        $fk = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(array('foreign_key_test'), 'alter_table_foreign', array('id'));
539
        $tableDiff->addedForeignKeys[] = $fk;
540
541
        $this->_sm->alterTable($tableDiff);
542
        $table = $this->_sm->listTableDetails('alter_table');
543
544
        // dont check for index size here, some platforms automatically add indexes for foreign keys.
545
        $this->assertFalse($table->hasIndex('bar_idx'));
546
547
        if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
548
            $fks = $table->getForeignKeys();
549
            $this->assertCount(1, $fks);
550
            $foreignKey = current($fks);
551
            $this->assertEquals('alter_table_foreign', strtolower($foreignKey->getForeignTableName()));
552
            $this->assertEquals(array('foreign_key_test'), array_map('strtolower', $foreignKey->getColumns()));
553
            $this->assertEquals(array('id'), array_map('strtolower', $foreignKey->getForeignColumns()));
554
        }
555
    }
556
557
    public function testCreateAndListViews()
558
    {
559
        if (!$this->_sm->getDatabasePlatform()->supportsViews()) {
560
            $this->markTestSkipped('Views is not supported by this platform.');
561
        }
562
563
        $this->createTestTable('view_test_table');
564
565
        $name = "doctrine_test_view";
566
        $sql = "SELECT * FROM view_test_table";
567
568
        $view = new \Doctrine\DBAL\Schema\View($name, $sql);
569
570
        $this->_sm->dropAndCreateView($view);
571
572
        $views = $this->_sm->listViews();
0 ignored issues
show
Unused Code introduced by
$views is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
573
    }
574
575 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...
576
    {
577
        if (!$this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
578
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
579
        }
580
581
        $table = new Table('test_autoincrement');
582
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
583
        $table->addColumn('id', 'integer', array('autoincrement' => true));
584
        $table->setPrimaryKey(array('id'));
585
586
        $this->_sm->createTable($table);
587
588
        $inferredTable = $this->_sm->listTableDetails('test_autoincrement');
589
        $this->assertTrue($inferredTable->hasColumn('id'));
590
        $this->assertTrue($inferredTable->getColumn('id')->getAutoincrement());
591
    }
592
593
    /**
594
     * @group DBAL-792
595
     */
596 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...
597
    {
598
        if (!$this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
599
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
600
        }
601
602
        $table = new Table('test_not_autoincrement');
603
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
604
        $table->addColumn('id', 'integer');
605
        $table->addColumn('other_id', 'integer');
606
        $table->setPrimaryKey(array('id', 'other_id'));
607
608
        $this->_sm->createTable($table);
609
610
        $inferredTable = $this->_sm->listTableDetails('test_not_autoincrement');
611
        $this->assertTrue($inferredTable->hasColumn('id'));
612
        $this->assertFalse($inferredTable->getColumn('id')->getAutoincrement());
613
    }
614
615
    /**
616
     * @group DDC-887
617
     */
618
    public function testUpdateSchemaWithForeignKeyRenaming()
619
    {
620
        if (!$this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
621
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
622
        }
623
624
        $table = new Table('test_fk_base');
625
        $table->addColumn('id', 'integer');
626
        $table->setPrimaryKey(array('id'));
627
628
        $tableFK = new Table('test_fk_rename');
629
        $tableFK->setSchemaConfig($this->_sm->createSchemaConfig());
630
        $tableFK->addColumn('id', 'integer');
631
        $tableFK->addColumn('fk_id', 'integer');
632
        $tableFK->setPrimaryKey(array('id'));
633
        $tableFK->addIndex(array('fk_id'), 'fk_idx');
634
        $tableFK->addForeignKeyConstraint('test_fk_base', array('fk_id'), array('id'));
635
636
        $this->_sm->createTable($table);
637
        $this->_sm->createTable($tableFK);
638
639
        $tableFKNew = new Table('test_fk_rename');
640
        $tableFKNew->setSchemaConfig($this->_sm->createSchemaConfig());
641
        $tableFKNew->addColumn('id', 'integer');
642
        $tableFKNew->addColumn('rename_fk_id', 'integer');
643
        $tableFKNew->setPrimaryKey(array('id'));
644
        $tableFKNew->addIndex(array('rename_fk_id'), 'fk_idx');
645
        $tableFKNew->addForeignKeyConstraint('test_fk_base', array('rename_fk_id'), array('id'));
646
647
        $c = new \Doctrine\DBAL\Schema\Comparator();
648
        $tableDiff = $c->diffTable($tableFK, $tableFKNew);
649
650
        $this->_sm->alterTable($tableDiff);
0 ignored issues
show
Security Bug introduced by
It seems like $tableDiff defined by $c->diffTable($tableFK, $tableFKNew) on line 648 can also be of type false; however, Doctrine\DBAL\Schema\Abs...maManager::alterTable() does only seem to accept object<Doctrine\DBAL\Schema\TableDiff>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
651
    }
652
653
    /**
654
     * @group DBAL-1062
655
     */
656
    public function testRenameIndexUsedInForeignKeyConstraint()
657
    {
658
        if (! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
659
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
660
        }
661
662
        $primaryTable = new Table('test_rename_index_primary');
663
        $primaryTable->addColumn('id', 'integer');
664
        $primaryTable->setPrimaryKey(array('id'));
665
666
        $foreignTable = new Table('test_rename_index_foreign');
667
        $foreignTable->addColumn('fk', 'integer');
668
        $foreignTable->addIndex(array('fk'), 'rename_index_fk_idx');
669
        $foreignTable->addForeignKeyConstraint(
670
            'test_rename_index_primary',
671
            array('fk'),
672
            array('id'),
673
            array(),
674
            'fk_constraint'
675
        );
676
677
        $this->_sm->dropAndCreateTable($primaryTable);
678
        $this->_sm->dropAndCreateTable($foreignTable);
679
680
        $foreignTable2 = clone $foreignTable;
681
        $foreignTable2->renameIndex('rename_index_fk_idx', 'renamed_index_fk_idx');
682
683
        $comparator = new Comparator();
684
685
        $this->_sm->alterTable($comparator->diffTable($foreignTable, $foreignTable2));
0 ignored issues
show
Security Bug introduced by
It seems like $comparator->diffTable($...nTable, $foreignTable2) targeting Doctrine\DBAL\Schema\Comparator::diffTable() can also be of type false; however, Doctrine\DBAL\Schema\Abs...maManager::alterTable() does only seem to accept object<Doctrine\DBAL\Schema\TableDiff>, did you maybe forget to handle an error condition?
Loading history...
686
687
        $foreignTable = $this->_sm->listTableDetails('test_rename_index_foreign');
688
689
        $this->assertFalse($foreignTable->hasIndex('rename_index_fk_idx'));
690
        $this->assertTrue($foreignTable->hasIndex('renamed_index_fk_idx'));
691
        $this->assertTrue($foreignTable->hasForeignKey('fk_constraint'));
692
    }
693
694
    /**
695
     * @group DBAL-42
696
     */
697
    public function testGetColumnComment()
698
    {
699 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...
700
             ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
701
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
702
            $this->markTestSkipped('Database does not support column comments.');
703
        }
704
705
        $table = new Table('column_comment_test');
706
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
707
        $table->setPrimaryKey(array('id'));
708
709
        $this->_sm->createTable($table);
710
711
        $columns = $this->_sm->listTableColumns("column_comment_test");
712
        $this->assertEquals(1, count($columns));
713
        $this->assertEquals('This is a comment', $columns['id']->getComment());
714
715
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff('column_comment_test');
716
        $tableDiff->fromTable = $table;
717
        $tableDiff->changedColumns['id'] = new \Doctrine\DBAL\Schema\ColumnDiff(
718
            'id', new \Doctrine\DBAL\Schema\Column(
719
                'id', \Doctrine\DBAL\Types\Type::getType('integer'), array('primary' => true)
720
            ),
721
            array('comment'),
722
            new \Doctrine\DBAL\Schema\Column(
723
                'id', \Doctrine\DBAL\Types\Type::getType('integer'), array('comment' => 'This is a comment')
724
            )
725
        );
726
727
        $this->_sm->alterTable($tableDiff);
728
729
        $columns = $this->_sm->listTableColumns("column_comment_test");
730
        $this->assertEquals(1, count($columns));
731
        $this->assertEmpty($columns['id']->getComment());
732
    }
733
734
    /**
735
     * @group DBAL-42
736
     */
737
    public function testAutomaticallyAppendCommentOnMarkedColumns()
738
    {
739 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...
740
             ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
741
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
742
            $this->markTestSkipped('Database does not support column comments.');
743
        }
744
745
        $table = new Table('column_comment_test2');
746
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
747
        $table->addColumn('obj', 'object', array('comment' => 'This is a comment'));
748
        $table->addColumn('arr', 'array', array('comment' => 'This is a comment'));
749
        $table->setPrimaryKey(array('id'));
750
751
        $this->_sm->createTable($table);
752
753
        $columns = $this->_sm->listTableColumns("column_comment_test2");
754
        $this->assertEquals(3, count($columns));
755
        $this->assertEquals('This is a comment', $columns['id']->getComment());
756
        $this->assertEquals('This is a comment', $columns['obj']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
757
        $this->assertInstanceOf('Doctrine\DBAL\Types\ObjectType', $columns['obj']->getType(), "The Doctrine2 should be detected from comment hint.");
758
        $this->assertEquals('This is a comment', $columns['arr']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
759
        $this->assertInstanceOf('Doctrine\DBAL\Types\ArrayType', $columns['arr']->getType(), "The Doctrine2 should be detected from comment hint.");
760
    }
761
762
    /**
763
     * @group DBAL-1228
764
     */
765
    public function testCommentHintOnDateIntervalTypeColumn()
766
    {
767 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...
768
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
769
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
770
            $this->markTestSkipped('Database does not support column comments.');
771
        }
772
773
        $table = new Table('column_dateinterval_comment');
774
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
775
        $table->addColumn('date_interval', 'dateinterval', array('comment' => 'This is a comment'));
776
        $table->setPrimaryKey(array('id'));
777
778
        $this->_sm->createTable($table);
779
780
        $columns = $this->_sm->listTableColumns("column_dateinterval_comment");
781
        $this->assertEquals(2, count($columns));
782
        $this->assertEquals('This is a comment', $columns['id']->getComment());
783
        $this->assertEquals('This is a comment', $columns['date_interval']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
784
        $this->assertInstanceOf('Doctrine\DBAL\Types\DateIntervalType', $columns['date_interval']->getType(), "The Doctrine2 should be detected from comment hint.");
785
    }
786
787
    /**
788
     * @group DBAL-825
789
     */
790
    public function testChangeColumnsTypeWithDefaultValue()
791
    {
792
        $tableName = 'column_def_change_type';
793
        $table     = new Table($tableName);
794
795
        $table->addColumn('col_int', 'smallint', array('default' => 666));
796
        $table->addColumn('col_string', 'string', array('default' => 'foo'));
797
798
        $this->_sm->dropAndCreateTable($table);
799
800
        $tableDiff = new TableDiff($tableName);
801
        $tableDiff->fromTable = $table;
802
        $tableDiff->changedColumns['col_int'] = new ColumnDiff(
803
            'col_int',
804
            new Column('col_int', Type::getType('integer'), array('default' => 666)),
805
            array('type'),
806
            new Column('col_int', Type::getType('smallint'), array('default' => 666))
807
        );
808
809
        $tableDiff->changedColumns['col_string'] = new ColumnDiff(
810
            'col_string',
811
            new Column('col_string', Type::getType('string'), array('default' => 'foo', 'fixed' => true)),
812
            array('fixed'),
813
            new Column('col_string', Type::getType('string'), array('default' => 'foo'))
814
        );
815
816
        $this->_sm->alterTable($tableDiff);
817
818
        $columns = $this->_sm->listTableColumns($tableName);
819
820
        $this->assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['col_int']->getType());
821
        $this->assertEquals(666, $columns['col_int']->getDefault());
822
823
        $this->assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['col_string']->getType());
824
        $this->assertEquals('foo', $columns['col_string']->getDefault());
825
    }
826
827
    /**
828
     * @group DBAL-197
829
     */
830
    public function testListTableWithBlob()
831
    {
832
        $table = new Table('test_blob_table');
833
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
834
        $table->addColumn('binarydata', 'blob', array());
835
        $table->setPrimaryKey(array('id'));
836
837
        $this->_sm->createTable($table);
838
        $this->_sm->listTableDetails('test_blob_table');
839
    }
840
841
    /**
842
     * @param string $name
843
     * @param array $data
844
     * @return Table
845
     */
846
    protected function createTestTable($name = 'test_table', $data = array())
847
    {
848
        $options = array();
849
        if (isset($data['options'])) {
850
            $options = $data['options'];
851
        }
852
853
        $table = $this->getTestTable($name, $options);
854
855
        $this->_sm->dropAndCreateTable($table);
856
857
        return $table;
858
    }
859
860
    protected function getTestTable($name, $options=array())
861
    {
862
        $table = new Table($name, array(), array(), array(), false, $options);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
863
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
864
        $table->addColumn('id', 'integer', array('notnull' => true));
865
        $table->setPrimaryKey(array('id'));
866
        $table->addColumn('test', 'string', array('length' => 255));
867
        $table->addColumn('foreign_key_test', 'integer');
868
        return $table;
869
    }
870
871
    protected function getTestCompositeTable($name)
872
    {
873
        $table = new Table($name, array(), array(), array(), false, array());
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
874
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
875
        $table->addColumn('id', 'integer', array('notnull' => true));
876
        $table->addColumn('other_id', 'integer', array('notnull' => true));
877
        $table->setPrimaryKey(array('id', 'other_id'));
878
        $table->addColumn('test', 'string', array('length' => 255));
879
        return $table;
880
    }
881
882
    protected function assertHasTable($tables, $tableName)
0 ignored issues
show
Unused Code introduced by
The parameter $tableName is not used and could be removed.

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

Loading history...
883
    {
884
        $foundTable = false;
885 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...
886
            $this->assertInstanceOf('Doctrine\DBAL\Schema\Table', $table, 'No Table instance was found in tables array.');
887
            if (strtolower($table->getName()) == 'list_tables_test_new_name') {
888
                $foundTable = true;
889
            }
890
        }
891
        $this->assertTrue($foundTable, "Could not find new table");
892
    }
893
894
    public function testListForeignKeysComposite()
895
    {
896
        if(!$this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
897
            $this->markTestSkipped('Does not support foreign key constraints.');
898
        }
899
900
        $this->_sm->createTable($this->getTestTable('test_create_fk3'));
901
        $this->_sm->createTable($this->getTestCompositeTable('test_create_fk4'));
902
903
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
904
            array('id', 'foreign_key_test'), 'test_create_fk4', array('id', 'other_id'), 'foreign_key_test_fk2'
905
        );
906
907
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk3');
908
909
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk3');
910
911
        $this->assertEquals(1, count($fkeys), "Table 'test_create_fk3' has to have one foreign key.");
912
913
        $this->assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
914
        $this->assertEquals(array('id', 'foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns()));
915
        $this->assertEquals(array('id', 'other_id'),         array_map('strtolower', $fkeys[0]->getForeignColumns()));
916
    }
917
918
    /**
919
     * @group DBAL-44
920
     */
921
    public function testColumnDefaultLifecycle()
922
    {
923
        $table = new Table("col_def_lifecycle");
924
        $table->addColumn('id', 'integer', array('primary' => true, 'autoincrement' => true));
925
        $table->addColumn('column1', 'string', array('default' => null));
926
        $table->addColumn('column2', 'string', array('default' => false));
927
        $table->addColumn('column3', 'string', array('default' => true));
928
        $table->addColumn('column4', 'string', array('default' => 0));
929
        $table->addColumn('column5', 'string', array('default' => ''));
930
        $table->addColumn('column6', 'string', array('default' => 'def'));
931
        $table->addColumn('column7', 'integer', array('default' => 0));
932
        $table->setPrimaryKey(array('id'));
933
934
        $this->_sm->dropAndCreateTable($table);
935
936
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
937
938
        $this->assertNull($columns['id']->getDefault());
939
        $this->assertNull($columns['column1']->getDefault());
940
        $this->assertSame('', $columns['column2']->getDefault());
941
        $this->assertSame('1', $columns['column3']->getDefault());
942
        $this->assertSame('0', $columns['column4']->getDefault());
943
        $this->assertSame('', $columns['column5']->getDefault());
944
        $this->assertSame('def', $columns['column6']->getDefault());
945
        $this->assertSame('0', $columns['column7']->getDefault());
946
947
        $diffTable = clone $table;
948
949
        $diffTable->changeColumn('column1', array('default' => false));
950
        $diffTable->changeColumn('column2', array('default' => null));
951
        $diffTable->changeColumn('column3', array('default' => false));
952
        $diffTable->changeColumn('column4', array('default' => null));
953
        $diffTable->changeColumn('column5', array('default' => false));
954
        $diffTable->changeColumn('column6', array('default' => 666));
955
        $diffTable->changeColumn('column7', array('default' => null));
956
957
        $comparator = new Comparator();
958
959
        $this->_sm->alterTable($comparator->diffTable($table, $diffTable));
0 ignored issues
show
Security Bug introduced by
It seems like $comparator->diffTable($table, $diffTable) targeting Doctrine\DBAL\Schema\Comparator::diffTable() can also be of type false; however, Doctrine\DBAL\Schema\Abs...maManager::alterTable() does only seem to accept object<Doctrine\DBAL\Schema\TableDiff>, did you maybe forget to handle an error condition?
Loading history...
960
961
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
962
963
        $this->assertSame('', $columns['column1']->getDefault());
964
        $this->assertNull($columns['column2']->getDefault());
965
        $this->assertSame('', $columns['column3']->getDefault());
966
        $this->assertNull($columns['column4']->getDefault());
967
        $this->assertSame('', $columns['column5']->getDefault());
968
        $this->assertSame('666', $columns['column6']->getDefault());
969
        $this->assertNull($columns['column7']->getDefault());
970
    }
971
972 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...
973
    {
974
        $tableName = 'test_binary_table';
975
976
        $table = new Table($tableName);
977
        $table->addColumn('id', 'integer');
978
        $table->addColumn('column_varbinary', 'binary', array());
979
        $table->addColumn('column_binary', 'binary', array('fixed' => true));
980
        $table->setPrimaryKey(array('id'));
981
982
        $this->_sm->createTable($table);
983
984
        $table = $this->_sm->listTableDetails($tableName);
985
986
        $this->assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_varbinary')->getType());
987
        $this->assertFalse($table->getColumn('column_varbinary')->getFixed());
988
989
        $this->assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_binary')->getType());
990
        $this->assertTrue($table->getColumn('column_binary')->getFixed());
991
    }
992
993
    public function testListTableDetailsWithFullQualifiedTableName()
994
    {
995
        if ( ! $this->_sm->getDatabasePlatform()->supportsSchemas()) {
996
            $this->markTestSkipped('Test only works on platforms that support schemas.');
997
        }
998
999
        $defaultSchemaName = $this->_sm->getDatabasePlatform()->getDefaultSchemaName();
1000
        $primaryTableName  = 'primary_table';
1001
        $foreignTableName  = 'foreign_table';
1002
1003
        $table = new Table($foreignTableName);
1004
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1005
        $table->setPrimaryKey(array('id'));
1006
1007
        $this->_sm->dropAndCreateTable($table);
1008
1009
        $table = new Table($primaryTableName);
1010
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1011
        $table->addColumn('foo', 'integer');
1012
        $table->addColumn('bar', 'string');
1013
        $table->addForeignKeyConstraint($foreignTableName, array('foo'), array('id'));
1014
        $table->addIndex(array('bar'));
1015
        $table->setPrimaryKey(array('id'));
1016
1017
        $this->_sm->dropAndCreateTable($table);
1018
1019
        $this->assertEquals(
1020
            $this->_sm->listTableColumns($primaryTableName),
1021
            $this->_sm->listTableColumns($defaultSchemaName . '.' . $primaryTableName)
1022
        );
1023
        $this->assertEquals(
1024
            $this->_sm->listTableIndexes($primaryTableName),
1025
            $this->_sm->listTableIndexes($defaultSchemaName . '.' . $primaryTableName)
1026
        );
1027
        $this->assertEquals(
1028
            $this->_sm->listTableForeignKeys($primaryTableName),
1029
            $this->_sm->listTableForeignKeys($defaultSchemaName . '.' . $primaryTableName)
1030
        );
1031
    }
1032
1033
    public function testCommentStringsAreQuoted()
1034
    {
1035 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...
1036
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
1037
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1038
            $this->markTestSkipped('Database does not support column comments.');
1039
        }
1040
1041
        $table = new Table('my_table');
1042
        $table->addColumn('id', 'integer', array('comment' => "It's a comment with a quote"));
1043
        $table->setPrimaryKey(array('id'));
1044
1045
        $this->_sm->createTable($table);
1046
1047
        $columns = $this->_sm->listTableColumns("my_table");
1048
        $this->assertEquals("It's a comment with a quote", $columns['id']->getComment());
1049
    }
1050
1051
    public function testCommentNotDuplicated()
1052
    {
1053
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments()) {
1054
            $this->markTestSkipped('Database does not support column comments.');
1055
        }
1056
1057
        $options = array(
1058
            'type' => Type::getType('integer'),
1059
            'default' => 0,
1060
            'notnull' => true,
1061
            'comment' => 'expected+column+comment',
1062
        );
1063
        $columnDefinition = substr($this->_conn->getDatabasePlatform()->getColumnDeclarationSQL('id', $options), strlen('id') + 1);
1064
1065
        $table = new Table('my_table');
1066
        $table->addColumn('id', 'integer', array('columnDefinition' => $columnDefinition, 'comment' => 'unexpected_column_comment'));
1067
        $sql = $this->_conn->getDatabasePlatform()->getCreateTableSQL($table);
1068
1069
        $this->assertContains('expected+column+comment', $sql[0]);
1070
        $this->assertNotContains('unexpected_column_comment', $sql[0]);
1071
    }
1072
1073
    /**
1074
     * @group DBAL-1009
1075
     *
1076
     * @dataProvider getAlterColumnComment
1077
     */
1078
    public function testAlterColumnComment($comment1, $expectedComment1, $comment2, $expectedComment2)
1079
    {
1080 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...
1081
            ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
1082
            $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1083
            $this->markTestSkipped('Database does not support column comments.');
1084
        }
1085
1086
        $offlineTable = new Table('alter_column_comment_test');
1087
        $offlineTable->addColumn('comment1', 'integer', array('comment' => $comment1));
1088
        $offlineTable->addColumn('comment2', 'integer', array('comment' => $comment2));
1089
        $offlineTable->addColumn('no_comment1', 'integer');
1090
        $offlineTable->addColumn('no_comment2', 'integer');
1091
        $this->_sm->dropAndCreateTable($offlineTable);
1092
1093
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1094
1095
        $this->assertSame($expectedComment1, $onlineTable->getColumn('comment1')->getComment());
1096
        $this->assertSame($expectedComment2, $onlineTable->getColumn('comment2')->getComment());
1097
        $this->assertNull($onlineTable->getColumn('no_comment1')->getComment());
1098
        $this->assertNull($onlineTable->getColumn('no_comment2')->getComment());
1099
1100
        $onlineTable->changeColumn('comment1', array('comment' => $comment2));
1101
        $onlineTable->changeColumn('comment2', array('comment' => $comment1));
1102
        $onlineTable->changeColumn('no_comment1', array('comment' => $comment1));
1103
        $onlineTable->changeColumn('no_comment2', array('comment' => $comment2));
1104
1105
        $comparator = new Comparator();
1106
1107
        $tableDiff = $comparator->diffTable($offlineTable, $onlineTable);
1108
1109
        $this->assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
1110
1111
        $this->_sm->alterTable($tableDiff);
0 ignored issues
show
Security Bug introduced by
It seems like $tableDiff defined by $comparator->diffTable($...ineTable, $onlineTable) on line 1107 can also be of type false; however, Doctrine\DBAL\Schema\Abs...maManager::alterTable() does only seem to accept object<Doctrine\DBAL\Schema\TableDiff>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
1112
1113
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1114
1115
        $this->assertSame($expectedComment2, $onlineTable->getColumn('comment1')->getComment());
1116
        $this->assertSame($expectedComment1, $onlineTable->getColumn('comment2')->getComment());
1117
        $this->assertSame($expectedComment1, $onlineTable->getColumn('no_comment1')->getComment());
1118
        $this->assertSame($expectedComment2, $onlineTable->getColumn('no_comment2')->getComment());
1119
    }
1120
1121
    public function getAlterColumnComment()
1122
    {
1123
        return array(
1124
            array(null, null, ' ', ' '),
1125
            array(null, null, '0', '0'),
1126
            array(null, null, 'foo', 'foo'),
1127
1128
            array('', null, ' ', ' '),
1129
            array('', null, '0', '0'),
1130
            array('', null, 'foo', 'foo'),
1131
1132
            array(' ', ' ', '0', '0'),
1133
            array(' ', ' ', 'foo', 'foo'),
1134
1135
            array('0', '0', 'foo', 'foo'),
1136
        );
1137
    }
1138
1139
    /**
1140
     * @group DBAL-1095
1141
     */
1142
    public function testDoesNotListIndexesImplicitlyCreatedByForeignKeys()
1143
    {
1144
        if (! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
1145
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
1146
        }
1147
1148
        $primaryTable = new Table('test_list_index_impl_primary');
1149
        $primaryTable->addColumn('id', 'integer');
1150
        $primaryTable->setPrimaryKey(array('id'));
1151
1152
        $foreignTable = new Table('test_list_index_impl_foreign');
1153
        $foreignTable->addColumn('fk1', 'integer');
1154
        $foreignTable->addColumn('fk2', 'integer');
1155
        $foreignTable->addIndex(array('fk1'), 'explicit_fk1_idx');
1156
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk1'), array('id'));
1157
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk2'), array('id'));
1158
1159
        $this->_sm->dropAndCreateTable($primaryTable);
1160
        $this->_sm->dropAndCreateTable($foreignTable);
1161
1162
        $indexes = $this->_sm->listTableIndexes('test_list_index_impl_foreign');
1163
1164
        $this->assertCount(2, $indexes);
1165
        $this->assertArrayHasKey('explicit_fk1_idx', $indexes);
1166
        $this->assertArrayHasKey('idx_3d6c147fdc58d6c', $indexes);
1167
    }
1168
1169
    /**
1170
     * @after
1171
     */
1172
    public function removeJsonArrayTable() : void
1173
    {
1174
        if ($this->_sm->tablesExist(['json_array_test'])) {
1175
            $this->_sm->dropTable('json_array_test');
1176
        }
1177
    }
1178
1179
    /**
1180
     * @group 2782
1181
     * @group 6654
1182
     */
1183 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...
1184
    {
1185
        $table = new Table('json_array_test');
1186
        $table->addColumn('parameters', 'json_array');
1187
1188
        $this->_sm->createTable($table);
1189
1190
        $comparator = new Comparator();
1191
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1192
1193
        self::assertFalse($tableDiff);
1194
    }
1195
1196
    /**
1197
     * @group 2782
1198
     * @group 6654
1199
     */
1200
    public function testComparatorShouldModifyOnlyTheCommentWhenUpdatingFromJsonArrayTypeOnLegacyPlatforms() : void
1201
    {
1202
        if ($this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1203
            $this->markTestSkipped('This test is only supported on platforms that do not have native JSON type.');
1204
        }
1205
1206
        $table = new Table('json_array_test');
1207
        $table->addColumn('parameters', 'json_array');
1208
1209
        $this->_sm->createTable($table);
1210
1211
        $table = new Table('json_array_test');
1212
        $table->addColumn('parameters', 'json');
1213
1214
        $comparator = new Comparator();
1215
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1216
1217
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1218
1219
        $changedColumn = $tableDiff->changedColumns['parameters'] ?? $tableDiff->changedColumns['PARAMETERS'];
1220
1221
        self::assertSame(['comment'], $changedColumn->changedProperties);
1222
    }
1223
1224
    /**
1225
     * @group 2782
1226
     * @group 6654
1227
     */
1228 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...
1229
    {
1230
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1231
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1232
        }
1233
1234
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON NOT NULL)');
1235
1236
        $table = new Table('json_array_test');
1237
        $table->addColumn('parameters', 'json_array');
1238
1239
        $comparator = new Comparator();
1240
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1241
1242
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1243
        self::assertSame(['comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1244
    }
1245
1246
    /**
1247
     * @group 2782
1248
     * @group 6654
1249
     */
1250 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...
1251
    {
1252
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1253
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1254
        }
1255
1256
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON DEFAULT NULL)');
1257
1258
        $table = new Table('json_array_test');
1259
        $table->addColumn('parameters', 'json_array');
1260
1261
        $comparator = new Comparator();
1262
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1263
1264
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1265
        self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1266
    }
1267
1268
    /**
1269
     * @group 2782
1270
     * @group 6654
1271
     */
1272 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...
1273
    {
1274
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1275
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1276
        }
1277
1278
        $this->_conn->executeQuery('CREATE TABLE json_array_test (parameters JSON DEFAULT NULL)');
1279
1280
        $table = new Table('json_array_test');
1281
        $table->addColumn('parameters', 'json_array');
1282
1283
        $comparator = new Comparator();
1284
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_array_test'), $table);
1285
1286
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1287
        self::assertSame(['notnull', 'comment'], $tableDiff->changedColumns['parameters']->changedProperties);
1288
    }
1289
1290
    /**
1291
     * @group 2782
1292
     * @group 6654
1293
     */
1294
    public function testComparatorShouldNotAddCommentToJsonTypeSinceItIsTheDefaultNow() : void
1295
    {
1296
        if ( ! $this->_sm->getDatabasePlatform()->hasNativeJsonType()) {
1297
            $this->markTestSkipped('This test is only supported on platforms that have native JSON type.');
1298
        }
1299
1300
        $this->_conn->executeQuery('CREATE TABLE json_test (parameters JSON NOT NULL)');
1301
1302
        $table = new Table('json_test');
1303
        $table->addColumn('parameters', 'json');
1304
1305
        $comparator = new Comparator();
1306
        $tableDiff  = $comparator->diffTable($this->_sm->listTableDetails('json_test'), $table);
1307
1308
        self::assertFalse($tableDiff);
1309
    }
1310
}
1311