Failed Conditions
Pull Request — master (#2849)
by Luís
63:28
created

testCommentHintOnDateIntervalTypeColumn()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 22
Code Lines 15

Duplication

Lines 5
Ratio 22.73 %

Importance

Changes 0
Metric Value
dl 5
loc 22
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 15
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
            self::assertContains('TEST_DROP_DATABASE', $knownDatabases);
58
        } else {
59
            self::assertContains('test_drop_database', $knownDatabases);
60
        }
61
62
        $params = $this->_conn->getParams();
63
        if ($this->_conn->getDatabasePlatform() instanceof OraclePlatform) {
64
            $params['user'] = 'test_drop_database';
65
        } else {
66
            $params['dbname'] = 'test_drop_database';
67
        }
68
69
        $user     = 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
        self::assertInstanceOf('Doctrine\DBAL\Driver\Connection', $connection);
75
76
        $this->_sm->dropDatabase('test_drop_database');
77
78
        self::assertNotContains('test_drop_database', $this->_sm->listDatabases());
79
    }
80
81
    /**
82
     * @group DBAL-195
83
     */
84
    public function testDropAndCreateSequence()
85
    {
86
        if ( ! $this->_conn->getDatabasePlatform()->supportsSequences()) {
87
            $this->markTestSkipped($this->_conn->getDriver()->getName() . ' does not support sequences.');
88
        }
89
90
        $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
        self::assertInternalType('array', $sequences, 'listSequences() should return an array.');
106
107
        $foundSequence = null;
108
        foreach ($sequences as $sequence) {
109
            self::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
        self::assertNotNull($foundSequence, "Sequence with name 'list_sequences_test_seq' was not found.");
116
        self::assertEquals(20, $foundSequence->getAllocationSize(), "Allocation Size is expected to be 20.");
117
        self::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
        self::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
        self::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
        self::assertInternalType('array', $tables);
163
        self::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
            self::assertInstanceOf('Doctrine\DBAL\Schema\Table', $table);
168
            if (strtolower($table->getName()) == 'list_tables_test') {
169
                $foundTable = true;
170
171
                self::assertTrue($table->hasColumn('id'));
172
                self::assertTrue($table->hasColumn('test'));
173
                self::assertTrue($table->hasColumn('foreign_key_test'));
174
            }
175
        }
176
177
        self::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
        self::assertArrayHasKey('id', $columns);
205
        self::assertEquals(0, array_search('id', $columnsKeys));
206
        self::assertEquals('id', strtolower($columns['id']->getname()));
207
        self::assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['id']->gettype());
208
        self::assertEquals(false, $columns['id']->getunsigned());
209
        self::assertEquals(true, $columns['id']->getnotnull());
210
        self::assertEquals(null, $columns['id']->getdefault());
211
        self::assertInternalType('array', $columns['id']->getPlatformOptions());
212
213
        self::assertArrayHasKey('test', $columns);
214
        self::assertEquals(1, array_search('test', $columnsKeys));
215
        self::assertEquals('test', strtolower($columns['test']->getname()));
216
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['test']->gettype());
217
        self::assertEquals(255, $columns['test']->getlength());
218
        self::assertEquals(false, $columns['test']->getfixed());
219
        self::assertEquals(false, $columns['test']->getnotnull());
220
        self::assertEquals('expected default', $columns['test']->getdefault());
221
        self::assertInternalType('array', $columns['test']->getPlatformOptions());
222
223
        self::assertEquals('foo', strtolower($columns['foo']->getname()));
224
        self::assertEquals(2, array_search('foo', $columnsKeys));
225
        self::assertInstanceOf('Doctrine\DBAL\Types\TextType', $columns['foo']->gettype());
226
        self::assertEquals(false, $columns['foo']->getunsigned());
227
        self::assertEquals(false, $columns['foo']->getfixed());
228
        self::assertEquals(true, $columns['foo']->getnotnull());
229
        self::assertEquals(null, $columns['foo']->getdefault());
230
        self::assertInternalType('array', $columns['foo']->getPlatformOptions());
231
232
        self::assertEquals('bar', strtolower($columns['bar']->getname()));
233
        self::assertEquals(3, array_search('bar', $columnsKeys));
234
        self::assertInstanceOf('Doctrine\DBAL\Types\DecimalType', $columns['bar']->gettype());
235
        self::assertEquals(null, $columns['bar']->getlength());
236
        self::assertEquals(10, $columns['bar']->getprecision());
237
        self::assertEquals(4, $columns['bar']->getscale());
238
        self::assertEquals(false, $columns['bar']->getunsigned());
239
        self::assertEquals(false, $columns['bar']->getfixed());
240
        self::assertEquals(false, $columns['bar']->getnotnull());
241
        self::assertEquals(null, $columns['bar']->getdefault());
242
        self::assertInternalType('array', $columns['bar']->getPlatformOptions());
243
244
        self::assertEquals('baz1', strtolower($columns['baz1']->getname()));
245
        self::assertEquals(4, array_search('baz1', $columnsKeys));
246
        self::assertInstanceOf('Doctrine\DBAL\Types\DateTimeType', $columns['baz1']->gettype());
