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

testColumnDefaultValuesCurrentTimeAndDate()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 31
rs 8.8571
cc 2
eloc 19
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\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 MariaDb1027Platform) {
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
     * As of MariaDB 10.2.7, nullable default values literals are always single quoted in
338
     * information_schema. Non-nullable defaults behaviour is not affected.
339
     * This test ensure accidental removal of double single encoded defaults for MariaDB >= 10.2.7.
340
     *
341
     * @link https://mariadb.com/kb/en/library/information-schema-columns-table/
342
     * @link https://dev.mysql.com/doc/refman/5.5/en/string-literals.html
343
     */
344
    public function testColumnDefaultValuesDoubleQuoted() : void
345
    {
346
        $table = new Table("test_column_default_values_double_quoted");
347
        $table->addColumn('string_nullable_quoted', 'string', ['notnull' => false, 'default' => 'NULL']);
348
        $table->addColumn('string_nullable_double_quoted', 'string', ['notnull' => false, 'default' => "'NULL'"]);
349
350
        $table->addColumn('string_notnull_quoted', 'string', ['notnull' => true, 'default' => 'NULL']);
351
        $table->addColumn('string_notnull_double_quoted', 'string', ['notnull' => true, 'default' => "\\'NULL\\'"]);
352
353
        $this->_sm->dropAndCreateTable($table);
354
355
        $onlineTable = $this->_sm->listTableDetails("test_column_default_values_double_quoted");
356
        self::assertSame('NULL', $onlineTable->getColumn('string_nullable_quoted')->getDefault());
357
358
        self::assertSame("'NULL'", $onlineTable->getColumn('string_nullable_double_quoted')->getDefault());
359
        self::assertSame("NULL", $onlineTable->getColumn('string_notnull_quoted')->getDefault());
360
        self::assertSame("\\'NULL\\'", $onlineTable->getColumn('string_notnull_double_quoted')->getDefault());
361
362
        $comparator = new Comparator();
363
364
        $diff = $comparator->diffTable($table, $onlineTable);
365
        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 364 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...
366
    }
367
368
    /**
369
     * @link https://mariadb.com/kb/en/library/string-literals
370
     * @link https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
371
     */
372
    public function testColumnEscapingDefaultValuesDoesNotTriggerSchemaChange() : void
373
    {
374
        $table = new Table("test_column_default_values_escaping");
375
        $table->addColumn('single_backslash', 'string', ['default' => 'F\Q\D\N']);
376
        $table->addColumn('double_backslash', 'string', ['default' => 'F\\Q\\D\\N']);
377
        $table->addColumn('triple_backslash', 'string', ['default' => 'a\\\z']);
378
        $table->addColumn('repeated_single_quotes', 'string', ['default' => "a''z"]);
379
        $table->addColumn('backslash_double_quote', 'string', ['default' => 'a\"z']);
380
        $table->addColumn('backslash_newline', 'string', ['default' => 'a\nz']);
381
382
        $this->_sm->dropAndCreateTable($table);
383
384
        $onlineTable = $this->_sm->listTableDetails("test_column_default_values_escaping");
385
        self::assertSame('F\Q\D\N', $onlineTable->getColumn('single_backslash')->getDefault());
386
        self::assertSame('F\\Q\\D\\N', $onlineTable->getColumn('double_backslash')->getDefault());
387
        self::assertSame('a\\\z', $onlineTable->getColumn('triple_backslash')->getDefault());
388
        self::assertSame("a''z", $onlineTable->getColumn('repeated_single_quotes')->getDefault());
389
        self::assertSame('a\"z', $onlineTable->getColumn('backslash_double_quote')->getDefault());
390
        self::assertSame('a\nz', $onlineTable->getColumn('backslash_newline')->getDefault());
391
392
        $comparator = new Comparator();
393
394
        $diff = $comparator->diffTable($table, $onlineTable);
395
        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 394 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...
396
    }
397
398
    public function testJsonColumnType() : void
399
    {
400
        $platform = $this->_sm->getDatabasePlatform();
401
        if (!$platform->hasNativeJsonType()) {
402
            $this->markTestSkipped("Requires native JSON type");
403
        }
404
405
        $table = new Table('test_mysql_json');
406
        $table->addColumn('col_json', 'json');
407
        $this->_sm->dropAndCreateTable($table);
408
409
        $columns = $this->_sm->listTableColumns('test_mysql_json');
410
411
        self::assertSame(TYPE::JSON, $columns['col_json']->getType()->getName());
412
    }
413
414
    /**
415
     * Ensure that a table created outside doctrine and containing
416
     * quoted default values does not trigger a table diff change. I
417
     * Note: MariaDb 10.2 silently change "\'" into "''" when storing in
418
     * information schema, MariaDb102Platform should normalize the table details.
419
     */
420
    public function testExistingTableWithQuotedDefaultsDoesNotTriggerChange() : void
421
    {
422
        $this->_conn->query('DROP TABLE IF EXISTS test_column_defaults_with_create');
423
        $sql = "
424
            CREATE TABLE test_column_defaults_with_create (
425
                col1 VARCHAR(255) NULL DEFAULT 'O''Connor\'\"',              
426
                col2 VARCHAR(255) NOT NULL DEFAULT 'O''Connor\'\"'                                
427
                );
428
        ";
429
        $this->_conn->query($sql);
430
431
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_with_create");
432
        self::assertSame("O'Connor'\"", $onlineTable->getColumn('col1')->getDefault());
433
        self::assertSame("O'Connor'\"", $onlineTable->getColumn('col2')->getDefault());
434
435
        $table = new Table("test_column_defaults_no_diff");
436
        $table->addColumn('col1', 'string', ['notnull' => false, 'default' => "O'Connor'\""]);
437
        $table->addColumn('col2', 'string', ['notnull' => true, 'default' => "O'Connor'\""]);
438
439
        $comparator = new Comparator();
440
        $diff = $comparator->diffTable($table, $onlineTable);
441
        self::assertFalse($diff);
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 440 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...
442
    }
443
444
    public function testColumnDefaultCurrentTimestamp() : void
445
    {
446
        $platform = $this->_sm->getDatabasePlatform();
447
448
        $table = new Table("test_column_defaults_current_timestamp");
449
450
        $currentTimeStampSql = $platform->getCurrentTimestampSQL();
451
452
        $table->addColumn('col_datetime', 'datetime', ['notnull' => true, 'default' => $currentTimeStampSql]);
453
        $table->addColumn('col_datetime_nullable', 'datetime', ['default' => $currentTimeStampSql]);
454
455
        $this->_sm->dropAndCreateTable($table);
456
457
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_current_timestamp");
458
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime')->getDefault());
459
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime_nullable')->getDefault());
460
461
        $comparator = new Comparator();
462
463
        $diff = $comparator->diffTable($table, $onlineTable);
464
        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 463 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...
465
    }
466
467
    public function testColumnDefaultsAreValid() {
468
469
        $table = new Table("test_column_defaults_are_valid");
470
471
        $currentTimeStampSql = $this->_sm->getDatabasePlatform()->getCurrentTimestampSQL();
472
        $table->addColumn('col_datetime', 'datetime', ['default' => $currentTimeStampSql]);
473
        $table->addColumn('col_datetime_null', 'datetime', ['notnull' => false, 'default' => null]);
474
        $table->addColumn('col_int', 'integer', ['default' => 1]);
475
        $table->addColumn('col_neg_int', 'integer', ['default' => -1]);
476
        $table->addColumn('col_string', 'string', ['default' => 'A']);
477
        $table->addColumn('col_decimal', 'decimal', ['scale' => 3, 'precision' => 6, 'default' => -2.3]);
478
        $table->addColumn('col_date', 'date', ['default' => '2012-12-12']);
479
480
        $this->_sm->dropAndCreateTable($table);
481
482
        $this->_conn->executeUpdate(
483
            "INSERT INTO test_column_defaults_are_valid () VALUES()"
484
        );
485
486
        $row = $this->_conn->fetchAssoc(
487
            'SELECT *, DATEDIFF(CURRENT_TIMESTAMP(), col_datetime) as diff_seconds FROM test_column_defaults_are_valid'
488
        );
489
490
        self::assertInstanceOf(\DateTime::class, \DateTime::createFromFormat('Y-m-d H:i:s', $row['col_datetime']));
491
        self::assertNull($row['col_datetime_null']);
492
        self::assertSame('2012-12-12', $row['col_date']);
493
        self::assertSame('A', $row['col_string']);
494
        self::assertEquals(1, $row['col_int']);
495
        self::assertEquals(-1, $row['col_neg_int']);
496
        self::assertEquals('-2.300', $row['col_decimal']);
497
        self::assertLessThan(5, $row['diff_seconds']);
498
    }
499
500
    /**
501
     * MariaDB 10.2+ does support CURRENT_TIME and CURRENT_DATE as
502
     * column default values for time and date columns.
503
     * (Not supported on Mysql as of 5.7.19)
504
     *
505
     * Note that MariaDB 10.2+, when storing default in information_schema,
506
     * silently change CURRENT_TIMESTAMP as 'current_timestamp()',
507
     * CURRENT_TIME as 'currtime()' and CURRENT_DATE as 'currdate()'.
508
     * This test also ensure proper aliasing to not trigger a table diff.
509
     */
510
    public function testColumnDefaultValuesCurrentTimeAndDate() : void
511
    {
512
        if (!$this->_sm->getDatabasePlatform() instanceof MariaDb1027Platform) {
513
            $this->markTestSkipped('Only relevant for MariaDb102Platform.');
514
        }
515
516
        $platform = $this->_sm->getDatabasePlatform();
517
518
        $table = new Table("test_column_defaults_current_time_and_date");
519
520
        $currentTimestampSql = $platform->getCurrentTimestampSQL();
521
        $currentTimeSql = $platform->getCurrentTimeSQL();
522
        $currentDateSql = $platform->getCurrentDateSQL();
523
524
        $table->addColumn('col_datetime', 'datetime', ['default' => $currentTimestampSql]);
525
        $table->addColumn('col_date', 'date', ['default' => $currentDateSql]);
526
        $table->addColumn('col_time', 'time', ['default' => $currentTimeSql]);
527
528
        $this->_sm->dropAndCreateTable($table);
529
530
        $onlineTable = $this->_sm->listTableDetails("test_column_defaults_current_time_and_date");
531
532
        self::assertSame($currentTimestampSql, $onlineTable->getColumn('col_datetime')->getDefault());
533
        self::assertSame($currentDateSql, $onlineTable->getColumn('col_date')->getDefault());
534
        self::assertSame($currentTimeSql, $onlineTable->getColumn('col_time')->getDefault());
535
536
        $comparator = new Comparator();
537
538
        $diff = $comparator->diffTable($table, $onlineTable);
539
        self::assertFalse($diff, "Tables should be identical with column defauts time and date.");
0 ignored issues
show
Bug introduced by
It seems like $diff defined by $comparator->diffTable($table, $onlineTable) on line 538 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...
540
    }
541
542
    /**
543
     * Since MariaDB 10.2.1, Blob and text columns can have a default value
544
     *
545
     * @link https://mariadb.com/kb/en/library/blob-and-text-data-types
546
     */
547
    public function testDoesPropagateDefaultValuesForBlobTextAndJson() : void
548
    {
549
        if (!$this->_sm->getDatabasePlatform() instanceof MariaDb1027Platform) {
550
            $this->markTestSkipped('Only relevant for MariaDb102Platform.');
551
        }
552
553
        $table = new Table("text_blob_default_value");
554
555
        $json = json_encode(['prop1' => "O'Connor", 'prop2' => 10]);
556
557
        $table->addColumn('def_text', 'text', ['default' => "O'Connor"]);
558
        $table->addColumn('def_text_null', 'text', ['notnull' => false, 'default' => 'def']);
559
        $table->addColumn('def_blob', 'blob', ['default' => '\F\Q\D\N']);
560
        $table->addColumn('def_json', 'json', ['default' => $json]);
561
562
        $this->_sm->dropAndCreateTable($table);
563
564
        $onlineTable = $this->_sm->listTableDetails("text_blob_default_value");
565
566
        self::assertSame("O'Connor", $onlineTable->getColumn('def_text')->getDefault());
567
        self::assertSame('def', $onlineTable->getColumn('def_text_null')->getDefault());
568
        self::assertSame('\F\Q\D\N', $onlineTable->getColumn('def_blob')->getDefault());
569
        self::assertSame($json, $onlineTable->getColumn('def_json')->getDefault());
570
571
        $comparator = new Comparator();
572
573
        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...
574
    }
575
}
576