Passed
Push — phpstan-tests ( 6a2b78...974220 )
by Michael
61:35 queued 23s
created

testEnsureTableOptionsAreReflectedInMetadata()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 22
dl 0
loc 27
rs 9.568
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\DBAL\Functional\Schema;
6
7
use DateTime;
8
use Doctrine\DBAL\Platforms\MariaDb1027Platform;
9
use Doctrine\DBAL\Platforms\MySqlPlatform;
10
use Doctrine\DBAL\Schema\Comparator;
11
use Doctrine\DBAL\Schema\Schema;
12
use Doctrine\DBAL\Schema\Table;
13
use Doctrine\DBAL\Types\Type;
14
use Doctrine\DBAL\Types\Types;
15
use Doctrine\Tests\Types\MySqlPointType;
16
use function implode;
17
use function sprintf;
18
19
class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
20
{
21
    protected function setUp() : void
22
    {
23
        parent::setUp();
24
25
        if (Type::hasType('point')) {
26
            return;
27
        }
28
29
        $this->resetSharedConn();
30
31
        Type::addType('point', MySqlPointType::class);
32
    }
33
34
    public function testSwitchPrimaryKeyColumns()
35
    {
36
        $tableOld = new Table('switch_primary_key_columns');
37
        $tableOld->addColumn('foo_id', 'integer');
38
        $tableOld->addColumn('bar_id', 'integer');
39
40
        $this->schemaManager->createTable($tableOld);
41
        $tableFetched = $this->schemaManager->listTableDetails('switch_primary_key_columns');
42
        $tableNew     = clone $tableFetched;
43
        $tableNew->setPrimaryKey(['bar_id', 'foo_id']);
44
45
        $comparator = new Comparator();
46
        $this->schemaManager->alterTable($comparator->diffTable($tableFetched, $tableNew));
47
48
        $table      = $this->schemaManager->listTableDetails('switch_primary_key_columns');
49
        $primaryKey = $table->getPrimaryKeyColumns();
50
51
        self::assertCount(2, $primaryKey);
52
        self::assertContains('bar_id', $primaryKey);
53
        self::assertContains('foo_id', $primaryKey);
54
    }
55
56
    public function testDiffTableBug()
57
    {
58
        $schema = new Schema();
59
        $table  = $schema->createTable('diffbug_routing_translations');
60
        $table->addColumn('id', 'integer');
61
        $table->addColumn('route', 'string');
62
        $table->addColumn('locale', 'string');
63
        $table->addColumn('attribute', 'string');
64
        $table->addColumn('localized_value', 'string');
65
        $table->addColumn('original_value', 'string');
66
        $table->setPrimaryKey(['id']);
67
        $table->addUniqueIndex(['route', 'locale', 'attribute']);
68
        $table->addIndex(['localized_value']); // this is much more selective than the unique index
69
70
        $this->schemaManager->createTable($table);
71
        $tableFetched = $this->schemaManager->listTableDetails('diffbug_routing_translations');
72
73
        $comparator = new Comparator();
74
        $diff       = $comparator->diffTable($tableFetched, $table);
75
76
        self::assertFalse($diff, 'no changes expected.');
77
    }
78
79
    public function testFulltextIndex()
80
    {
81
        $table = new Table('fulltext_index');
82
        $table->addColumn('text', 'text');
83
        $table->addIndex(['text'], 'f_index');
84
        $table->addOption('engine', 'MyISAM');
85
86
        $index = $table->getIndex('f_index');
87
        $index->addFlag('fulltext');
88
89
        $this->schemaManager->dropAndCreateTable($table);
90
91
        $indexes = $this->schemaManager->listTableIndexes('fulltext_index');
92
        self::assertArrayHasKey('f_index', $indexes);
93
        self::assertTrue($indexes['f_index']->hasFlag('fulltext'));
94
    }
95
96
    public function testSpatialIndex()
97
    {
98
        $table = new Table('spatial_index');
99
        $table->addColumn('point', 'point');
100
        $table->addIndex(['point'], 's_index');
101
        $table->addOption('engine', 'MyISAM');
102
103
        $index = $table->getIndex('s_index');
104
        $index->addFlag('spatial');
105
106
        $this->schemaManager->dropAndCreateTable($table);
107
108
        $indexes = $this->schemaManager->listTableIndexes('spatial_index');
109
        self::assertArrayHasKey('s_index', $indexes);
110
        self::assertTrue($indexes['s_index']->hasFlag('spatial'));
111
    }
112
113
    public function testIndexWithLength() : void
114
    {
115
        $table = new Table('index_length');
116
        $table->addColumn('text', 'string', ['length' => 255]);
117
        $table->addIndex(['text'], 'text_index', [], ['lengths' => [128]]);
118
119
        $this->schemaManager->dropAndCreateTable($table);
120
121
        $indexes = $this->schemaManager->listTableIndexes('index_length');
122
        self::assertArrayHasKey('text_index', $indexes);
123
        self::assertSame([128], $indexes['text_index']->getOption('lengths'));
124
    }
125
126
    /**
127
     * @group DBAL-400
128
     */
129
    public function testAlterTableAddPrimaryKey()
130
    {
131
        $table = new Table('alter_table_add_pk');
132
        $table->addColumn('id', 'integer');
133
        $table->addColumn('foo', 'integer');
134
        $table->addIndex(['id'], 'idx_id');
135
136
        $this->schemaManager->createTable($table);
137
138
        $comparator = new Comparator();
139
        $diffTable  = clone $table;
140
141
        $diffTable->dropIndex('idx_id');
142
        $diffTable->setPrimaryKey(['id']);
143
144
        $this->schemaManager->alterTable($comparator->diffTable($table, $diffTable));
0 ignored issues
show
Bug introduced by
It seems like $comparator->diffTable($table, $diffTable) can also be of type false; however, parameter $tableDiff of Doctrine\DBAL\Schema\Abs...maManager::alterTable() does only seem to accept Doctrine\DBAL\Schema\TableDiff, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

144
        $this->schemaManager->alterTable(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable));
Loading history...
145
146
        $table = $this->schemaManager->listTableDetails('alter_table_add_pk');
147
148
        self::assertFalse($table->hasIndex('idx_id'));
149
        self::assertTrue($table->hasPrimaryKey());
150
    }