247
        self::assertEquals(true, $columns['baz1']->getnotnull());
248
        self::assertEquals(null, $columns['baz1']->getdefault());
249
        self::assertInternalType('array', $columns['baz1']->getPlatformOptions());
250
251
        self::assertEquals('baz2', strtolower($columns['baz2']->getname()));
252
        self::assertEquals(5, array_search('baz2', $columnsKeys));
253
        self::assertContains($columns['baz2']->gettype()->getName(), array('time', 'date', 'datetime'));
254
        self::assertEquals(true, $columns['baz2']->getnotnull());
255
        self::assertEquals(null, $columns['baz2']->getdefault());
256
        self::assertInternalType('array', $columns['baz2']->getPlatformOptions());
257
258
        self::assertEquals('baz3', strtolower($columns['baz3']->getname()));
259
        self::assertEquals(6, array_search('baz3', $columnsKeys));
260
        self::assertContains($columns['baz3']->gettype()->getName(), array('time', 'date', 'datetime'));
261
        self::assertEquals(true, $columns['baz3']->getnotnull());
262
        self::assertEquals(null, $columns['baz3']->getdefault());
263
        self::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
        self::assertArrayHasKey('column_char', $columns);
281
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['column_char']->getType());
282
        self::assertTrue($columns['column_char']->getFixed());
283
        self::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
        self::assertFalse($diff, "No differences should be detected with the offline vs online schema.");
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($...ineTable, $onlineTable) on line 351 can also be of type object<Doctrine\DBAL\Schema\TableDiff>; however, PHPUnit\Framework\Assert::assertFalse() does only seem to accept boolean, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
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
        self::assertEquals(3, count($tableIndexes));
367
368
        self::assertArrayHasKey('primary', $tableIndexes, 'listTableIndexes() has to return a "primary" array key.');
369
        self::assertEquals(array('id', 'other_id'), array_map('strtolower', $tableIndexes['primary']->getColumns()));
370
        self::assertTrue($tableIndexes['primary']->isUnique());
371
        self::assertTrue($tableIndexes['primary']->isPrimary());
372
373
        self::assertEquals('test_index_name', strtolower($tableIndexes['test_index_name']->getName()));
374
        self::assertEquals(array('test'), array_map('strtolower', $tableIndexes['test_index_name']->getColumns()));
375
        self::assertTrue($tableIndexes['test_index_name']->isUnique());
376
        self::assertFalse($tableIndexes['test_index_name']->isPrimary());
377
378
        self::assertEquals('test_composite_idx', strtolower($tableIndexes['test_composite_idx']->getName()));
379
        self::assertEquals(array('id', 'test'), array_map('strtolower', $tableIndexes['test_composite_idx']->getColumns()));
380
        self::assertFalse($tableIndexes['test_composite_idx']->isUnique());
381
        self::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
        self::assertInternalType('array', $tableIndexes);
393
394
        self::assertEquals('test', strtolower($tableIndexes['test']->getName()));
395
        self::assertEquals(array('test'), array_map('strtolower', $tableIndexes['test']->getColumns()));
396
        self::assertTrue($tableIndexes['test']->isUnique());
397
        self::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
        self::assertEquals(1, count($fkConstraints), "Table 'test_create_fk1' has to have one foreign key.");
418
419
        $fkConstraint = current($fkConstraints);
420
        self::assertInstanceOf('\Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkConstraint);
421
        self::assertEquals('test_foreign', strtolower($fkConstraint->getForeignTableName()));
422
        self::assertEquals(array('foreign_key_test'), array_map('strtolower', $fkConstraint->getColumns()));
423
        self::assertEquals(array('id'), array_map('strtolower', $fkConstraint->getForeignColumns()));
424
425
        self::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'),
439
            'test_create_fk2',
440
            array('id'),
441
            'foreign_key_test_fk',
442
            array('onDelete' => 'CASCADE')
443
        );
444
445
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk1');
446
447
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk1');
448
449
        self::assertEquals(1, count($fkeys), "Table 'test_create_fk1' has to have one foreign key.");
450
451
        self::assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
