Failed Conditions
Pull Request — master (#2825)
by Sébastien
11:02
created

testColumnDefaultValuesDoubleQuoted()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 13

Duplication

Lines 25
Ratio 100 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 25
loc 25
rs 8.8571
cc 1
eloc 13
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional\Schema;
4
5
use Doctrine\DBAL\Platforms\MariaDb1027Platform;
6
use Doctrine\DBAL\Platforms\MySqlPlatform;
7
use Doctrine\DBAL\Schema\Comparator;
8
use Doctrine\DBAL\Schema\Schema;
9
use Doctrine\DBAL\Schema\Table;
10
use Doctrine\DBAL\Types\Type;
11
12
class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
13
{
14
15
    protected function setUp()
16
    {
17
        parent::setUp();
18
19
        if (!Type::hasType('point')) {
20
            Type::addType('point', 'Doctrine\Tests\Types\MySqlPointType');
21
        }
22
    }
23
24
    public function testSwitchPrimaryKeyColumns()
25
    {
26
        $tableOld = new Table("switch_primary_key_columns");
27
        $tableOld->addColumn('foo_id', 'integer');
28
        $tableOld->addColumn('bar_id', 'integer');
29
30
        $this->_sm->createTable($tableOld);
31
        $tableFetched = $this->_sm->listTableDetails("switch_primary_key_columns");
32
        $tableNew = clone $tableFetched;
33
        $tableNew->setPrimaryKey(array('bar_id', 'foo_id'));
34
35
        $comparator = new Comparator;
36
        $this->_sm->alterTable($comparator->diffTable($tableFetched, $tableNew));
0 ignored issues
show
Security Bug introduced by
It seems like $comparator->diffTable($tableFetched, $tableNew) 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...
37
38
        $table      = $this->_sm->listTableDetails('switch_primary_key_columns');
39
        $primaryKey = $table->getPrimaryKeyColumns();
40
41
        self::assertCount(2, $primaryKey);
42
        self::assertContains('bar_id', $primaryKey);
43
        self::assertContains('foo_id', $primaryKey);
44
    }
45
46
    public function testDiffTableBug()
47
    {
48
        $schema = new Schema();
49
        $table = $schema->createTable('diffbug_routing_translations');
50
        $table->addColumn('id', 'integer');
51
        $table->addColumn('route', 'string');
52
        $table->addColumn('locale', 'string');
53
        $table->addColumn('attribute', 'string');
54
        $table->addColumn('localized_value', 'string');
55
        $table->addColumn('original_value', 'string');
56
        $table->setPrimaryKey(array('id'));
57
        $table->addUniqueIndex(array('route', 'locale', 'attribute'));
58
        $table->addIndex(array('localized_value')); // this is much more selective than the unique index
59
60
        $this->_sm->createTable($table);
61
        $tableFetched = $this->_sm->listTableDetails("diffbug_routing_translations");
62
63
        $comparator = new Comparator;
64
        $diff = $comparator->diffTable($tableFetched, $table);
65
66
        self::assertFalse($diff, "no changes expected.");
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($tableFetched, $table) on line 64 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...
67
    }
68
69 View Code Duplication
    public function testFulltextIndex()
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...
70
    {
71
        $table = new Table('fulltext_index');
72
        $table->addColumn('text', 'text');
73
        $table->addIndex(array('text'), 'f_index');
74
        $table->addOption('engine', 'MyISAM');
75
76
        $index = $table->getIndex('f_index');
77
        $index->addFlag('fulltext');
78
79
        $this->_sm->dropAndCreateTable($table);
80
81
        $indexes = $this->_sm->listTableIndexes('fulltext_index');
82
        self::assertArrayHasKey('f_index', $indexes);
83
        self::assertTrue($indexes['f_index']->hasFlag('fulltext'));
84
    }
85
86 View Code Duplication
    public function testSpatialIndex()
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...
87
    {
88
        $table = new Table('spatial_index');
89
        $table->addColumn('point', 'point');
90
        $table->addIndex(array('point'), 's_index');
91
        $table->addOption('engine', 'MyISAM');
92
93
        $index = $table->getIndex('s_index');
94
        $index->addFlag('spatial');
95
96
        $this->_sm->dropAndCreateTable($table);
97
98
        $indexes = $this->_sm->listTableIndexes('spatial_index');
99
        self::assertArrayHasKey('s_index', $indexes);
100
        self::assertTrue($indexes['s_index']->hasFlag('spatial'));
101
    }
102
103
    /**
104
     * @group DBAL-400
105
     */
106
    public function testAlterTableAddPrimaryKey()
107
    {
108
        $table = new Table('alter_table_add_pk');
109
        $table->addColumn('id', 'integer');
110
        $table->addColumn('foo', 'integer');
111
        $table->addIndex(array('id'), 'idx_id');
112
113
        $this->_sm->createTable($table);
114
115
        $comparator = new Comparator();
116
        $diffTable  = clone $table;
117
118
        $diffTable->dropIndex('idx_id');
119
        $diffTable->setPrimaryKey(array('id'));
120
121
        $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...
122
123
        $table = $this->_sm->listTableDetails("alter_table_add_pk");
124
125
        self::assertFalse($table->hasIndex('idx_id'));
126
        self::assertTrue($table->hasPrimaryKey());
127
    }
128
129
    /**
130
     * @group DBAL-464
131
     */
132
    public function testDropPrimaryKeyWithAutoincrementColumn()
133
    {
134
        $table = new Table("drop_primary_key");
135
        $table->addColumn('id', 'integer', array('primary' => true, 'autoincrement' => true));
136
        $table->addColumn('foo', 'integer', array('primary' => true));
137
        $table->setPrimaryKey(array('id', 'foo'));
138
139
        $this->_sm->dropAndCreateTable($table);
140
141
        $diffTable = clone $table;
142
143
        $diffTable->dropPrimaryKey();
144
145
        $comparator = new Comparator();
146
147
        $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...
148
149
        $table = $this->_sm->listTableDetails("drop_primary_key");
150
151
        self::assertFalse($table->hasPrimaryKey());
152
        self::assertFalse($table->getColumn('id')->getAutoincrement());
153
    }
154
155
    /**
156
     * @group DBAL-789
157
     */
158
    public function testDoesNotPropagateDefaultValuesForUnsupportedColumnTypes()
159
    {
160
        if ($this->_sm->getDatabasePlatform() instanceof MariaDb1027Platform) {
161
            $this->markTestSkipped('MariaDb1027Platform supports default values for BLOB and TEXT columns and will propagate values');
162
        }
163
164
        $table = new Table("text_blob_default_value");
165
        $table->addColumn('def_text', 'text', array('default' => 'def'));
166
        $table->addColumn('def_text_null', 'text', array('notnull' => false, 'default' => 'def'));
167
        $table->addColumn('def_blob', 'blob', array('default' => 'def'));
168
        $table->addColumn('def_blob_null', 'blob', array('notnull' => false, 'default' => 'def'));
169
170
        $this->_sm->dropAndCreateTable($table);
171
172
        $onlineTable = $this->_sm->listTableDetails("text_blob_default_value");
173
174
        self::assertNull($onlineTable->getColumn('def_text')->getDefault());
175
        self::assertNull($onlineTable->getColumn('def_text_null')->getDefault());
176
        self::assertFalse($onlineTable->getColumn('def_text_null')->getNotnull());
177
        self::assertNull($onlineTable->getColumn('def_blob')->getDefault());
178
        self::assertNull($onlineTable->getColumn('def_blob_null')->getDefault());
179
        self::assertFalse($onlineTable->getColumn('def_blob_null')->getNotnull());
180
181
        $comparator = new Comparator();
182
183
        $this->_sm->alterTable($comparator->diffTable($table, $onlineTable));
0 ignored issues
show
Security Bug introduced by
It seems like $comparator->diffTable($table, $onlineTable) 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...
184
185
        $onlineTable = $this->_sm->listTableDetails("text_blob_default_value");
186
187
        self::assertNull($onlineTable->getColumn('def_text')->getDefault());
188
        self::assertNull($onlineTable->getColumn('def_text_null')->getDefault());
189
        self::assertFalse($onlineTable->getColumn('def_text_null')->getNotnull());
190
        self::assertNull($onlineTable->getColumn('def_blob')->getDefault());
191
        self::assertNull($onlineTable->getColumn('def_blob_null')->getDefault());
192
        self::assertFalse($onlineTable->getColumn('def_blob_null')->getNotnull());
193
    }
194
195
    /**
196
     * Since MariaDB 10.2.1, Blob and text columns can have a default value
197
     *
198
     * @link https://mariadb.com/kb/en/library/blob-and-text-data-types
199
     */
200
    public function testDefaultValueSupportForBlobAndText()
201
    {
202
        if (!$this->_sm->getDatabasePlatform() instanceof MariaDb1027Platform) {
203
            $this->markTestSkipped('Only MariaDb1027Platform supports default values for BLOB and TEXT columns');
204
        }
205
206
        $table = new Table("text_blob_default_value");
207
        $table->addColumn('def_text', 'text', array('default' => 'def'));
208
        $table->addColumn('def_text_null', 'text', array('notnull' => false, 'default' => 'def'));
209
        $table->addColumn('def_blob', 'blob', array('default' => 'def'));
210
        $table->addColumn('def_blob_null', 'blob', array('notnull' => false, 'default' => 'def'));
211
212
        $this->_sm->dropAndCreateTable($table);
213
214
        $onlineTable = $this->_sm->listTableDetails("text_blob_default_value");
215
216
        self::assertSame('def', $onlineTable->getColumn('def_text')->getDefault());
217
        self::assertSame('def', $onlineTable->getColumn('def_text_null')->getDefault());
218
        self::assertSame('def', $onlineTable->getColumn('def_blob')->getDefault());
219
        self::assertSame('def', $onlineTable->getColumn('def_blob_null')->getDefault());
220
221
        $comparator = new Comparator();
222
223
        self::assertFalse($comparator->diffTable($table, $onlineTable));
0 ignored issues
show
Bug introduced by
It seems like $comparator->diffTable($table, $onlineTable) targeting Doctrine\DBAL\Schema\Comparator::diffTable() 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?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
224
    }
225
226 View Code Duplication
    public function testColumnCollation()
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...
227
    {
228
        $table = new Table('test_collation');
229
        $table->addOption('collate', $collation = 'latin1_swedish_ci');
230
        $table->addOption('charset', 'latin1');
231
        $table->addColumn('id', 'integer');
232
        $table->addColumn('text', 'text');
233
        $table->addColumn('foo', 'text')->setPlatformOption('collation', 'latin1_swedish_ci');
234
        $table->addColumn('bar', 'text')->setPlatformOption('collation', 'utf8_general_ci');
235
        $this->_sm->dropAndCreateTable($table);
236
237
        $columns = $this->_sm->listTableColumns('test_collation');
238
239
        self::assertArrayNotHasKey('collation', $columns['id']->getPlatformOptions());
240
        self::assertEquals('latin1_swedish_ci', $columns['text']->getPlatformOption('collation'));
241
        self::assertEquals('latin1_swedish_ci', $columns['foo']->getPlatformOption('collation'));
242
        self::assertEquals('utf8_general_ci', $columns['bar']->getPlatformOption('collation'));
243
    }
244
245
    /**
246
     * @group DBAL-843
247
     */
248
    public function testListLobTypeColumns()
249
    {
250
        $tableName = 'lob_type_columns';
251
        $table = new Table($tableName);
252
253
        $table->addColumn('col_tinytext', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_TINYTEXT));
254
        $table->addColumn('col_text', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_TEXT));
255
        $table->addColumn('col_mediumtext', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMTEXT));