151
152
    /**
153
     * @group DBAL-464
154
     */
155
    public function testDropPrimaryKeyWithAutoincrementColumn()
156
    {
157
        $table = new Table('drop_primary_key');
158
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
159
        $table->addColumn('foo', 'integer');
160
        $table->setPrimaryKey(['id', 'foo']);
161
162
        $this->schemaManager->dropAndCreateTable($table);
163
164
        $diffTable = clone $table;
165
166
        $diffTable->dropPrimaryKey();
167
168
        $comparator = new Comparator();
169
170
        $this->schemaManager->alterTable($comparator->diffTable($table, $diffTable));
0 ignored issues
show
Bug introduced by
It seems like $comparator->diffTable($table, $diffTable) can also be of type false; however, parameter $tableDiff of Doctrine\DBAL\Schema\Abs...maManager::alterTable() does only seem to accept Doctrine\DBAL\Schema\TableDiff, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
        $this->schemaManager->alterTable(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable));
Loading history...
171
172
        $table = $this->schemaManager->listTableDetails('drop_primary_key');
173
174
        self::assertFalse($table->hasPrimaryKey());
175
        self::assertFalse($table->getColumn('id')->getAutoincrement());
176
    }
177
178
    /**
179
     * @group DBAL-789
180
     */
181
    public function testDoesNotPropagateDefaultValuesForUnsupportedColumnTypes()