452
        self::assertEquals(array('foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns()));
453
        self::assertEquals(array('id'), array_map('strtolower', $fkeys[0]->getForeignColumns()));
454
        self::assertEquals('test_create_fk2', strtolower($fkeys[0]->getForeignTableName()));
455
456
        if ($fkeys[0]->hasOption('onDelete')) {
457
            self::assertEquals('CASCADE', $fkeys[0]->getOption('onDelete'));
458
        }
459
    }
460
461
    protected function getCreateExampleViewSql()
462
    {
463
        $this->markTestSkipped('No Create Example View SQL was defined for this SchemaManager');
464
    }
465
466
    public function testCreateSchema()
467
    {
468
        $this->createTestTable('test_table');
469
470
        $schema = $this->_sm->createSchema();
471
        self::assertTrue($schema->hasTable('test_table'));
472
    }
473
474
    public function testAlterTableScenario()
475
    {
476
        if ( ! $this->_sm->getDatabasePlatform()->supportsAlterTable()) {
477
            $this->markTestSkipped('Alter Table is not supported by this platform.');
478
        }
479
480
        $alterTable = $this->createTestTable('alter_table');
481
        $this->createTestTable('alter_table_foreign');
482
483
        $table = $this->_sm->listTableDetails('alter_table');
484
        self::assertTrue($table->hasColumn('id'));
485
        self::assertTrue($table->hasColumn('test'));
486
        self::assertTrue($table->hasColumn('foreign_key_test'));
487
        self::assertEquals(0, count($table->getForeignKeys()));
488
        self::assertEquals(1, count($table->getIndexes()));
489
490
        $tableDiff                         = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
491
        $tableDiff->fromTable              = $alterTable;
492
        $tableDiff->addedColumns['foo']    = new \Doctrine\DBAL\Schema\Column('foo', Type::getType('integer'));
493
        $tableDiff->removedColumns['test'] = $table->getColumn('test');
494
495
        $this->_sm->alterTable($tableDiff);
496
497
        $table = $this->_sm->listTableDetails('alter_table');
498
        self::assertFalse($table->hasColumn('test'));
499
        self::assertTrue($table->hasColumn('foo'));
500
501
        $tableDiff                 = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
502
        $tableDiff->fromTable      = $table;
503
        $tableDiff->addedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo'));
504
505
        $this->_sm->alterTable($tableDiff);
506
507
        $table = $this->_sm->listTableDetails('alter_table');
508
        self::assertEquals(2, count($table->getIndexes()));
509
        self::assertTrue($table->hasIndex('foo_idx'));
510
        self::assertEquals(array('foo'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
511
        self::assertFalse($table->getIndex('foo_idx')->isPrimary());
512
        self::assertFalse($table->getIndex('foo_idx')->isUnique());
513
514
        $tableDiff                   = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
515
        $tableDiff->fromTable        = $table;
516
        $tableDiff->changedIndexes[] = new \Doctrine\DBAL\Schema\Index('foo_idx', array('foo', 'foreign_key_test'));
517
518
        $this->_sm->alterTable($tableDiff);
519
520
        $table = $this->_sm->listTableDetails('alter_table');
521
        self::assertEquals(2, count($table->getIndexes()));
522
        self::assertTrue($table->hasIndex('foo_idx'));
523
        self::assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('foo_idx')->getColumns()));
524
525
        $tableDiff                            = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
526
        $tableDiff->fromTable                 = $table;
527
        $tableDiff->renamedIndexes['foo_idx'] = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
528
529
        $this->_sm->alterTable($tableDiff);
530
531
        $table = $this->_sm->listTableDetails('alter_table');
532
        self::assertEquals(2, count($table->getIndexes()));
533
        self::assertTrue($table->hasIndex('bar_idx'));
534
        self::assertFalse($table->hasIndex('foo_idx'));
535
        self::assertEquals(array('foo', 'foreign_key_test'), array_map('strtolower', $table->getIndex('bar_idx')->getColumns()));
536
        self::assertFalse($table->getIndex('bar_idx')->isPrimary());
537
        self::assertFalse($table->getIndex('bar_idx')->isUnique());
538
539
        $tableDiff                     = new \Doctrine\DBAL\Schema\TableDiff("alter_table");
540
        $tableDiff->fromTable          = $table;
541
        $tableDiff->removedIndexes[]   = new \Doctrine\DBAL\Schema\Index('bar_idx', array('foo', 'foreign_key_test'));
542
        $fk                            = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(array('foreign_key_test'), 'alter_table_foreign', array('id'));
543
        $tableDiff->addedForeignKeys[] = $fk;
544
545
        $this->_sm->alterTable($tableDiff);
546
        $table = $this->_sm->listTableDetails('alter_table');
547
548
        // dont check for index size here, some platforms automatically add indexes for foreign keys.
549
        self::assertFalse($table->hasIndex('bar_idx'));
550
551
        if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
552
            $fks = $table->getForeignKeys();
553
            self::assertCount(1, $fks);
554
            $foreignKey = current($fks);
555
            self::assertEquals('alter_table_foreign', strtolower($foreignKey->getForeignTableName()));
556
            self::assertEquals(array('foreign_key_test'), array_map('strtolower', $foreignKey->getColumns()));
557
            self::assertEquals(array('id'), array_map('strtolower', $foreignKey->getForeignColumns()));
558
        }
559
    }
560
561
    public function testCreateAndListViews()
562
    {
563
        if ( ! $this->_sm->getDatabasePlatform()->supportsViews()) {
564
            $this->markTestSkipped('Views is not supported by this platform.');
565
        }
566
567
        $this->createTestTable('view_test_table');
568
569
        $name = "doctrine_test_view";
570
        $sql  = "SELECT * FROM view_test_table";
571
572
        $view = new \Doctrine\DBAL\Schema\View($name, $sql);
573
574
        $this->_sm->dropAndCreateView($view);
575
576
        $views = $this->_sm->listViews();
577
578
        self::assertCount(1, $views);
579
    }