256
        $table->addColumn('col_longtext', 'text');
257
258
        $table->addColumn('col_tinyblob', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_TINYBLOB));
259
        $table->addColumn('col_blob', 'blob', array('length' => MySqlPlatform::LENGTH_LIMIT_BLOB));
260
        $table->addColumn('col_mediumblob', 'blob', array('length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMBLOB));
261
        $table->addColumn('col_longblob', 'blob');
262
263
        $this->_sm->dropAndCreateTable($table);
264
265
        $platform = $this->_sm->getDatabasePlatform();
266
        $offlineColumns = $table->getColumns();
267
        $onlineColumns = $this->_sm->listTableColumns($tableName);
268
269
        self::assertSame(
270
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_tinytext']->toArray()),
271
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_tinytext']->toArray())
272
        );
273
        self::assertSame(
274
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_text']->toArray()),
275
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_text']->toArray())
276
        );
277
        self::assertSame(
278
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_mediumtext']->toArray()),
279
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_mediumtext']->toArray())
280
        );
281
        self::assertSame(
282
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_longtext']->toArray()),
283
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_longtext']->toArray())
284
        );
285
286
        self::assertSame(
287
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_tinyblob']->toArray()),
288
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_tinyblob']->toArray())
289
        );
290
        self::assertSame(
291
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_blob']->toArray()),
292
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_blob']->toArray())
293
        );
294
        self::assertSame(
295
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_mediumblob']->toArray()),
296
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_mediumblob']->toArray())
297
        );
298
        self::assertSame(
299
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_longblob']->toArray()),
300
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_longblob']->toArray())
301
        );
302
    }
303
304
    /**
305
     * @group DBAL-423
306
     */
307
    public function testDiffListGuidTableColumn()
308
    {
309
        $offlineTable = new Table('list_guid_table_column');
310
        $offlineTable->addColumn('col_guid', 'guid');
311
312
        $this->_sm->dropAndCreateTable($offlineTable);
313
314
        $onlineTable = $this->_sm->listTableDetails('list_guid_table_column');
315
316
        $comparator = new Comparator();
317
318
        self::assertFalse(
319
            $comparator->diffTable($offlineTable, $onlineTable),
0 ignored issues
show
Bug introduced by
It seems like $comparator->diffTable($...ineTable, $onlineTable) targeting Doctrine\DBAL\Schema\Comparator::diffTable() 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?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
320
            "No differences should be detected with the offline vs online schema."
321
        );
322
    }
323
324
    /**
325
     * @group DBAL-1082
326
     */
327 View Code Duplication
    public function testListDecimalTypeColumns()
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...
328
    {
329
        $tableName = 'test_list_decimal_columns';
330
        $table = new Table($tableName);
331
332
        $table->addColumn('col', 'decimal');
333
        $table->addColumn('col_unsigned', 'decimal', array('unsigned' => true));
334
335
        $this->_sm->dropAndCreateTable($table);
336
337
        $columns = $this->_sm->listTableColumns($tableName);
338
339
        self::assertArrayHasKey('col', $columns);
340
        self::assertArrayHasKey('col_unsigned', $columns);
341
        self::assertFalse($columns['col']->getUnsigned());
342
        self::assertTrue($columns['col_unsigned']->getUnsigned());
343
    }
344
345
    /**
346
     * @group DBAL-1082
347
     */
348 View Code Duplication
    public function testListFloatTypeColumns()
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...
349
    {
350
        $tableName = 'test_list_float_columns';
351
        $table = new Table($tableName);
352
353
        $table->addColumn('col', 'float');
354
        $table->addColumn('col_unsigned', 'float', array('unsigned' => true));
355
356
        $this->_sm->dropAndCreateTable($table);
357
358
        $columns = $this->_sm->listTableColumns($tableName);
359
360
        self::assertArrayHasKey('col', $columns);
361
        self::assertArrayHasKey('col_unsigned', $columns);
362
        self::assertFalse($columns['col']->getUnsigned());
363
        self::assertTrue($columns['col_unsigned']->getUnsigned());
364
    }
365
366
367
    /**
368
     * As of MariaDB 10.2.7, nullable default values literals are always single quoted in
369
     * information_schema. Non-nullable defaults behaviour is not affected.
370
     * This test ensure accidental removal of double single encoded defaults for MariaDB >= 10.2.7.
371
     *
372
     * @link https://mariadb.com/kb/en/library/information-schema-columns-table/
373
     * @link https://dev.mysql.com/doc/refman/5.5/en/string-literals.html
374
     */
375 View Code Duplication
    public function testColumnDefaultValuesDoubleQuoted(): 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...
376
    {
377
378
        $table = new Table("test_column_default_values_double_quoted");
379
        $table->addColumn('string_nullable_quoted', 'string', ['notnull' => false, 'default' => 'NULL']);
380
        $table->addColumn('string_nullable_double_quoted', 'string', ['notnull' => false, 'default' => "'NULL'"]);
381
382
        $table->addColumn('string_notnull_quoted', 'string', ['notnull' => true, 'default' => 'NULL']);
383
        //$table->addColumn('string_notnull_double_quoted', 'string', ['notnull' => true, 'default' => "\\'NULL\\'"]);
0 ignored issues
show
Unused Code Comprehensibility introduced by
66% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
384
385
        $this->_sm->dropAndCreateTable($table);
386
387
        $onlineTable = $this->_sm->listTableDetails("test_column_default_values_double_quoted");
388
        self::assertSame('NULL', $onlineTable->getColumn('string_nullable_quoted')->getDefault());
389
390
        self::assertSame("'NULL'", $onlineTable->getColumn('string_nullable_double_quoted')->getDefault());
391
        self::assertSame("NULL", $onlineTable->getColumn('string_notnull_quoted')->getDefault());
392
        //self::assertSame("'NULL'", $onlineTable->getColumn('string_notnull_double_quoted')->getDefault());
0 ignored issues
show
Unused Code Comprehensibility introduced by
79% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
393
394
        $comparator = new Comparator();
395
396
        $diff = $comparator->diffTable($table, $onlineTable);
397
        self::assertFalse($diff, "Tables should be identical with double quoted literals.");
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 396 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...
398
399
    }
400
401
402
    public function testColumnDefaultCurrentTimestamp(): void
403
    {
404
        $platform = $this->_sm->getDatabasePlatform();
405
406
        $table = new Table("test_column_defaults_current_timestamp");
407
408
        $currentTimeStampSql = $platform->getCurrentTimestampSQL();
409
410
        $table->addColumn('col_datetime', 'datetime', ['notnull' => true, 'default' => $currentTimeStampSql]);
411
        $table->addColumn('col_datetime_nullable', 'datetime', ['notnull' => false, 'default' => $currentTimeStampSql]);
412
413
        $this->_sm->dropAndCreateTable($table);
414
415
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_current_timestamp");
416
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime')->getDefault());
417
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime_nullable')->getDefault());
418
419
        $comparator = new Comparator();
420
421
        $diff = $comparator->diffTable($table, $onlineTable);
422
        self::assertFalse($diff, "Tables should be identical with column defaults.");
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 421 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...
423
    }
424
425
    /**
426
     * Test default CURRENT_TIME and CURRENT_DATE as default values
427
     *
428
     * Note: MySQL (as of 5.7.19) does not support default value
429
     * for DATE and TIME fields while MariaDB 10.2+ does
430
     */
431
    public function testColumnDefaultCurrentTimeAndDate()
432
    {
433
        $platform = $this->_sm->getDatabasePlatform();
434
435
        if (!$platform instanceof MariaDb1027Platform) {
436
            $this->markTestSkipped('Currently only MariaDb1027Platform supports setting CURRENT_TIME and CURRENT_DATE default values.');
437
        }
438
439
        $table = new Table("test_column_defaults_current_time_and_date");
440
441
        $currentTimeSql = $platform->getCurrentTimeSQL();
442
        $currentDateSql = $platform->getCurrentDateSQL();
443
444
        $table->addColumn('col_date', 'date', ['notnull' => true, 'default' => $currentDateSql]);
445
        $table->addColumn('col_time', 'time', ['notnull' => true, 'default' => $currentTimeSql]);
446
447
        $this->_sm->dropAndCreateTable($table);
448
449
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_current_time_and_date");
450
451
        self::assertSame($currentDateSql, $onlineTable->getColumn('col_date')->getDefault());
452
        self::assertSame($currentTimeSql, $onlineTable->getColumn('col_time')->getDefault());
453
454
        $comparator = new Comparator();
455
456
        $diff = $comparator->diffTable($table, $onlineTable);
457
        self::assertFalse($diff, "Tables should be identical with column defaults.");
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 456 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...
458
    }
459
460
461
    /**
462
     *
463
     * @link https://mariadb.com/kb/en/library/string-literals
464
     */
465 View Code Duplication
    public function testColumnDefaultValuesEscaping(): 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...
466
    {
467
        $table = new Table("test_column_default_values_escaping");
468
        $table->addColumn('no_quotes', 'string', ['notnull' => false, 'default' => 'az']);
469
470
        $table->addColumn('backslash', 'string', ['notnull' => false, 'default' => 'a\\\z']);
471
        $table->addColumn('repeated_single_quotes', 'string', ['notnull' => false, 'default' => "a''z"]);
472
473
        $this->_sm->dropAndCreateTable($table);
474
475
        $onlineTable = $this->_sm->listTableDetails("test_column_default_values_escaping");
476
        self::assertSame("az", $onlineTable->getColumn('no_quotes')->getDefault());
477
        self::assertSame('a\\\z', $onlineTable->getColumn('backslash')->getDefault());
478
        self::assertSame("a''z", $onlineTable->getColumn('repeated_single_quotes')->getDefault());
479
480
        $comparator = new Comparator();
481
482
        $diff = $comparator->diffTable($table, $onlineTable);
483
        self::assertFalse($diff, "Tables should be identical with values escape sequences.");
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 482 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...
484
    }
485
486
    public function testColumnDefaultsUsingDoctrineTable(): void
487
    {
488
489
        $table = new Table("test_column_defaults_with_table");
490
        $table->addColumn('col0', 'integer', ['notnull' => false]);
491
        $table->addColumn('col1', 'integer', ['notnull' => false, 'default' => null]);
492
        $table->addColumn('col2', 'string', ['notnull' => false, 'default' => null]);
493
        $table->addColumn('col3', 'string', ['notnull' => false, 'default' => 'NULL']);
494
        $table->addColumn('col4', 'string', ['notnull' => false, 'default' => 'Hello world']);
495
        $table->addColumn('col5', 'datetime', ['notnull' => false, 'default' => null]);
496
        $table->addColumn('col6', 'decimal', ['scale' => 3, 'precision' => 6, 'notnull' => false, 'default' => -2.3]);
497
        $table->addColumn('col7', 'date', ['notnull' => false, 'default' => '2012-12-12']);
498
        $table->addColumn('col8', 'string', ['notnull' => true, 'default' => '']);
499
        $table->addColumn('col9', 'integer', ['notnull' => false, 'default' => 0]);
500
        $table->addColumn('col10', 'string', ['notnull' => false, 'default' => 'He"ll"o world']);
501
        $table->addColumn('col11', 'string', ['notnull' => false, 'default' => '2012-12-12 23:59:59']);
502
        //$table->addColumn('col12', 'string', ['notnull' => false, 'default' => 'He\\\'llo \\\world']);
503
504
        $table->addColumn('col20', 'string', ['notnull' => true, 'default' => 'CURRENT_TIMESTAMP()']);
505
        $table->addColumn('col21', 'string', ['notnull' => false, 'default' => 'CURRENT_TIMESTAMP']);
506
507
        $this->_sm->dropAndCreateTable($table);
508
509
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_with_table");
510
        self::assertNull($onlineTable->getColumn('col0')->getDefault());
511
        self::assertNull($onlineTable->getColumn('col1')->getDefault());
512
        self::assertNull($onlineTable->getColumn('col2')->getDefault());
513
        self::assertEquals('NULL', $onlineTable->getColumn('col3')->getDefault());
514
        self::assertEquals('Hello world', $onlineTable->getColumn('col4')->getDefault());
515
        self::assertNull($onlineTable->getColumn('col5')->getDefault());
516
        self::assertEquals(-2.3, $onlineTable->getColumn('col6')->getDefault());
517
        self::assertEquals('2012-12-12', $onlineTable->getColumn('col7')->getDefault());
518
        self::assertTrue($onlineTable->getColumn('col8')->getNotnull());
519
        self::assertEquals('', $onlineTable->getColumn('col8')->getDefault());
520
        self::assertSame('0', $onlineTable->getColumn('col9')->getDefault());
521
        self::assertEquals('He"ll"o world', $onlineTable->getColumn('col10')->getDefault());
522
        self::assertEquals('2012-12-12 23:59:59', $onlineTable->getColumn('col11')->getDefault());
523
        //self::assertEquals('He\\\'llo \\world', $onlineTable->getColumn('col12')->getDefault());
524
525
        // MariaDB 10.2 and MySQL 5.7 differences while storing default now() in information schema.
526
        // MariaDB will always store "current_timestamp()", mysql "CURRENT_TIMESTAMP"
527
        self::assertStringStartsWith('current_timestamp', strtolower($onlineTable->getColumn('col20')->getDefault()));
528
        self::assertStringStartsWith('current_timestamp', strtolower($onlineTable->getColumn('col21')->getDefault()));
529
530
        $comparator = new Comparator();
531
532
        $diff = $comparator->diffTable($table, $onlineTable);
533
        self::assertFalse($diff, "Tables should be identical with column defaults.");
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 532 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...
534
    }
535
536
    /**
537
     * Ensure that an existing table with quoted (literals) default values
538
     * does not trigger a table change.
539
     */
540
    public function testColumnDefaultsDoesNotTriggerADiff(): void
541
    {
542
        $this->_conn->query('DROP TABLE IF EXISTS test_column_defaults_no_diff');
543
        $sql = "
544
            CREATE TABLE test_column_defaults_with_create (
545
                col1 VARCHAR(255) NULL DEFAULT 'O''Connor\'\"',
546
                col2 VARCHAR(255) NULL DEFAULT '''A'''
547
                );
548
        ";
549
550
        $this->_conn->query($sql);
551
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_with_create");
552
        self::assertSame("O'Connor'\"", $onlineTable->getColumn('col1')->getDefault());
553
        self::assertSame("'A'", $onlineTable->getColumn('col2')->getDefault());
554
555
        $table = new Table("test_column_defaults_no_diff");
556
        $table->addColumn('col1', 'string', ['notnull' => false, 'default' => "O'Connor'\""]);
557
        $table->addColumn('col2', 'string', ['notnull' => false, 'default' => "'A'"]);
558
559
        $comparator = new Comparator();
560
        $diff = $comparator->diffTable($table, $onlineTable);
561
        self::assertFalse($diff);
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 560 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...
562
    }
563
564
    /**
565
     * MariaDB supports expressions as default values
566
     *
567
     * @link https://mariadb.com/kb/en/library/information-schema-columns-table/
568
     */
569
    public function testColumnDefaultExpressions(): void
570
    {
571
        $this->markTestSkipped('Setting an expression as a default value is not yet supported (WIP)');
572
573
        if ($this->_sm->getDatabasePlatform() instanceof MariaDb1027Platform) {
574
575
            $table = new Table("test_column_default_expressions");
576
577
            $table->addColumn('expression', 'string', ['notnull' => false, 'default' => "concat('A','B')"]);
578
579
            $this->_sm->dropAndCreateTable($table);
580
581
            $onlineTable = $this->_sm->listTableDetails("test_column_default_expressions");
582
            self::assertSame("concat('A','B')", $onlineTable->getColumn('expression')->getDefault());
583
584
            $comparator = new Comparator();
585
586
            $diff = $comparator->diffTable($table, $onlineTable);
587
            self::assertFalse($diff, "Tables should be identical with expression column defaults.");
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 586 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...
588
        }
589
    }
590
591
}
592