182
    {
183
        if ($this->schemaManager->getDatabasePlatform() instanceof MariaDb1027Platform) {
184
            $this->markTestSkipped(
185
                'MariaDb102Platform supports default values for BLOB and TEXT columns and will propagate values'
186
            );
187
        }
188
189
        $table = new Table('text_blob_default_value');
190
        $table->addColumn('def_text', 'text', ['default' => 'def']);
191
        $table->addColumn('def_text_null', 'text', ['notnull' => false, 'default' => 'def']);
192
        $table->addColumn('def_blob', 'blob', ['default' => 'def']);
193
        $table->addColumn('def_blob_null', 'blob', ['notnull' => false, 'default' => 'def']);
194
195
        $this->schemaManager->dropAndCreateTable($table);
196
197
        $onlineTable = $this->schemaManager->listTableDetails('text_blob_default_value');
198
199
        self::assertNull($onlineTable->getColumn('def_text')->getDefault());
200
        self::assertNull($onlineTable->getColumn('def_text_null')->getDefault());
201
        self::assertFalse($onlineTable->getColumn('def_text_null')->getNotnull());
202
        self::assertNull($onlineTable->getColumn('def_blob')->getDefault());
203
        self::assertNull($onlineTable->getColumn('def_blob_null')->getDefault());
204
        self::assertFalse($onlineTable->getColumn('def_blob_null')->getNotnull());
205
206
        $comparator = new Comparator();
207
208
        $this->schemaManager->alterTable($comparator->diffTable($table, $onlineTable));
209
210
        $onlineTable = $this->schemaManager->listTableDetails('text_blob_default_value');
211
212
        self::assertNull($onlineTable->getColumn('def_text')->getDefault());
213
        self::assertNull($onlineTable->getColumn('def_text_null')->getDefault());
214
        self::assertFalse($onlineTable->getColumn('def_text_null')->getNotnull());
215
        self::assertNull($onlineTable->getColumn('def_blob')->getDefault());
216
        self::assertNull($onlineTable->getColumn('def_blob_null')->getDefault());
217
        self::assertFalse($onlineTable->getColumn('def_blob_null')->getNotnull());
218
    }
219
220
    public function testColumnCharset()
221
    {
222
        $table = new Table('test_column_charset');
223
        $table->addColumn('id', 'integer');
224
        $table->addColumn('no_charset', 'text');
225
        $table->addColumn('foo', 'text')->setPlatformOption('charset', 'ascii');
226
        $table->addColumn('bar', 'text')->setPlatformOption('charset', 'latin1');
227
        $this->schemaManager->dropAndCreateTable($table);
228
229
        $columns = $this->schemaManager->listTableColumns('test_column_charset');
230
231
        self::assertFalse($columns['id']->hasPlatformOption('charset'));
232
        self::assertEquals('utf8', $columns['no_charset']->getPlatformOption('charset'));
233
        self::assertEquals('ascii', $columns['foo']->getPlatformOption('charset'));
234
        self::assertEquals('latin1', $columns['bar']->getPlatformOption('charset'));
235
    }
236
237
    public function testAlterColumnCharset()
238
    {
239
        $tableName = 'test_alter_column_charset';
240
241
        $table = new Table($tableName);
242
        $table->addColumn('col_text', 'text')->setPlatformOption('charset', 'utf8');
243
244
        $this->schemaManager->dropAndCreateTable($table);
245
246
        $diffTable = clone $table;
247
        $diffTable->getColumn('col_text')->setPlatformOption('charset', 'ascii');
248
249
        $comparator = new Comparator();
250
251
        $this->schemaManager->alterTable($comparator->diffTable($table, $diffTable));
0 ignored issues
show
Bug introduced by
It seems like $comparator->diffTable($table, $diffTable) can also be of type false; however, parameter $tableDiff of Doctrine\DBAL\Schema\Abs...maManager::alterTable() does only seem to accept Doctrine\DBAL\Schema\TableDiff, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

251
        $this->schemaManager->alterTable(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable));
Loading history...
252
253
        $table = $this->schemaManager->listTableDetails($tableName);
254
255
        self::assertEquals('ascii', $table->getColumn('col_text')->getPlatformOption('charset'));
256
    }
257
258
    public function testColumnCharsetChange()