580
581 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...
582
    {
583
        if ( ! $this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
584
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
585
        }
586
587
        $table = new Table('test_autoincrement');
588
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
589
        $table->addColumn('id', 'integer', array('autoincrement' => true));
590
        $table->setPrimaryKey(array('id'));
591
592
        $this->_sm->createTable($table);
593
594
        $inferredTable = $this->_sm->listTableDetails('test_autoincrement');
595
        self::assertTrue($inferredTable->hasColumn('id'));
596
        self::assertTrue($inferredTable->getColumn('id')->getAutoincrement());
597
    }
598
599
    /**
600
     * @group DBAL-792
601
     */
602 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...
603
    {
604
        if ( ! $this->_sm->getDatabasePlatform()->supportsIdentityColumns()) {
605
            $this->markTestSkipped('This test is only supported on platforms that have autoincrement');
606
        }
607
608
        $table = new Table('test_not_autoincrement');
609
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
610
        $table->addColumn('id', 'integer');
611
        $table->addColumn('other_id', 'integer');
612
        $table->setPrimaryKey(array('id', 'other_id'));
613
614
        $this->_sm->createTable($table);
615
616
        $inferredTable = $this->_sm->listTableDetails('test_not_autoincrement');
617
        self::assertTrue($inferredTable->hasColumn('id'));
618
        self::assertFalse($inferredTable->getColumn('id')->getAutoincrement());
619
    }
620
621
    /**
622
     * @group DDC-887
623
     */
624
    public function testUpdateSchemaWithForeignKeyRenaming()
625
    {
626
        if ( ! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
627
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
628
        }
629
630
        $table = new Table('test_fk_base');
631
        $table->addColumn('id', 'integer');
632
        $table->setPrimaryKey(array('id'));
633
634
        $tableFK = new Table('test_fk_rename');
635
        $tableFK->setSchemaConfig($this->_sm->createSchemaConfig());
636
        $tableFK->addColumn('id', 'integer');
637
        $tableFK->addColumn('fk_id', 'integer');
638
        $tableFK->setPrimaryKey(array('id'));
639
        $tableFK->addIndex(array('fk_id'), 'fk_idx');
640
        $tableFK->addForeignKeyConstraint('test_fk_base', array('fk_id'), array('id'));
641
642
        $this->_sm->createTable($table);
643
        $this->_sm->createTable($tableFK);
644
645
        $tableFKNew = new Table('test_fk_rename');
646
        $tableFKNew->setSchemaConfig($this->_sm->createSchemaConfig());
647
        $tableFKNew->addColumn('id', 'integer');
648
        $tableFKNew->addColumn('rename_fk_id', 'integer');
649
        $tableFKNew->setPrimaryKey(array('id'));
650
        $tableFKNew->addIndex(array('rename_fk_id'), 'fk_idx');
651
        $tableFKNew->addForeignKeyConstraint('test_fk_base', array('rename_fk_id'), array('id'));
652
653
        $c         = new \Doctrine\DBAL\Schema\Comparator();
654
        $tableDiff = $c->diffTable($tableFK, $tableFKNew);
655
656
        $this->_sm->alterTable($tableDiff);
0 ignored issues
show
Security Bug introduced by
It seems like $tableDiff defined by $c->diffTable($tableFK, $tableFKNew) on line 654 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...
657
    }
658
659
    /**
660
     * @group DBAL-1062
661
     */
662
    public function testRenameIndexUsedInForeignKeyConstraint()
663
    {
664
        if ( ! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
665
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
666
        }
667
668
        $primaryTable = new Table('test_rename_index_primary');
669
        $primaryTable->addColumn('id', 'integer');
670
        $primaryTable->setPrimaryKey(array('id'));
671
672
        $foreignTable = new Table('test_rename_index_foreign');
673
        $foreignTable->addColumn('fk', 'integer');
674
        $foreignTable->addIndex(array('fk'), 'rename_index_fk_idx');
675
        $foreignTable->addForeignKeyConstraint(
676
            'test_rename_index_primary',
677
            array('fk'),
678
            array('id'),
679
            array(),
680
            'fk_constraint'
681
        );
682
683
        $this->_sm->dropAndCreateTable($primaryTable);
684
        $this->_sm->dropAndCreateTable($foreignTable);
685
686
        $foreignTable2 = clone $foreignTable;
687
        $foreignTable2->renameIndex('rename_index_fk_idx', 'renamed_index_fk_idx');
688
689
        $comparator = new Comparator();
690
691
        $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...
692
693
        $foreignTable = $this->_sm->listTableDetails('test_rename_index_foreign');
694
695
        self::assertFalse($foreignTable->hasIndex('rename_index_fk_idx'));
696
        self::assertTrue($foreignTable->hasIndex('renamed_index_fk_idx'));
697
        self::assertTrue($foreignTable->hasForeignKey('fk_constraint'));
698
    }
699
700
    /**
701
     * @group DBAL-42
702
     */
703
    public function testGetColumnComment()
704
    {
705 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...
706
            && ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement()
707
            && $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
708
            $this->markTestSkipped('Database does not support column comments.');
709
        }
710
711
        $table = new Table('column_comment_test');
712
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
713
        $table->setPrimaryKey(array('id'));
714
715
        $this->_sm->createTable($table);
