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

testDefaultValueSupportForBlobAndText()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 25
rs 8.8571
cc 2
eloc 16
nc 2
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\Schema\TableDiff;
11
use Doctrine\DBAL\Types\Type;
12
13
class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
14
{
15
16
    protected function setUp()
17
    {
18
        parent::setUp();
19
20
        if (!Type::hasType('point')) {
21
            Type::addType('point', 'Doctrine\Tests\Types\MySqlPointType');
22
        }
23
    }
24
25
    public function testSwitchPrimaryKeyColumns()
26
    {
27
        $tableOld = new Table("switch_primary_key_columns");
28
        $tableOld->addColumn('foo_id', 'integer');
29
        $tableOld->addColumn('bar_id', 'integer');
30
31
        $this->_sm->createTable($tableOld);
32
        $tableFetched = $this->_sm->listTableDetails("switch_primary_key_columns");
33
        $tableNew = clone $tableFetched;
34
        $tableNew->setPrimaryKey(array('bar_id', 'foo_id'));
35
36
        $comparator = new Comparator;
37
        $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...
38
39
        $table      = $this->_sm->listTableDetails('switch_primary_key_columns');
40
        $primaryKey = $table->getPrimaryKeyColumns();
41
42
        self::assertCount(2, $primaryKey);
43
        self::assertContains('bar_id', $primaryKey);
44
        self::assertContains('foo_id', $primaryKey);
45
    }
46
47
    public function testDiffTableBug()
48
    {
49
        $schema = new Schema();
50
        $table = $schema->createTable('diffbug_routing_translations');
51
        $table->addColumn('id', 'integer');
52
        $table->addColumn('route', 'string');
53
        $table->addColumn('locale', 'string');
54
        $table->addColumn('attribute', 'string');
55
        $table->addColumn('localized_value', 'string');
56
        $table->addColumn('original_value', 'string');
57
        $table->setPrimaryKey(array('id'));
58
        $table->addUniqueIndex(array('route', 'locale', 'attribute'));
59
        $table->addIndex(array('localized_value')); // this is much more selective than the unique index
60
61
        $this->_sm->createTable($table);
62
        $tableFetched = $this->_sm->listTableDetails("diffbug_routing_translations");
63
64
        $comparator = new Comparator;
65
        $diff = $comparator->diffTable($tableFetched, $table);
66
67
        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 65 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...
68
    }
69
70 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...
71
    {
72
        $table = new Table('fulltext_index');
73
        $table->addColumn('text', 'text');
74
        $table->addIndex(array('text'), 'f_index');
75
        $table->addOption('engine', 'MyISAM');
76
77
        $index = $table->getIndex('f_index');
78
        $index->addFlag('fulltext');
79
80
        $this->_sm->dropAndCreateTable($table);
81
82
        $indexes = $this->_sm->listTableIndexes('fulltext_index');
83
        self::assertArrayHasKey('f_index', $indexes);
84
        self::assertTrue($indexes['f_index']->hasFlag('fulltext'));
85
    }
86
87 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...
88
    {
89
        $table = new Table('spatial_index');
90
        $table->addColumn('point', 'point');
91
        $table->addIndex(array('point'), 's_index');
92
        $table->addOption('engine', 'MyISAM');
93
94
        $index = $table->getIndex('s_index');
95
        $index->addFlag('spatial');
96
97
        $this->_sm->dropAndCreateTable($table);
98
99
        $indexes = $this->_sm->listTableIndexes('spatial_index');
100
        self::assertArrayHasKey('s_index', $indexes);
101
        self::assertTrue($indexes['s_index']->hasFlag('spatial'));
102
    }
103
104
    /**
105
     * @group DBAL-400
106
     */
107
    public function testAlterTableAddPrimaryKey()
108
    {
109
        $table = new Table('alter_table_add_pk');
110
        $table->addColumn('id', 'integer');
111
        $table->addColumn('foo', 'integer');
112
        $table->addIndex(array('id'), 'idx_id');
113
114
        $this->_sm->createTable($table);
115
116
        $comparator = new Comparator();
117
        $diffTable  = clone $table;
118
119
        $diffTable->dropIndex('idx_id');
120
        $diffTable->setPrimaryKey(array('id'));
121
122
        $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...
123
124
        $table = $this->_sm->listTableDetails("alter_table_add_pk");
125
126
        self::assertFalse($table->hasIndex('idx_id'));
127
        self::assertTrue($table->hasPrimaryKey());
128
    }
129
130
    /**
131
     * @group DBAL-464
132
     */
133
    public function testDropPrimaryKeyWithAutoincrementColumn()
134
    {
135
        $table = new Table("drop_primary_key");
136
        $table->addColumn('id', 'integer', array('primary' => true, 'autoincrement' => true));
137
        $table->addColumn('foo', 'integer', array('primary' => true));
138
        $table->setPrimaryKey(array('id', 'foo'));
139
140
        $this->_sm->dropAndCreateTable($table);
141
142
        $diffTable = clone $table;
143
144
        $diffTable->dropPrimaryKey();
145
146
        $comparator = new Comparator();
147
148
        $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...
149
150
        $table = $this->_sm->listTableDetails("drop_primary_key");
151
152
        self::assertFalse($table->hasPrimaryKey());
153
        self::assertFalse($table->getColumn('id')->getAutoincrement());
154
    }
155
156
    /**
157
     * @group DBAL-789
158
     */
159
    public function testDoesNotPropagateDefaultValuesForUnsupportedColumnTypes()
160
    {
161
        if ($this->_sm->getDatabasePlatform() instanceof MariaDb1027Platform) {
162
            $this->markTestSkipped('MariaDb1027Platform supports default values for BLOB and TEXT columns and will propagate values');
163
        }
164
165
        $table = new Table("text_blob_default_value");
166
        $table->addColumn('def_text', 'text', array('default' => 'def'));
167
        $table->addColumn('def_text_null', 'text', array('notnull' => false, 'default' => 'def'));
168
        $table->addColumn('def_blob', 'blob', array('default' => 'def'));
169
        $table->addColumn('def_blob_null', 'blob', array('notnull' => false, 'default' => 'def'));
170
171
        $this->_sm->dropAndCreateTable($table);
172
173
        $onlineTable = $this->_sm->listTableDetails("text_blob_default_value");
174
175
        self::assertNull($onlineTable->getColumn('def_text')->getDefault());
176
        self::assertNull($onlineTable->getColumn('def_text_null')->getDefault());
177
        self::assertFalse($onlineTable->getColumn('def_text_null')->getNotnull());
178
        self::assertNull($onlineTable->getColumn('def_blob')->getDefault());
179
        self::assertNull($onlineTable->getColumn('def_blob_null')->getDefault());
180
        self::assertFalse($onlineTable->getColumn('def_blob_null')->getNotnull());
181
182
        $comparator = new Comparator();
183
184
        $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...
185
186
        $onlineTable = $this->_sm->listTableDetails("text_blob_default_value");
187
188
        self::assertNull($onlineTable->getColumn('def_text')->getDefault());
189
        self::assertNull($onlineTable->getColumn('def_text_null')->getDefault());
190
        self::assertFalse($onlineTable->getColumn('def_text_null')->getNotnull());
191
        self::assertNull($onlineTable->getColumn('def_blob')->getDefault());
192
        self::assertNull($onlineTable->getColumn('def_blob_null')->getDefault());
193
        self::assertFalse($onlineTable->getColumn('def_blob_null')->getNotnull());
194
    }
195
196
    /**
197
     * Since MariaDB 10.2.1, Blob and text columns can have a default value
198
     *
199
     * @link https://mariadb.com/kb/en/library/blob-and-text-data-types
200
     */
201
    public function testDefaultValueSupportForBlobAndText()
202
    {
203
        if (!$this->_sm->getDatabasePlatform() instanceof MariaDb1027Platform) {
204
            $this->markTestSkipped('Only MariaDb1027Platform supports default values for BLOB and TEXT columns');
205
        }
206
207
        $table = new Table("text_blob_default_value");
208
        $table->addColumn('def_text', 'text', array('default' => 'def'));
209
        $table->addColumn('def_text_null', 'text', array('notnull' => false, 'default' => 'def'));
210
        $table->addColumn('def_blob', 'blob', array('default' => 'def'));
211
        $table->addColumn('def_blob_null', 'blob', array('notnull' => false, 'default' => 'def'));
212
213
        $this->_sm->dropAndCreateTable($table);
214
215
        $onlineTable = $this->_sm->listTableDetails("text_blob_default_value");
216
217
        self::assertSame('def', $onlineTable->getColumn('def_text')->getDefault());
218
        self::assertSame('def', $onlineTable->getColumn('def_text_null')->getDefault());
219
        self::assertSame('def', $onlineTable->getColumn('def_blob')->getDefault());
220
        self::assertSame('def', $onlineTable->getColumn('def_blob_null')->getDefault());
221
222
        $comparator = new Comparator();
223
224
        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...
225
    }
226
227 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...
228
    {
229
        $table = new Table('test_collation');
230
        $table->addOption('collate', $collation = 'latin1_swedish_ci');
231
        $table->addOption('charset', 'latin1');
232
        $table->addColumn('id', 'integer');
233
        $table->addColumn('text', 'text');
234
        $table->addColumn('foo', 'text')->setPlatformOption('collation', 'latin1_swedish_ci');
235
        $table->addColumn('bar', 'text')->setPlatformOption('collation', 'utf8_general_ci');
236
        $this->_sm->dropAndCreateTable($table);
237
238
        $columns = $this->_sm->listTableColumns('test_collation');
239
240
        self::assertArrayNotHasKey('collation', $columns['id']->getPlatformOptions());
241
        self::assertEquals('latin1_swedish_ci', $columns['text']->getPlatformOption('collation'));
242
        self::assertEquals('latin1_swedish_ci', $columns['foo']->getPlatformOption('collation'));
243
        self::assertEquals('utf8_general_ci', $columns['bar']->getPlatformOption('collation'));
244
    }
245
246
    /**
247
     * @group DBAL-843
248
     */
249
    public function testListLobTypeColumns()
250
    {
251
        $tableName = 'lob_type_columns';
252
        $table = new Table($tableName);
253
254
        $table->addColumn('col_tinytext', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_TINYTEXT));
255
        $table->addColumn('col_text', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_TEXT));
