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

testColumnDefaultValuesCurrentTimeAndDate()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 28
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\MariaDb102Platform;
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
use Doctrine\Tests\Types\MySqlPointType;
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', MySqlPointType::class);
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 MariaDb102Platform) {
162
            $this->markTestSkipped('MariaDb102Platform 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', ['default' => 'def']);
167
        $table->addColumn('def_text_null', 'text', ['notnull' => false, 'default' => 'def']);
168
        $table->addColumn('def_blob', 'blob', ['default' => 'def']);
169
        $table->addColumn('def_blob_null', 'blob', ['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 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...
197
    {
198
        $table = new Table('test_collation');
199
        $table->addOption('collate', $collation = 'latin1_swedish_ci');
200
        $table->addOption('charset', 'latin1');
201
        $table->addColumn('id', 'integer');
202
        $table->addColumn('text', 'text');
203
        $table->addColumn('foo', 'text')->setPlatformOption('collation', 'latin1_swedish_ci');
204
        $table->addColumn('bar', 'text')->setPlatformOption('collation', 'utf8_general_ci');
205
        $this->_sm->dropAndCreateTable($table);
206
207
        $columns = $this->_sm->listTableColumns('test_collation');
208
209
        self::assertArrayNotHasKey('collation', $columns['id']->getPlatformOptions());
210
        self::assertEquals('latin1_swedish_ci', $columns['text']->getPlatformOption('collation'));
211
        self::assertEquals('latin1_swedish_ci', $columns['foo']->getPlatformOption('collation'));
212
        self::assertEquals('utf8_general_ci', $columns['bar']->getPlatformOption('collation'));
213
    }
214
215
    /**
216
     * @group DBAL-843
217
     */
218
    public function testListLobTypeColumns()
219
    {
220
        $tableName = 'lob_type_columns';
221
        $table = new Table($tableName);
222
223
        $table->addColumn('col_tinytext', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_TINYTEXT));
224
        $table->addColumn('col_text', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_TEXT));
225
        $table->addColumn('col_mediumtext', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMTEXT));
226
        $table->addColumn('col_longtext', 'text');
227
228
        $table->addColumn('col_tinyblob', 'text', array('length' => MySqlPlatform::LENGTH_LIMIT_TINYBLOB));
229
        $table->addColumn('col_blob', 'blob', array('length' => MySqlPlatform::LENGTH_LIMIT_BLOB));
230
        $table->addColumn('col_mediumblob', 'blob', array('length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMBLOB));
231
        $table->addColumn('col_longblob', 'blob');
232
233
        $this->_sm->dropAndCreateTable($table);
234
235
        $platform = $this->_sm->getDatabasePlatform();
236
        $offlineColumns = $table->getColumns();
237
        $onlineColumns = $this->_sm->listTableColumns($tableName);
238
239
        self::assertSame(
240
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_tinytext']->toArray()),
241
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_tinytext']->toArray())
242
        );
243
        self::assertSame(
244
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_text']->toArray()),
245
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_text']->toArray())
246
        );
247
        self::assertSame(
248
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_mediumtext']->toArray()),
249
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_mediumtext']->toArray())
250
        );
251
        self::assertSame(
252
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_longtext']->toArray()),
253
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_longtext']->toArray())
254
        );
255
256
        self::assertSame(
257
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_tinyblob']->toArray()),
258
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_tinyblob']->toArray())
259
        );
260
        self::assertSame(
261
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_blob']->toArray()),
262
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_blob']->toArray())
263
        );
264
        self::assertSame(
265
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_mediumblob']->toArray()),
266
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_mediumblob']->toArray())
267
        );
268
        self::assertSame(
269
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_longblob']->toArray()),
270
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_longblob']->toArray())
271
        );
272
    }
273
274
    /**
275
     * @group DBAL-423
276
     */
277
    public function testDiffListGuidTableColumn()
278
    {
279
        $offlineTable = new Table('list_guid_table_column');
280
        $offlineTable->addColumn('col_guid', 'guid');
281
282
        $this->_sm->dropAndCreateTable($offlineTable);
283
284
        $onlineTable = $this->_sm->listTableDetails('list_guid_table_column');
285
286
        $comparator = new Comparator();
287
288
        self::assertFalse(
289
            $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...
290
            "No differences should be detected with the offline vs online schema."
291
        );
292
    }
293
294
    /**
295
     * @group DBAL-1082
296
     */
297 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...
298
    {
299
        $tableName = 'test_list_decimal_columns';
300
        $table = new Table($tableName);
301
302
        $table->addColumn('col', 'decimal');
303
        $table->addColumn('col_unsigned', 'decimal', array('unsigned' => true));
304
305
        $this->_sm->dropAndCreateTable($table);
306
307
        $columns = $this->_sm->listTableColumns($tableName);
308
309
        self::assertArrayHasKey('col', $columns);
310
        self::assertArrayHasKey('col_unsigned', $columns);
311
        self::assertFalse($columns['col']->getUnsigned());
312
        self::assertTrue($columns['col_unsigned']->getUnsigned());
313
    }
314
315
    /**
316
     * @group DBAL-1082
317
     */
318 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...
319
    {
320
        $tableName = 'test_list_float_columns';
321
        $table = new Table($tableName);
322
323
        $table->addColumn('col', 'float');
324
        $table->addColumn('col_unsigned', 'float', array('unsigned' => true));
325
326
        $this->_sm->dropAndCreateTable($table);
327
328
        $columns = $this->_sm->listTableColumns($tableName);
329
330
        self::assertArrayHasKey('col', $columns);
331
        self::assertArrayHasKey('col_unsigned', $columns);
332
        self::assertFalse($columns['col']->getUnsigned());
333
        self::assertTrue($columns['col_unsigned']->getUnsigned());
334
    }
335
336
337
    /**
338
     * As of MariaDB 10.2.7, nullable default values literals are always single quoted in
339
     * information_schema. Non-nullable defaults behaviour is not affected.
340
     * This test ensure accidental removal of double single encoded defaults for MariaDB >= 10.2.7.
341
     *
342
     * @link https://mariadb.com/kb/en/library/information-schema-columns-table/
343
     * @link https://dev.mysql.com/doc/refman/5.5/en/string-literals.html
344
     */
345
    public function testColumnDefaultValuesDoubleQuoted(): void
346
    {
347
        $table = new Table("test_column_default_values_double_quoted");
348
        $table->addColumn('string_nullable_quoted', 'string', ['notnull' => false, 'default' => 'NULL']);
349
        $table->addColumn('string_nullable_double_quoted', 'string', ['notnull' => false, 'default' => "'NULL'"]);
350
351
        $table->addColumn('string_notnull_quoted', 'string', ['notnull' => true, 'default' => 'NULL']);
352
        $table->addColumn('string_notnull_double_quoted', 'string', ['notnull' => true, 'default' => "\\'NULL\\'"]);
353
354
        $this->_sm->dropAndCreateTable($table);
355
356
        $onlineTable = $this->_sm->listTableDetails("test_column_default_values_double_quoted");
357
        self::assertSame('NULL', $onlineTable->getColumn('string_nullable_quoted')->getDefault());
358
359
        self::assertSame("'NULL'", $onlineTable->getColumn('string_nullable_double_quoted')->getDefault());
360
        self::assertSame("NULL", $onlineTable->getColumn('string_notnull_quoted')->getDefault());
361
        self::assertSame("\\'NULL\\'", $onlineTable->getColumn('string_notnull_double_quoted')->getDefault());
362
363
        $comparator = new Comparator();
364
365
        $diff = $comparator->diffTable($table, $onlineTable);
366
        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 365 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...
367
    }
368
369
    public function testColumnDefaultCurrentTimestamp(): void
370
    {
371
        $platform = $this->_sm->getDatabasePlatform();
372
373
        $table = new Table("test_column_defaults_current_timestamp");
374
375
        $currentTimeStampSql = $platform->getCurrentTimestampSQL();
376
377
        $table->addColumn('col_datetime', 'datetime', ['notnull' => true, 'default' => $currentTimeStampSql]);
378
        $table->addColumn('col_datetime_nullable', 'datetime', ['notnull' => false, 'default' => $currentTimeStampSql]);
379
380
        $this->_sm->dropAndCreateTable($table);
381
382
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_current_timestamp");
383
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime')->getDefault());
384
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime_nullable')->getDefault());
385
386
        $comparator = new Comparator();
387
388
        $diff = $comparator->diffTable($table, $onlineTable);
389
        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 388 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...
390
    }
391
392
    /**
393
     * Test that default value escaping does not trigger a schema change
394
     * using different escaping options.
395
     * @link https://mariadb.com/kb/en/library/string-literals
396
     * @link https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
397
     */
398
    public function testColumnDefaultValuesEscaping(): void
399
    {
400
        $table = new Table("test_column_default_values_escaping");
401
        $table->addColumn('double_backslash', 'string', ['default' => 'F\\Q\\D\\N']);
402
        $table->addColumn('triple_backslash', 'string', ['default' => 'a\\\z']);
403
        $table->addColumn('repeated_single_quotes', 'string', ['default' => "a''z"]);
404
        $table->addColumn('backslash_double_quote', 'string', ['default' => 'a\"z']);
405
        $table->addColumn('backslash_newline', 'string', ['default' => 'a\nz']);
406
407
        $this->_sm->dropAndCreateTable($table);
408
409
        $onlineTable = $this->_sm->listTableDetails("test_column_default_values_escaping");
410
        self::assertSame('F\\Q\\D\\N', $onlineTable->getColumn('double_backslash')->getDefault());
411
        self::assertSame('a\\\z', $onlineTable->getColumn('triple_backslash')->getDefault());
412
        self::assertSame("a''z", $onlineTable->getColumn('repeated_single_quotes')->getDefault());
413
        self::assertSame('a\"z', $onlineTable->getColumn('backslash_double_quote')->getDefault());
414
        self::assertSame('a\nz', $onlineTable->getColumn('backslash_newline')->getDefault());
415
416
        $comparator = new Comparator();
417
418
        $diff = $comparator->diffTable($table, $onlineTable);
419
        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 418 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...
420
    }
421
422
    public function testJsonColumnType(): void
423
    {
424
        $platform = $this->_sm->getDatabasePlatform();
425
        if (!$platform->hasNativeJsonType()) {
426
            $this->markTestSkipped("Requires native JSON type");
427
        }
428
429
        $table = new Table('test_mysql_json');
430
        $table->addColumn('col_json', 'json');
431
        $this->_sm->dropAndCreateTable($table);
432
433
        $columns = $this->_sm->listTableColumns('test_mysql_json');
434
435
        self::assertSame(TYPE::JSON, $columns['col_json']->getType()->getName());
436
    }
437
    /**
438
     * @todo split into multiple tests (most of them already made) and remove
439
     */
440
    public function testColumnDefaultsUsingDoctrineTable(): void
441
    {
442
        $table = new Table("test_column_defaults_with_table");
443
        $table->addColumn('col0', 'integer', ['notnull' => false]);
444
        $table->addColumn('col1', 'integer', ['notnull' => false, 'default' => null]);
445
        $table->addColumn('col2', 'string', ['notnull' => false, 'default' => null]);
446
        $table->addColumn('col3', 'string', ['notnull' => false, 'default' => 'NULL']);
447
        $table->addColumn('col4', 'string', ['notnull' => false, 'default' => 'Hello world']);
448
        $table->addColumn('col5', 'datetime', ['notnull' => false, 'default' => null]);
449
        $table->addColumn('col6', 'decimal', ['scale' => 3, 'precision' => 6, 'notnull' => false, 'default' => -2.3]);
450
        $table->addColumn('col7', 'date', ['notnull' => false, 'default' => '2012-12-12']);
451
        $table->addColumn('col8', 'string', ['notnull' => true, 'default' => '']);
452
        $table->addColumn('col9', 'integer', ['notnull' => false, 'default' => 0]);
453
        $table->addColumn('col10', 'string', ['notnull' => false, 'default' => 'He"ll"o world']);
454
        $table->addColumn('col11', 'string', ['notnull' => false, 'default' => '2012-12-12 23:59:59']);
455
        //$table->addColumn('col12', 'string', ['notnull' => false, 'default' => 'He\\\'llo \\\world']);
456
457
        $table->addColumn('col20', 'string', ['notnull' => true, 'default' => 'CURRENT_TIMESTAMP()']);
458
        $table->addColumn('col21', 'string', ['notnull' => false, 'default' => 'CURRENT_TIMESTAMP']);
459
460
        $this->_sm->dropAndCreateTable($table);
461
462
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_with_table");
463
        self::assertNull($onlineTable->getColumn('col0')->getDefault());
464
        self::assertNull($onlineTable->getColumn('col1')->getDefault());
465
        self::assertNull($onlineTable->getColumn('col2')->getDefault());
466
        self::assertEquals('NULL', $onlineTable->getColumn('col3')->getDefault());
467
        self::assertEquals('Hello world', $onlineTable->getColumn('col4')->getDefault());
468
        self::assertNull($onlineTable->getColumn('col5')->getDefault());
469
        self::assertEquals(-2.3, $onlineTable->getColumn('col6')->getDefault());
470
        self::assertEquals('2012-12-12', $onlineTable->getColumn('col7')->getDefault());
471
        self::assertTrue($onlineTable->getColumn('col8')->getNotnull());
472
        self::assertEquals('', $onlineTable->getColumn('col8')->getDefault());
473
        self::assertSame('0', $onlineTable->getColumn('col9')->getDefault());
474
        self::assertEquals('He"ll"o world', $onlineTable->getColumn('col10')->getDefault());
475
        self::assertEquals('2012-12-12 23:59:59', $onlineTable->getColumn('col11')->getDefault());
476
        //self::assertEquals('He\\\'llo \\world', $onlineTable->getColumn('col12')->getDefault());
477
478
        // MariaDB 10.2 and MySQL 5.7 differences while storing default now() in information schema.
479
        // MariaDB will always store "current_timestamp()", mysql "CURRENT_TIMESTAMP"
480
        self::assertStringStartsWith('current_timestamp', strtolower($onlineTable->getColumn('col20')->getDefault()));
481
        self::assertStringStartsWith('current_timestamp', strtolower($onlineTable->getColumn('col21')->getDefault()));
482
483
        $comparator = new Comparator();
484
485
        $diff = $comparator->diffTable($table, $onlineTable);
486
        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 485 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...
487
    }
488
489
    /**
490
     * Ensure that a table created outside doctrine and containing
491
     * quoted default values does not trigger a table diff change. I
492
     * Note: MariaDb 10.2 silently change "\'" into "''" when storing in
493
     * information schema, MariaDb102Platform should normalize the table details.
494
     */
495
    public function testExistingTableWithQuotedDefaultsDoesNotTriggerChange(): void
496
    {
497
        $this->_conn->query('DROP TABLE IF EXISTS test_column_defaults_with_create');
498
        $sql = "
499
            CREATE TABLE test_column_defaults_with_create (
500
                col1 VARCHAR(255) NULL DEFAULT 'O''Connor\'\"',
501
                col2 VARCHAR(255) NULL DEFAULT '''A'''
502
                );
503
        ";
504
        $this->_conn->query($sql);
505
506
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_with_create");
507
        self::assertSame("O'Connor'\"", $onlineTable->getColumn('col1')->getDefault());
508
        self::assertSame("'A'", $onlineTable->getColumn('col2')->getDefault());
509
510
        $table = new Table("test_column_defaults_no_diff");
511
        $table->addColumn('col1', 'string', ['notnull' => false, 'default' => "O'Connor'\""]);
512
        $table->addColumn('col2', 'string', ['notnull' => false, 'default' => "'A'"]);
513
514
        $comparator = new Comparator();
515
        $diff = $comparator->diffTable($table, $onlineTable);
516
        self::assertFalse($diff);
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 515 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...
517
    }
518
519
    /**
520
     * Since MariaDB 10.2.1, Blob and text columns can have a default value
521
     *
522
     * @link https://mariadb.com/kb/en/library/blob-and-text-data-types
523
     */
524
    public function testDoesPropagateDefaultValuesForBlobTextAndJson(): void
525
    {
526
        if (!$this->_sm->getDatabasePlatform() instanceof MariaDb102Platform) {
527
            $this->markTestSkipped('Only relevant for MariaDb102Platform.');
528
        }
529
530
        $table = new Table("text_blob_default_value");
531
532
        $json = json_encode(['prop1' => "O'Connor", 'prop2' => 10]);
533
534
        $table->addColumn('def_text', 'text', ['default' => "O'Connor"]);
535
        $table->addColumn('def_text_null', 'text', ['notnull' => false, 'default' => 'def']);
536
        $table->addColumn('def_blob', 'blob', ['default' => 'def']);
537
        $table->addColumn('def_json', 'json', ['default' => $json]);
538
539
        $this->_sm->dropAndCreateTable($table);
540
541
        $onlineTable = $this->_sm->listTableDetails("text_blob_default_value");
542
543
        self::assertSame("O'Connor", $onlineTable->getColumn('def_text')->getDefault());
544
        self::assertSame('def', $onlineTable->getColumn('def_text_null')->getDefault());
545
        self::assertSame('def', $onlineTable->getColumn('def_blob')->getDefault());
546
        self::assertSame($json, $onlineTable->getColumn('def_json')->getDefault());
547
548
        $comparator = new Comparator();
549
550
        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...
551
    }
552
553
    /**
554
     * Note: MySQL (as of 5.7.19) does not support default value
555
     * for DATE and TIME fields while MariaDB 10.2+ does
556
     */
557
    public function testColumnDefaultValuesCurrentTimeAndDate(): void
558
    {
559
        if (!$this->_sm->getDatabasePlatform() instanceof MariaDb102Platform) {
560
            $this->markTestSkipped('Only relevant for MariaDb102Platform.');
561
        }
562
563
        $platform = $this->_sm->getDatabasePlatform();
564
565
        $table = new Table("test_column_defaults_current_time_and_date");
566
567
        $currentTimeSql = $platform->getCurrentTimeSQL();
568
        $currentDateSql = $platform->getCurrentDateSQL();
569
570
        $table->addColumn('col_date', 'date', ['notnull' => true, 'default' => $currentDateSql]);
571
        $table->addColumn('col_time', 'time', ['notnull' => true, 'default' => $currentTimeSql]);
572
573
        $this->_sm->dropAndCreateTable($table);
574
575
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_current_time_and_date");
576
577
        self::assertSame($currentDateSql, $onlineTable->getColumn('col_date')->getDefault());
578
        self::assertSame($currentTimeSql, $onlineTable->getColumn('col_time')->getDefault());
579
580
        $comparator = new Comparator();
581
582
        $diff = $comparator->diffTable($table, $onlineTable);
583
        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 582 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...
584
    }
585
586
    /**
587
     * MariaDB supports expressions as default values
588
     *
589
     * @todo remove or implement !!!
590
     *
591
     * @link https://mariadb.com/kb/en/library/information-schema-columns-table/
592
     */
593
    public function testColumnDefaultExpressions(): void
594
    {
595
        $this->markTestSkipped('Setting an expression as a default value is not yet supported (WIP)');
596
597
        if (!$this->_sm->getDatabasePlatform() instanceof MariaDb102Platform) {
598
            $this->markTestSkipped('Only relevant for MariaDb102Platform.');
599
        }
600
601
        $table = new Table("test_column_default_expressions");
602
603
        $table->addColumn('expression', 'string', ['notnull' => false, 'default' => "concat('A','B')"]);
604
605
        $this->_sm->dropAndCreateTable($table);
606
607
        $onlineTable = $this->_sm->listTableDetails("test_column_default_expressions");
608
        self::assertSame("concat('A','B')", $onlineTable->getColumn('expression')->getDefault());
609
610
        $comparator = new Comparator();
611
612
        $diff = $comparator->diffTable($table, $onlineTable);
613
        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 612 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...
614
    }
615
616
}
617