716
717
        $columns = $this->_sm->listTableColumns("column_comment_test");
718
        self::assertEquals(1, count($columns));
719
        self::assertEquals('This is a comment', $columns['id']->getComment());
720
721
        $tableDiff                       = new \Doctrine\DBAL\Schema\TableDiff('column_comment_test');
722
        $tableDiff->fromTable            = $table;
723
        $tableDiff->changedColumns['id'] = new \Doctrine\DBAL\Schema\ColumnDiff(
724
            'id',
725
            new \Doctrine\DBAL\Schema\Column(
726
                'id',
727
                \Doctrine\DBAL\Types\Type::getType('integer'),
728
                array('primary' => true)
729
            ),
730
            array('comment'),
731
            new \Doctrine\DBAL\Schema\Column(
732
                'id',
733
                \Doctrine\DBAL\Types\Type::getType('integer'),
734
                array('comment' => 'This is a comment')
735
            )
736
        );
737
738
        $this->_sm->alterTable($tableDiff);
739
740
        $columns = $this->_sm->listTableColumns("column_comment_test");
741
        self::assertEquals(1, count($columns));
742
        self::assertEmpty($columns['id']->getComment());
743
    }
744
745
    /**
746
     * @group DBAL-42
747
     */
748
    public function testAutomaticallyAppendCommentOnMarkedColumns()
749
    {
750 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...
751
            && ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement()
752
            && $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
753
            $this->markTestSkipped('Database does not support column comments.');
754
        }
755
756
        $table = new Table('column_comment_test2');
757
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
758
        $table->addColumn('obj', 'object', array('comment' => 'This is a comment'));
759
        $table->addColumn('arr', 'array', array('comment' => 'This is a comment'));
760
        $table->setPrimaryKey(array('id'));
761
762
        $this->_sm->createTable($table);
763
764
        $columns = $this->_sm->listTableColumns("column_comment_test2");
765
        self::assertEquals(3, count($columns));
766
        self::assertEquals('This is a comment', $columns['id']->getComment());
767
        self::assertEquals('This is a comment', $columns['obj']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
768
        self::assertInstanceOf('Doctrine\DBAL\Types\ObjectType', $columns['obj']->getType(), "The Doctrine2 should be detected from comment hint.");
769
        self::assertEquals('This is a comment', $columns['arr']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
770
        self::assertInstanceOf('Doctrine\DBAL\Types\ArrayType', $columns['arr']->getType(), "The Doctrine2 should be detected from comment hint.");
771
    }
772
773
    /**
774
     * @group DBAL-1228
775
     */
776
    public function testCommentHintOnDateIntervalTypeColumn()
777
    {
778 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...
779
            && ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement()
780
            && $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
781
            $this->markTestSkipped('Database does not support column comments.');
782
        }
783
784
        $table = new Table('column_dateinterval_comment');
785
        $table->addColumn('id', 'integer', array('comment' => 'This is a comment'));
786
        $table->addColumn('date_interval', 'dateinterval', array('comment' => 'This is a comment'));
787
        $table->setPrimaryKey(array('id'));
788
789
        $this->_sm->createTable($table);
790
791
        $columns = $this->_sm->listTableColumns("column_dateinterval_comment");
792
793
        self::assertEquals(2, count($columns));
794
        self::assertEquals('This is a comment', $columns['id']->getComment());
795
        self::assertEquals('This is a comment', $columns['date_interval']->getComment(), "The Doctrine2 Typehint should be stripped from comment.");
796
        self::assertInstanceOf('Doctrine\DBAL\Types\DateIntervalType', $columns['date_interval']->getType(), "The Doctrine2 should be detected from comment hint.");
797
    }
798
799
    /**
800
     * @group DBAL-825
801
     */
802
    public function testChangeColumnsTypeWithDefaultValue()
803
    {
804
        $tableName = 'column_def_change_type';
805
        $table     = new Table($tableName);
806
807
        $table->addColumn('col_int', 'smallint', array('default' => 666));
808
        $table->addColumn('col_string', 'string', array('default' => 'foo'));
809
810
        $this->_sm->dropAndCreateTable($table);
811
812
        $tableDiff                            = new TableDiff($tableName);
813
        $tableDiff->fromTable                 = $table;
814
        $tableDiff->changedColumns['col_int'] = new ColumnDiff(
815
            'col_int',
816
            new Column('col_int', Type::getType('integer'), array('default' => 666)),
817
            array('type'),
818
            new Column('col_int', Type::getType('smallint'), array('default' => 666))
819
        );
820
821
        $tableDiff->changedColumns['col_string'] = new ColumnDiff(
822
            'col_string',
823
            new Column('col_string', Type::getType('string'), array('default' => 'foo', 'fixed' => true)),
824
            array('fixed'),
825
            new Column('col_string', Type::getType('string'), array('default' => 'foo'))
826
        );
827
828
        $this->_sm->alterTable($tableDiff);
829
830
        $columns = $this->_sm->listTableColumns($tableName);
831
832
        self::assertInstanceOf('Doctrine\DBAL\Types\IntegerType', $columns['col_int']->getType());
833
        self::assertEquals(666, $columns['col_int']->getDefault());
834
835
        self::assertInstanceOf('Doctrine\DBAL\Types\StringType', $columns['col_string']->getType());
836
        self::assertEquals('foo', $columns['col_string']->getDefault());
837
    }