259
    {
260
        $table = new Table('test_column_charset_change');
261
        $table->addColumn('col_string', 'string')->setLength(100)->setNotnull(true)->setPlatformOption('charset', 'utf8');
262
263
        $diffTable = clone $table;
264
        $diffTable->getColumn('col_string')->setPlatformOption('charset', 'ascii');
265
266
        $fromSchema = new Schema([$table]);
267
        $toSchema   = new Schema([$diffTable]);
268
269
        $diff = $fromSchema->getMigrateToSql($toSchema, $this->connection->getDatabasePlatform());
270
        self::assertContains('ALTER TABLE test_column_charset_change CHANGE col_string col_string VARCHAR(100) CHARACTER SET ascii NOT NULL', $diff);
271
    }
272
273
    public function testColumnCollation()
274
    {
275
        $table                                  = new Table('test_collation');
276
        $table->addOption('collate', $collation = 'latin1_swedish_ci');
277
        $table->addOption('charset', 'latin1');
278
        $table->addColumn('id', 'integer');
279
        $table->addColumn('text', 'text');
280
        $table->addColumn('foo', 'text')->setPlatformOption('collation', 'latin1_swedish_ci');
281
        $table->addColumn('bar', 'text')->setPlatformOption('collation', 'utf8_general_ci');
282
        $this->schemaManager->dropAndCreateTable($table);
283
284
        $columns = $this->schemaManager->listTableColumns('test_collation');
285
286
        self::assertArrayNotHasKey('collation', $columns['id']->getPlatformOptions());
287
        self::assertEquals('latin1_swedish_ci', $columns['text']->getPlatformOption('collation'));
288
        self::assertEquals('latin1_swedish_ci', $columns['foo']->getPlatformOption('collation'));
289
        self::assertEquals('utf8_general_ci', $columns['bar']->getPlatformOption('collation'));
290
    }
291
292
    /**
293
     * @group DBAL-843
294
     */
295
    public function testListLobTypeColumns()