256
        $table->addColumn('col_mediumtext', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMTEXT));
257
        $table->addColumn('col_longtext', 'text');
258
259
        $table->addColumn('col_tinyblob', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_TINYBLOB));
260
        $table->addColumn('col_blob', 'blob', array('length' => MySqlPlatform::LENGTH_LIMIT_BLOB));
261
        $table->addColumn('col_mediumblob', 'blob', array('length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMBLOB));
262
        $table->addColumn('col_longblob', 'blob');
263
264
        $this->_sm->dropAndCreateTable($table);
265
266
        $platform = $this->_sm->getDatabasePlatform();
267
        $offlineColumns = $table->getColumns();
268
        $onlineColumns = $this->_sm->listTableColumns($tableName);
269
270
        self::assertSame(
271
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_tinytext']->toArray()),
272
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_tinytext']->toArray())
273
        );
274
        self::assertSame(
275
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_text']->toArray()),
276
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_text']->toArray())
277
        );
278
        self::assertSame(
279
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_mediumtext']->toArray()),
280
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_mediumtext']->toArray())
281
        );
282
        self::assertSame(
283
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_longtext']->toArray()),
284
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_longtext']->toArray())
285
        );
286
287
        self::assertSame(
288
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_tinyblob']->toArray()),
289
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_tinyblob']->toArray())
290
        );
291
        self::assertSame(
292
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_blob']->toArray()),
293
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_blob']->toArray())
294
        );
295
        self::assertSame(
296
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_mediumblob']->toArray()),
297
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_mediumblob']->toArray())
298
        );
299
        self::assertSame(
300
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_longblob']->toArray()),
301
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_longblob']->toArray())
302
        );
303
    }
304
305
    /**
306
     * @group DBAL-423
307
     */
308
    public function testDiffListGuidTableColumn()
309
    {
310
        $offlineTable = new Table('list_guid_table_column');
311
        $offlineTable->addColumn('col_guid', 'guid');
312
313
        $this->_sm->dropAndCreateTable($offlineTable);
314
315
        $onlineTable = $this->_sm->listTableDetails('list_guid_table_column');
316
317
        $comparator = new Comparator();
318
319
        self::assertFalse(
320
            $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...
321
            "No differences should be detected with the offline vs online schema."
322
        );
323
    }
324
325
    /**
326
     * @group DBAL-1082
327
     */
328 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...
329
    {
330
        $tableName = 'test_list_decimal_columns';
331
        $table = new Table($tableName);
332
333
        $table->addColumn('col', 'decimal');
334
        $table->addColumn('col_unsigned', 'decimal', array('unsigned' => true));
335
336
        $this->_sm->dropAndCreateTable($table);
337
338
        $columns = $this->_sm->listTableColumns($tableName);
339
340
        self::assertArrayHasKey('col', $columns);
341
        self::assertArrayHasKey('col_unsigned', $columns);
342
        self::assertFalse($columns['col']->getUnsigned());
343
        self::assertTrue($columns['col_unsigned']->getUnsigned());
344
    }
345
346
    /**
347
     * @group DBAL-1082
348
     */
349 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...
350
    {
351
        $tableName = 'test_list_float_columns';
352
        $table = new Table($tableName);
353
354
        $table->addColumn('col', 'float');
355
        $table->addColumn('col_unsigned', 'float', array('unsigned' => true));
356
357
        $this->_sm->dropAndCreateTable($table);
358
359
        $columns = $this->_sm->listTableColumns($tableName);
360
361
        self::assertArrayHasKey('col', $columns);
362
        self::assertArrayHasKey('col_unsigned', $columns);
363
        self::assertFalse($columns['col']->getUnsigned());
364
        self::assertTrue($columns['col_unsigned']->getUnsigned());
365
    }
366
367
368
    /**
369
     * As of MariaDB 10.2.7, nullable default values literals are always single quoted in
370
     * information_schema. Non-nullable defaults behaviour is not affected.
371
     * This test ensure accidental removal of double single encoded defaults for MariaDB >= 10.2.7.
372
     *
373
     * @link https://mariadb.com/kb/en/library/information-schema-columns-table/
374
     * @link https://dev.mysql.com/doc/refman/5.5/en/string-literals.html
375
     */
376 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...
377
    {
378
379
        $table = new Table("test_column_default_values_double_quoted");
380
        $table->addColumn('string_nullable_quoted', 'string', ['notnull' => false, 'default' => 'NULL']);
381
        $table->addColumn('string_nullable_double_quoted', 'string', ['notnull' => false, 'default' => "'NULL'"]);
382
383
        $table->addColumn('string_notnull_quoted', 'string', ['notnull' => true, 'default' => 'NULL']);
384
        //$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...
385
386
        $this->_sm->dropAndCreateTable($table);
387
388
        $onlineTable = $this->_sm->listTableDetails("test_column_default_values_double_quoted");
389
        self::assertSame('NULL', $onlineTable->getColumn('string_nullable_quoted')->getDefault());
390
391
        self::assertSame("'NULL'", $onlineTable->getColumn('string_nullable_double_quoted')->getDefault());
392
        self::assertSame("NULL", $onlineTable->getColumn('string_notnull_quoted')->getDefault());
393
        //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...
394
395
        $comparator = new Comparator();
396
397
        $diff = $comparator->diffTable($table, $onlineTable);
398
        $this->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 397 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...
399
400
    }
401
402
403
    public function testColumnDefaultCurrentTimestamp(): void
404
    {
405
        $platform = $this->_sm->getDatabasePlatform();
406
407
        $table = new Table("test_column_defaults_current_timestamp");
408
409
        $currentTimeStampSql = $platform->getCurrentTimestampSQL();
410
411
        $table->addColumn('col_datetime', 'datetime', ['notnull' => true, 'default' => $currentTimeStampSql]);
412
        $table->addColumn('col_datetime_nullable', 'datetime', ['notnull' => false, 'default' => $currentTimeStampSql]);
413
414
        $this->_sm->dropAndCreateTable($table);
415
416
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_current_timestamp");
417
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime')->getDefault());
418
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime_nullable')->getDefault());
419
420
        $comparator = new Comparator();
421
422
        $diff = $comparator->diffTable($table, $onlineTable);
423
        $this->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 422 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...
424
    }
425
426
    /**
427
     * Test default CURRENT_TIME and CURRENT_DATE as default values
428
     *
429
     * Note: MySQL (as of 5.7.19) does not support default value
430
     * for DATE and TIME fields while MariaDB 10.2+ does
431
     */
432
    public function testColumnDefaultCurrentTimeAndDate()
433
    {
434
        $platform = $this->_sm->getDatabasePlatform();
435
436
        if (!$platform instanceof MariaDb1027Platform) {
437
            $this->markTestSkipped('Currently only MariaDb1027Platform supports setting CURRENT_TIME and CURRENT_DATE default values.');
438
        }
439
440
        $table = new Table("test_column_defaults_current_time_and_date");
441
442
        $currentTimeSql = $platform->getCurrentTimeSQL();
443
        $currentDateSql = $platform->getCurrentDateSQL();
444
445
        $table->addColumn('col_date', 'date', ['notnull' => true, 'default' => $currentDateSql]);
446
        $table->addColumn('col_time', 'time', ['notnull' => true, 'default' => $currentTimeSql]);
447
448
        $this->_sm->dropAndCreateTable($table);
449
450
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_current_time_and_date");
451
452
        self::assertSame($currentDateSql, $onlineTable->getColumn('col_date')->getDefault());
453
        self::assertSame($currentTimeSql, $onlineTable->getColumn('col_time')->getDefault());
454
455
        $comparator = new Comparator();
456
457
        $diff = $comparator->diffTable($table, $onlineTable);
458
        $this->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 457 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...
459
    }
460
461
462
    /**
463
     *
464
     * @link https://mariadb.com/kb/en/library/string-literals
465
     */
466 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...
467
    {
468
        $table = new Table("test_column_default_values_escaping");
469
        $table->addColumn('no_quotes', 'string', ['notnull' => false, 'default' => 'az']);
470
471
        $table->addColumn('backslash', 'string', ['notnull' => false, 'default' => 'a\\\z']);
472
        $table->addColumn('repeated_single_quotes', 'string', ['notnull' => false, 'default' => "a''z"]);
473
474
        $this->_sm->dropAndCreateTable($table);
475
476
        $onlineTable = $this->_sm->listTableDetails("test_column_default_values_escaping");
477
        self::assertSame("az", $onlineTable->getColumn('no_quotes')->getDefault());
478
        self::assertSame('a\\\z', $onlineTable->getColumn('backslash')->getDefault());
479
        self::assertSame("a''z", $onlineTable->getColumn('repeated_single_quotes')->getDefault());
480
481
        $comparator = new Comparator();
482
483
        $diff = $comparator->diffTable($table, $onlineTable);
484
        $this->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 483 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...
485
    }
486
487
    public function testColumnDefaultsUsingDoctrineTable(): void
488
    {
489
490
        $table = new Table("test_column_defaults_with_table");
491
        $table->addColumn('col0', 'integer', ['notnull' => false]);
492
        $table->addColumn('col1', 'integer', ['notnull' => false, 'default' => null]);
493
        $table->addColumn('col2', 'string', ['notnull' => false, 'default' => null]);
494
        $table->addColumn('col3', 'string', ['notnull' => false, 'default' => 'NULL']);
495
        $table->addColumn('col4', 'string', ['notnull' => false, 'default' => 'Hello world']);
496
        $table->addColumn('col5', 'datetime', ['notnull' => false, 'default' => null]);
497
        $table->addColumn('col6', 'decimal', ['scale' => 3, 'precision' => 6, 'notnull' => false, 'default' => -2.3]);
498
        $table->addColumn('col7', 'date', ['notnull' => false, 'default' => '2012-12-12']);
499
        $table->addColumn('col8', 'string', ['notnull' => true, 'default' => '']);
500
        $table->addColumn('col9', 'integer', ['notnull' => false, 'default' => 0]);
501
        $table->addColumn('col10', 'string', ['notnull' => false, 'default' => 'He"ll"o world']);
502
        $table->addColumn('col11', 'string', ['notnull' => false, 'default' => '2012-12-12 23:59:59']);
503
        //$table->addColumn('col12', 'string', ['notnull' => false, 'default' => 'He\\\'llo \\\world']);
504
505
        $table->addColumn('col20', 'string', ['notnull' => true, 'default' => 'CURRENT_TIMESTAMP()']);
506
        $table->addColumn('col21', 'string', ['notnull' => false, 'default' => 'CURRENT_TIMESTAMP']);
507
508
        $this->_sm->dropAndCreateTable($table);
509
510
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_with_table");
511
        self::assertNull($onlineTable->getColumn('col0')->getDefault());
512
        self::assertNull($onlineTable->getColumn('col1')->getDefault());
513
        self::assertNull($onlineTable->getColumn('col2')->getDefault());
514
        self::assertEquals('NULL', $onlineTable->getColumn('col3')->getDefault());
515
        self::assertEquals('Hello world', $onlineTable->getColumn('col4')->getDefault());
516
        self::assertNull($onlineTable->getColumn('col5')->getDefault());
517
        self::assertEquals(-2.3, $onlineTable->getColumn('col6')->getDefault());
518
        self::assertEquals('2012-12-12', $onlineTable->getColumn('col7')->getDefault());
519
        self::assertTrue($onlineTable->getColumn('col8')->getNotnull());
520
        self::assertEquals('', $onlineTable->getColumn('col8')->getDefault());
521
        self::assertSame('0', $onlineTable->getColumn('col9')->getDefault());
522
        self::assertEquals('He"ll"o world', $onlineTable->getColumn('col10')->getDefault());
523
        self::assertEquals('2012-12-12 23:59:59', $onlineTable->getColumn('col11')->getDefault());
524
        //self::assertEquals('He\\\'llo \\world', $onlineTable->getColumn('col12')->getDefault());
525
526
        // MariaDB 10.2 and MySQL 5.7 differences while storing default now() in information schema.
527
        // MariaDB will always store "current_timestamp()", mysql "CURRENT_TIMESTAMP"
528
        self::assertStringStartsWith('current_timestamp', strtolower($onlineTable->getColumn('col20')->getDefault()));
529
        self::assertStringStartsWith('current_timestamp', strtolower($onlineTable->getColumn('col21')->getDefault()));
530
531
        $comparator = new Comparator();
532
533
        $diff = $comparator->diffTable($table, $onlineTable);
534
        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 533 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...
535
    }
536
537
    /**
538
     * Ensure that an existing table with quoted (literals) default values
539
     * does not trigger a table change.
540
     */
541
    public function testColumnDefaultsDoesNotTriggerADiff(): void
542
    {
543
        $this->_conn->query('DROP TABLE IF EXISTS test_column_defaults_no_diff');
544
        $sql = "
545
            CREATE TABLE test_column_defaults_with_create (
546
                col1 VARCHAR(255) NULL DEFAULT 'O''Connor\'\"',
547
                col2 VARCHAR(255) NULL DEFAULT '''A'''
548
                );
549
        ";
550
551
        $this->_conn->query($sql);
552
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_with_create");
553
        self::assertSame("O'Connor'\"", $onlineTable->getColumn('col1')->getDefault());
554
        self::assertSame("'A'", $onlineTable->getColumn('col2')->getDefault());
555
556
        $table = new Table("test_column_defaults_no_diff");
557
        $table->addColumn('col1', 'string', ['notnull' => false, 'default' => "O'Connor'\""]);
558
        $table->addColumn('col2', 'string', ['notnull' => false, 'default' => "'A'"]);
559
560
        $comparator = new Comparator();
561
        $diff = $comparator->diffTable($table, $onlineTable);
562
        self::assertFalse($diff);
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 561 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...
563
    }
564
565
    /**
566
     * MariaDB supports expressions as default values
567
     *
568
     * @link https://mariadb.com/kb/en/library/information-schema-columns-table/
569
     */
570
    public function testColumnDefaultExpressions(): void
571
    {
572
        $this->markTestSkipped('Setting an expression as a default value is not yet supported (WIP)');
573
574
        if ($this->_sm->getDatabasePlatform() instanceof MariaDb1027Platform) {
575
576
            $table = new Table("test_column_default_expressions");
577
578
            $table->addColumn('expression', 'string', ['notnull' => false, 'default' => "concat('A','B')"]);
579
580
            $this->_sm->dropAndCreateTable($table);
581
582
            $onlineTable = $this->_sm->listTableDetails("test_column_default_expressions");
583
            self::assertSame("concat('A','B')", $onlineTable->getColumn('expression')->getDefault());
584
585
            $comparator = new Comparator();
586
587
            $diff = $comparator->diffTable($table, $onlineTable);
588
            $this->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 587 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...
589
        }
590
    }
591
592
}
593