838
839
    /**
840
     * @group DBAL-197
841
     */
842
    public function testListTableWithBlob()
843
    {
844
        $table = new Table('test_blob_table');
845
        $table->addColumn('id', 'integer', ['comment' => 'This is a comment']);
846
        $table->addColumn('binarydata', 'blob', []);
847
        $table->setPrimaryKey(['id']);
848
849
        $this->_sm->createTable($table);
850
851
        $created = $this->_sm->listTableDetails('test_blob_table');
852
853
        self::assertTrue($created->hasColumn('id'));
854
        self::assertTrue($created->hasColumn('binarydata'));
855
        self::assertTrue($created->hasPrimaryKey());
856
    }
857
858
    /**
859
     * @param string $name
860
     * @param array $data
861
     * @return Table
862
     */
863
    protected function createTestTable($name = 'test_table', $data = array())
864
    {
865
        $options = array();
866
        if (isset($data['options'])) {
867
            $options = $data['options'];
868
        }
869
870
        $table = $this->getTestTable($name, $options);
871
872
        $this->_sm->dropAndCreateTable($table);
873
874
        return $table;
875
    }
876
877
    protected function getTestTable($name, $options = array())
878
    {
879
        $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...
880
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
881
        $table->addColumn('id', 'integer', array('notnull' => true));
882
        $table->setPrimaryKey(array('id'));
883
        $table->addColumn('test', 'string', array('length' => 255));
884
        $table->addColumn('foreign_key_test', 'integer');
885
        return $table;
886
    }
887
888
    protected function getTestCompositeTable($name)
889
    {
890
        $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...
891
        $table->setSchemaConfig($this->_sm->createSchemaConfig());
892
        $table->addColumn('id', 'integer', array('notnull' => true));
893
        $table->addColumn('other_id', 'integer', array('notnull' => true));
894
        $table->setPrimaryKey(array('id', 'other_id'));
895
        $table->addColumn('test', 'string', array('length' => 255));
896
        return $table;
897
    }
898
899
    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...
900
    {
901
        $foundTable = false;
902 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...
903
            self::assertInstanceOf('Doctrine\DBAL\Schema\Table', $table, 'No Table instance was found in tables array.');
904
            if (strtolower($table->getName()) == 'list_tables_test_new_name') {
905
                $foundTable = true;
906
            }
907
        }
908
        self::assertTrue($foundTable, "Could not find new table");
909
    }
910
911
    public function testListForeignKeysComposite()
912
    {
913
        if ( ! $this->_conn->getDatabasePlatform()->supportsForeignKeyConstraints()) {
914
            $this->markTestSkipped('Does not support foreign key constraints.');
915
        }
916
917
        $this->_sm->createTable($this->getTestTable('test_create_fk3'));
918
        $this->_sm->createTable($this->getTestCompositeTable('test_create_fk4'));
919
920
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
921
            array('id', 'foreign_key_test'),
922
            'test_create_fk4',
923
            array('id', 'other_id'),
924
            'foreign_key_test_fk2'
925
        );
926
927
        $this->_sm->createForeignKey($foreignKey, 'test_create_fk3');
928
929
        $fkeys = $this->_sm->listTableForeignKeys('test_create_fk3');
930
931
        self::assertEquals(1, count($fkeys), "Table 'test_create_fk3' has to have one foreign key.");
932
933
        self::assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $fkeys[0]);
934
        self::assertEquals(array('id', 'foreign_key_test'), array_map('strtolower', $fkeys[0]->getLocalColumns()));
935
        self::assertEquals(array('id', 'other_id'), array_map('strtolower', $fkeys[0]->getForeignColumns()));
936
    }
937
938
    /**
939
     * @group DBAL-44
940
     */
941
    public function testColumnDefaultLifecycle()