296
    {
297
        $tableName = 'lob_type_columns';
298
        $table     = new Table($tableName);
299
300
        $table->addColumn('col_tinytext', 'text', ['length' => MySqlPlatform::LENGTH_LIMIT_TINYTEXT]);
301
        $table->addColumn('col_text', 'text', ['length' => MySqlPlatform::LENGTH_LIMIT_TEXT]);
302
        $table->addColumn('col_mediumtext', 'text', ['length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMTEXT]);
303
        $table->addColumn('col_longtext', 'text');
304
305
        $table->addColumn('col_tinyblob', 'text', ['length' => MySqlPlatform::LENGTH_LIMIT_TINYBLOB]);
306
        $table->addColumn('col_blob', 'blob', ['length' => MySqlPlatform::LENGTH_LIMIT_BLOB]);
307
        $table->addColumn('col_mediumblob', 'blob', ['length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMBLOB]);
308
        $table->addColumn('col_longblob', 'blob');
309
310
        $this->schemaManager->dropAndCreateTable($table);
311
312
        $platform       = $this->schemaManager->getDatabasePlatform();
313
        $offlineColumns = $table->getColumns();
314
        $onlineColumns  = $this->schemaManager->listTableColumns($tableName);
315
316
        self::assertSame(
317
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_tinytext']->toArray()),
318
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_tinytext']->toArray())
319
        );
320
        self::assertSame(
321
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_text']->toArray()),
322
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_text']->toArray())
323
        );
324
        self::assertSame(
325
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_mediumtext']->toArray()),
326
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_mediumtext']->toArray())
327
        );
328
        self::assertSame(
329
            $platform->getClobTypeDeclarationSQL($offlineColumns['col_longtext']->toArray()),
330
            $platform->getClobTypeDeclarationSQL($onlineColumns['col_longtext']->toArray())
331
        );
332
333
        self::assertSame(
334
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_tinyblob']->toArray()),
335
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_tinyblob']->toArray())
336
        );
337
        self::assertSame(
338
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_blob']->toArray()),
339
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_blob']->toArray())
340
        );
341
        self::assertSame(
342
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_mediumblob']->toArray()),
343
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_mediumblob']->toArray())
344
        );
345
        self::assertSame(
346
            $platform->getBlobTypeDeclarationSQL($offlineColumns['col_longblob']->toArray()),
347
            $platform->getBlobTypeDeclarationSQL($onlineColumns['col_longblob']->toArray())
348
        );
349
    }
350
351
    /**
352
     * @group DBAL-423
353
     */
354
    public function testDiffListGuidTableColumn()
355
    {
356
        $offlineTable = new Table('list_guid_table_column');
357
        $offlineTable->addColumn('col_guid', 'guid');
358
359
        $this->schemaManager->dropAndCreateTable($offlineTable);
360
361
        $onlineTable = $this->schemaManager->listTableDetails('list_guid_table_column');
362
363
        $comparator = new Comparator();
364
365
        self::assertFalse(
366
            $comparator->diffTable($offlineTable, $onlineTable),
367
            'No differences should be detected with the offline vs online schema.'
368
        );
369
    }
370
371
    /**
372
     * @group DBAL-1082
373
     */
374
    public function testListDecimalTypeColumns()
375
    {
376
        $tableName = 'test_list_decimal_columns';
377
        $table     = new Table($tableName);
378
379
        $table->addColumn('col', 'decimal');
380
        $table->addColumn('col_unsigned', 'decimal', ['unsigned' => true]);
381
382
        $this->schemaManager->dropAndCreateTable($table);
383
384
        $columns = $this->schemaManager->listTableColumns($tableName);
385
386
        self::assertArrayHasKey('col', $columns);
387
        self::assertArrayHasKey('col_unsigned', $columns);
388
        self::assertFalse($columns['col']->getUnsigned());
389
        self::assertTrue($columns['col_unsigned']->getUnsigned());
390
    }
391
392
    /**
393
     * @group DBAL-1082
394
     */
395
    public function testListFloatTypeColumns()
396
    {
397
        $tableName = 'test_list_float_columns';
398
        $table     = new Table($tableName);
399
400
        $table->addColumn('col', 'float');
401
        $table->addColumn('col_unsigned', 'float', ['unsigned' => true]);
402
403
        $this->schemaManager->dropAndCreateTable($table);
404
405
        $columns = $this->schemaManager->listTableColumns($tableName);
406
407
        self::assertArrayHasKey('col', $columns);
408
        self::assertArrayHasKey('col_unsigned', $columns);
409
        self::assertFalse($columns['col']->getUnsigned());
410
        self::assertTrue($columns['col_unsigned']->getUnsigned());
411
    }
412
413
    public function testJsonColumnType() : void
414
    {
415
        $table = new Table('test_mysql_json');
416
        $table->addColumn('col_json', 'json');
417
        $this->schemaManager->dropAndCreateTable($table);
418
419
        $columns = $this->schemaManager->listTableColumns('test_mysql_json');
420
421
        self::assertSame(Types::JSON, $columns['col_json']->getType()->getName());
422
    }
423
424
    public function testColumnDefaultCurrentTimestamp() : void
425
    {
426
        $platform = $this->schemaManager->getDatabasePlatform();
427
428
        $table = new Table('test_column_defaults_current_timestamp');
429
430
        $currentTimeStampSql = $platform->getCurrentTimestampSQL();
431
432
        $table->addColumn('col_datetime', 'datetime', ['notnull' => true, 'default' => $currentTimeStampSql]);
433
        $table->addColumn('col_datetime_nullable', 'datetime', ['default' => $currentTimeStampSql]);
434
435
        $this->schemaManager->dropAndCreateTable($table);
436
437
        $onlineTable = $this->schemaManager->listTableDetails('test_column_defaults_current_timestamp');
438
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime')->getDefault());
439
        self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime_nullable')->getDefault());
440
441
        $comparator = new Comparator();
442
443
        $diff = $comparator->diffTable($table, $onlineTable);
444
        self::assertFalse($diff, 'Tables should be identical with column defaults.');
445
    }
446
447
    public function testColumnDefaultsAreValid()
448
    {
449
        $table = new Table('test_column_defaults_are_valid');
450
451
        $currentTimeStampSql = $this->schemaManager->getDatabasePlatform()->getCurrentTimestampSQL();
452
        $table->addColumn('col_datetime', 'datetime', ['default' => $currentTimeStampSql]);
453
        $table->addColumn('col_datetime_null', 'datetime', ['notnull' => false, 'default' => null]);
454
        $table->addColumn('col_int', 'integer', ['default' => 1]);
455
        $table->addColumn('col_neg_int', 'integer', ['default' => -1]);
456
        $table->addColumn('col_string', 'string', ['default' => 'A']);
457
        $table->addColumn('col_decimal', 'decimal', ['scale' => 3, 'precision' => 6, 'default' => -2.3]);
458
        $table->addColumn('col_date', 'date', ['default' => '2012-12-12']);
459
460
        $this->schemaManager->dropAndCreateTable($table);
461
462
        $this->connection->executeUpdate(
463
            'INSERT INTO test_column_defaults_are_valid () VALUES()'
464
        );
465
466
        $row = $this->connection->fetchAssoc(
467
            'SELECT *, DATEDIFF(CURRENT_TIMESTAMP(), col_datetime) as diff_seconds FROM test_column_defaults_are_valid'
468
        );
469
470
        self::assertInstanceOf(DateTime::class, DateTime::createFromFormat('Y-m-d H:i:s', $row['col_datetime']));
471
        self::assertNull($row['col_datetime_null']);
472
        self::assertSame('2012-12-12', $row['col_date']);
473
        self::assertSame('A', $row['col_string']);
474
        self::assertEquals(1, $row['col_int']);
475
        self::assertEquals(-1, $row['col_neg_int']);
476
        self::assertEquals('-2.300', $row['col_decimal']);
477
        self::assertLessThan(5, $row['diff_seconds']);
478
    }
479
480
    /**
481
     * MariaDB 10.2+ does support CURRENT_TIME and CURRENT_DATE as
482
     * column default values for time and date columns.
483
     * (Not supported on Mysql as of 5.7.19)
484
     *
485
     * Note that MariaDB 10.2+, when storing default in information_schema,
486
     * silently change CURRENT_TIMESTAMP as 'current_timestamp()',
487
     * CURRENT_TIME as 'currtime()' and CURRENT_DATE as 'currdate()'.
488
     * This test also ensure proper aliasing to not trigger a table diff.
489
     */
490
    public function testColumnDefaultValuesCurrentTimeAndDate() : void
491
    {
492
        if (! $this->schemaManager->getDatabasePlatform() instanceof MariaDb1027Platform) {
493
            $this->markTestSkipped('Only relevant for MariaDb102Platform.');
494
        }
495
496
        $platform = $this->schemaManager->getDatabasePlatform();
497
498
        $table = new Table('test_column_defaults_current_time_and_date');
499
500
        $currentTimestampSql = $platform->getCurrentTimestampSQL();
501
        $currentTimeSql      = $platform->getCurrentTimeSQL();
502
        $currentDateSql      = $platform->getCurrentDateSQL();
503
504
        $table->addColumn('col_datetime', 'datetime', ['default' => $currentTimestampSql]);
505
        $table->addColumn('col_date', 'date', ['default' => $currentDateSql]);
506
        $table->addColumn('col_time', 'time', ['default' => $currentTimeSql]);
507
508
        $this->schemaManager->dropAndCreateTable($table);
509
510
        $onlineTable = $this->schemaManager->listTableDetails('test_column_defaults_current_time_and_date');
511
512
        self::assertSame($currentTimestampSql, $onlineTable->getColumn('col_datetime')->getDefault());
513
        self::assertSame($currentDateSql, $onlineTable->getColumn('col_date')->getDefault());
514
        self::assertSame($currentTimeSql, $onlineTable->getColumn('col_time')->getDefault());
515
516
        $comparator = new Comparator();
517
518
        $diff = $comparator->diffTable($table, $onlineTable);
519
        self::assertFalse($diff, 'Tables should be identical with column defauts time and date.');
520
    }
521
522
    /**
523
     * Ensure default values (un-)escaping is properly done by mysql platforms.
524
     * The test is voluntarily relying on schema introspection due to current
525
     * doctrine limitations. Once #2850 is landed, this test can be removed.
526
     *
527
     * @see https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
528
     */
529
    public function testEnsureDefaultsAreUnescapedFromSchemaIntrospection() : void
530
    {
531
        $platform = $this->schemaManager->getDatabasePlatform();
532
        $this->connection->query('DROP TABLE IF EXISTS test_column_defaults_with_create');
533
534
        $escapeSequences = [
535
            "\\0",          // An ASCII NUL (X'00') character
536
            "\\'",
537
            "''",    // Single quote
538
            '\\"',
539
            '""',    // Double quote
540
            '\\b',          // A backspace character
541
            '\\n',          // A new-line character
542
            '\\r',          // A carriage return character
543
            '\\t',          // A tab character
544
            '\\Z',          // ASCII 26 (Control+Z)
545
            '\\\\',         // A backslash (\) character
546
            '\\%',          // A percent (%) character
547
            '\\_',          // An underscore (_) character
548
        ];
549
550
        $default = implode('+', $escapeSequences);
551
552
        $sql = sprintf(
553
            'CREATE TABLE test_column_defaults_with_create(col1 VARCHAR(255) NULL DEFAULT %s)',
554
            $platform->quoteStringLiteral($default)
555
        );
556
        $this->connection->query($sql);
557
        $onlineTable = $this->schemaManager->listTableDetails('test_column_defaults_with_create');
558
        self::assertSame($default, $onlineTable->getColumn('col1')->getDefault());
559
    }
560
561
    public function testEnsureTableOptionsAreReflectedInMetadata() : void
562
    {
563
        $this->connection->query('DROP TABLE IF EXISTS test_table_metadata');
564
565
        $sql = <<<'SQL'
566
CREATE TABLE test_table_metadata(
567
  col1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY
568
)
569
COLLATE utf8_general_ci
570
ENGINE InnoDB
571
ROW_FORMAT COMPRESSED
572
COMMENT 'This is a test'
573
AUTO_INCREMENT=42
574
PARTITION BY HASH (col1)
575
SQL;
576
577
        $this->connection->query($sql);
578
        $onlineTable = $this->schemaManager->listTableDetails('test_table_metadata');
579
580
        self::assertEquals('InnoDB', $onlineTable->getOption('engine'));
581
        self::assertEquals('utf8_general_ci', $onlineTable->getOption('collation'));
582
        self::assertEquals(42, $onlineTable->getOption('autoincrement'));
583
        self::assertEquals('This is a test', $onlineTable->getOption('comment'));
584
        self::assertEquals([
585
            'row_format' => 'COMPRESSED',
586
            'partitioned' => true,
587
        ], $onlineTable->getOption('create_options'));
588
    }
589
590
    public function testEnsureTableWithoutOptionsAreReflectedInMetadata() : void
591
    {
592
        $this->connection->query('DROP TABLE IF EXISTS test_table_empty_metadata');
593
594
        $this->connection->query('CREATE TABLE test_table_empty_metadata(col1 INT NOT NULL)');
595
        $onlineTable = $this->schemaManager->listTableDetails('test_table_empty_metadata');
596
597
        self::assertNotEmpty($onlineTable->getOption('engine'));
598
        // collation could be set to default or not set, information_schema indicate a possibly null value
599
        self::assertFalse($onlineTable->hasOption('autoincrement'));
600
        self::assertEquals('', $onlineTable->getOption('comment'));
601
        self::assertEquals([], $onlineTable->getOption('create_options'));
602
    }
603
604
    public function testParseNullCreateOptions() : void
605
    {
606
        $table = $this->schemaManager->listTableDetails('sys.processlist');
607
608
        self::assertEquals([], $table->getOption('create_options'));
609
    }
610
}
611