942
    {
943
        $table = new Table("col_def_lifecycle");
944
        $table->addColumn('id', 'integer', array('primary' => true, 'autoincrement' => true));
945
        $table->addColumn('column1', 'string', array('default' => null));
946
        $table->addColumn('column2', 'string', array('default' => false));
947
        $table->addColumn('column3', 'string', array('default' => true));
948
        $table->addColumn('column4', 'string', array('default' => 0));
949
        $table->addColumn('column5', 'string', array('default' => ''));
950
        $table->addColumn('column6', 'string', array('default' => 'def'));
951
        $table->addColumn('column7', 'integer', array('default' => 0));
952
        $table->setPrimaryKey(array('id'));
953
954
        $this->_sm->dropAndCreateTable($table);
955
956
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
957
958
        self::assertNull($columns['id']->getDefault());
959
        self::assertNull($columns['column1']->getDefault());
960
        self::assertSame('', $columns['column2']->getDefault());
961
        self::assertSame('1', $columns['column3']->getDefault());
962
        self::assertSame('0', $columns['column4']->getDefault());
963
        self::assertSame('', $columns['column5']->getDefault());
964
        self::assertSame('def', $columns['column6']->getDefault());
965
        self::assertSame('0', $columns['column7']->getDefault());
966
967
        $diffTable = clone $table;
968
969
        $diffTable->changeColumn('column1', array('default' => false));
970
        $diffTable->changeColumn('column2', array('default' => null));
971
        $diffTable->changeColumn('column3', array('default' => false));
972
        $diffTable->changeColumn('column4', array('default' => null));
973
        $diffTable->changeColumn('column5', array('default' => false));
974
        $diffTable->changeColumn('column6', array('default' => 666));
975
        $diffTable->changeColumn('column7', array('default' => null));
976
977
        $comparator = new Comparator();
978
979
        $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...
980
981
        $columns = $this->_sm->listTableColumns('col_def_lifecycle');
982
983
        self::assertSame('', $columns['column1']->getDefault());
984
        self::assertNull($columns['column2']->getDefault());
985
        self::assertSame('', $columns['column3']->getDefault());
986
        self::assertNull($columns['column4']->getDefault());
987
        self::assertSame('', $columns['column5']->getDefault());
988
        self::assertSame('666', $columns['column6']->getDefault());
989
        self::assertNull($columns['column7']->getDefault());
990
    }
991
992 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...
993
    {
994
        $tableName = 'test_binary_table';
995
996
        $table = new Table($tableName);
997
        $table->addColumn('id', 'integer');
998
        $table->addColumn('column_varbinary', 'binary', array());
999
        $table->addColumn('column_binary', 'binary', array('fixed' => true));
1000
        $table->setPrimaryKey(array('id'));
1001
1002
        $this->_sm->createTable($table);
1003
1004
        $table = $this->_sm->listTableDetails($tableName);
1005
1006
        self::assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_varbinary')->getType());
1007
        self::assertFalse($table->getColumn('column_varbinary')->getFixed());
1008
1009
        self::assertInstanceOf('Doctrine\DBAL\Types\BinaryType', $table->getColumn('column_binary')->getType());
1010
        self::assertTrue($table->getColumn('column_binary')->getFixed());
1011
    }
1012
1013
    public function testListTableDetailsWithFullQualifiedTableName()
1014
    {
1015
        if ( ! $this->_sm->getDatabasePlatform()->supportsSchemas()) {
1016
            $this->markTestSkipped('Test only works on platforms that support schemas.');
1017
        }
1018
1019
        $defaultSchemaName = $this->_sm->getDatabasePlatform()->getDefaultSchemaName();
1020
        $primaryTableName  = 'primary_table';
1021
        $foreignTableName  = 'foreign_table';
1022
1023
        $table = new Table($foreignTableName);
1024
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1025
        $table->setPrimaryKey(array('id'));
1026
1027
        $this->_sm->dropAndCreateTable($table);
1028
1029
        $table = new Table($primaryTableName);
1030
        $table->addColumn('id', 'integer', array('autoincrement' => true));
1031
        $table->addColumn('foo', 'integer');
1032
        $table->addColumn('bar', 'string');
1033
        $table->addForeignKeyConstraint($foreignTableName, array('foo'), array('id'));
1034
        $table->addIndex(array('bar'));
1035
        $table->setPrimaryKey(array('id'));
1036
1037
        $this->_sm->dropAndCreateTable($table);
1038
1039
        self::assertEquals(
1040
            $this->_sm->listTableColumns($primaryTableName),
1041
            $this->_sm->listTableColumns($defaultSchemaName . '.' . $primaryTableName)
1042
        );
1043
        self::assertEquals(
1044
            $this->_sm->listTableIndexes($primaryTableName),
1045
            $this->_sm->listTableIndexes($defaultSchemaName . '.' . $primaryTableName)
1046
        );
1047
        self::assertEquals(
1048
            $this->_sm->listTableForeignKeys($primaryTableName),
1049
            $this->_sm->listTableForeignKeys($defaultSchemaName . '.' . $primaryTableName)
1050
        );
1051
    }
1052
1053
    public function testCommentStringsAreQuoted()
1054
    {
1055 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...
1056
            && ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement()
1057
            && $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1058
            $this->markTestSkipped('Database does not support column comments.');
1059
        }
1060
1061
        $table = new Table('my_table');
1062
        $table->addColumn('id', 'integer', array('comment' => "It's a comment with a quote"));
1063
        $table->setPrimaryKey(array('id'));
1064
1065
        $this->_sm->createTable($table);
1066
1067
        $columns = $this->_sm->listTableColumns("my_table");
1068
        self::assertEquals("It's a comment with a quote", $columns['id']->getComment());
1069
    }
1070
1071
    public function testCommentNotDuplicated()
1072
    {
1073
        if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments()) {
1074
            $this->markTestSkipped('Database does not support column comments.');
1075
        }
1076
1077
        $options          = array(
1078
            'type' => Type::getType('integer'),
1079
            'default' => 0,
1080
            'notnull' => true,
1081
            'comment' => 'expected+column+comment',
1082
        );
1083
        $columnDefinition = substr($this->_conn->getDatabasePlatform()->getColumnDeclarationSQL('id', $options), strlen('id') + 1);
1084
1085
        $table = new Table('my_table');
1086
        $table->addColumn('id', 'integer', array('columnDefinition' => $columnDefinition, 'comment' => 'unexpected_column_comment'));
1087
        $sql = $this->_conn->getDatabasePlatform()->getCreateTableSQL($table);
1088
1089
        self::assertContains('expected+column+comment', $sql[0]);
1090
        self::assertNotContains('unexpected_column_comment', $sql[0]);
1091
    }
1092
1093
    /**
1094
     * @group DBAL-1009
1095
     *
1096
     * @dataProvider getAlterColumnComment
1097
     */
1098
    public function testAlterColumnComment($comment1, $expectedComment1, $comment2, $expectedComment2)
1099
    {
1100 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...
1101
            && ! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement()
1102
            && $this->_conn->getDatabasePlatform()->getName() != 'mssql') {
1103
            $this->markTestSkipped('Database does not support column comments.');
1104
        }
1105
1106
        $offlineTable = new Table('alter_column_comment_test');
1107
        $offlineTable->addColumn('comment1', 'integer', array('comment' => $comment1));
1108
        $offlineTable->addColumn('comment2', 'integer', array('comment' => $comment2));
1109
        $offlineTable->addColumn('no_comment1', 'integer');
1110
        $offlineTable->addColumn('no_comment2', 'integer');
1111
        $this->_sm->dropAndCreateTable($offlineTable);
1112
1113
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1114
1115
        self::assertSame($expectedComment1, $onlineTable->getColumn('comment1')->getComment());
1116
        self::assertSame($expectedComment2, $onlineTable->getColumn('comment2')->getComment());
1117
        self::assertNull($onlineTable->getColumn('no_comment1')->getComment());
1118
        self::assertNull($onlineTable->getColumn('no_comment2')->getComment());
1119
1120
        $onlineTable->changeColumn('comment1', array('comment' => $comment2));
1121
        $onlineTable->changeColumn('comment2', array('comment' => $comment1));
1122
        $onlineTable->changeColumn('no_comment1', array('comment' => $comment1));
1123
        $onlineTable->changeColumn('no_comment2', array('comment' => $comment2));
1124
1125
        $comparator = new Comparator();
1126
1127
        $tableDiff = $comparator->diffTable($offlineTable, $onlineTable);
1128
1129
        self::assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
1130
1131
        $this->_sm->alterTable($tableDiff);
0 ignored issues
show
Security Bug introduced by
It seems like $tableDiff defined by $comparator->diffTable($...ineTable, $onlineTable) on line 1127 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...
1132
1133
        $onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
1134
1135
        self::assertSame($expectedComment2, $onlineTable->getColumn('comment1')->getComment());
1136
        self::assertSame($expectedComment1, $onlineTable->getColumn('comment2')->getComment());
1137
        self::assertSame($expectedComment1, $onlineTable->getColumn('no_comment1')->getComment());
1138
        self::assertSame($expectedComment2, $onlineTable->getColumn('no_comment2')->getComment());
1139
    }
1140
1141
    public function getAlterColumnComment()
1142
    {
1143
        return array(
1144
            array(null, null, ' ', ' '),
1145
            array(null, null, '0', '0'),
1146
            array(null, null, 'foo', 'foo'),
1147
1148
            array('', null, ' ', ' '),
1149
            array('', null, '0', '0'),
1150
            array('', null, 'foo', 'foo'),
1151
1152
            array(' ', ' ', '0', '0'),
1153
            array(' ', ' ', 'foo', 'foo'),
1154
1155
            array('0', '0', 'foo', 'foo'),
1156
        );
1157
    }
1158
1159
    /**
1160
     * @group DBAL-1095
1161
     */
1162
    public function testDoesNotListIndexesImplicitlyCreatedByForeignKeys()
1163
    {
1164
        if ( ! $this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
1165
            $this->markTestSkipped('This test is only supported on platforms that have foreign keys.');
1166
        }
1167
1168
        $primaryTable = new Table('test_list_index_impl_primary');
1169
        $primaryTable->addColumn('id', 'integer');
1170
        $primaryTable->setPrimaryKey(array('id'));
1171
1172
        $foreignTable = new Table('test_list_index_impl_foreign');
1173
        $foreignTable->addColumn('fk1', 'integer');
1174
        $foreignTable->addColumn('fk2', 'integer');
1175
        $foreignTable->addIndex(array('fk1'), 'explicit_fk1_idx');
1176
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk1'), array('id'));
1177
        $foreignTable->addForeignKeyConstraint('test_list_index_impl_primary', array('fk2'), array('id'));
1178
1179
        $this->_sm->dropAndCreateTable($primaryTable);
1180
        $this->_sm->dropAndCreateTable($foreignTable);
1181
1182
        $indexes = $this->_sm->listTableIndexes('test_list_index_impl_foreign');
1183
1184
        self::assertCount(2, $indexes);
1185
        self::assertArrayHasKey('explicit_fk1_idx', $indexes);
1186
        self::assertArrayHasKey('idx_3d6c147fdc58d6c', $indexes);
1187
    }
1188
}
1189