Completed
Push — develop ( 7c38e8...152bc9 )
by Sergei
64:01 queued 11s
created

testColumnCharsetDeclarationSQL()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Platforms;
4
5
use Doctrine\DBAL\Platforms\AbstractPlatform;
6
use Doctrine\DBAL\Schema\Comparator;
7
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
8
use Doctrine\DBAL\Schema\Index;
9
use Doctrine\DBAL\Schema\Table;
10
use Doctrine\DBAL\Schema\TableDiff;
11
use Doctrine\DBAL\TransactionIsolationLevel;
12
use function array_shift;
13
14
abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase
15
{
16
    public function testModifyLimitQueryWitoutLimit()
17
    {
18
        $sql = $this->platform->modifyLimitQuery('SELECT n FROM Foo', null, 10);
19
        self::assertEquals('SELECT n FROM Foo LIMIT 18446744073709551615 OFFSET 10', $sql);
20
    }
21
22
    public function testGenerateMixedCaseTableCreate()
23
    {
24
        $table = new Table('Foo');
25
        $table->addColumn('Bar', 'integer');
26
27
        $sql = $this->platform->getCreateTableSQL($table);
28
        self::assertEquals('CREATE TABLE Foo (Bar INT NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB', array_shift($sql));
29
    }
30
31
    public function getGenerateTableSql()
32
    {
33
        return 'CREATE TABLE test (id INT AUTO_INCREMENT NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';
34
    }
35
36
    public function getGenerateTableWithMultiColumnUniqueIndexSql()
37
    {
38
        return ['CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL, UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA (foo, bar)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'];
39
    }
40
41
    public function getGenerateAlterTableSql()
42
    {
43
        return ["ALTER TABLE mytable RENAME TO userlist, ADD quota INT DEFAULT NULL, DROP foo, CHANGE bar baz VARCHAR(255) DEFAULT 'def' NOT NULL, CHANGE bloo bloo TINYINT(1) DEFAULT '0' NOT NULL"];
44
    }
45
46
    public function testGeneratesSqlSnippets()
47
    {
48
        self::assertEquals('RLIKE', $this->platform->getRegexpExpression(), 'Regular expression operator is not correct');
49
        self::assertEquals('`', $this->platform->getIdentifierQuoteCharacter(), 'Quote character is not correct');
50
        self::assertEquals('CONCAT(column1, column2, column3)', $this->platform->getConcatExpression('column1', 'column2', 'column3'), 'Concatenation function is not correct');
51
    }
52
53
    public function testGeneratesTransactionsCommands()
54
    {
55
        self::assertEquals(
56
            'SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED',
57
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_UNCOMMITTED),
58
            ''
59
        );
60
        self::assertEquals(
61
            'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED',
62
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_COMMITTED)
63
        );
64
        self::assertEquals(
65
            'SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ',
66
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::REPEATABLE_READ)
67
        );
68
        self::assertEquals(
69
            'SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE',
70
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::SERIALIZABLE)
71
        );
72
    }
73
74
75
    public function testGeneratesDDLSnippets()
76
    {
77
        self::assertEquals('SHOW DATABASES', $this->platform->getListDatabasesSQL());
78
        self::assertEquals('CREATE DATABASE foobar', $this->platform->getCreateDatabaseSQL('foobar'));
79
        self::assertEquals('DROP DATABASE foobar', $this->platform->getDropDatabaseSQL('foobar'));
80
        self::assertEquals('DROP TABLE foobar', $this->platform->getDropTableSQL('foobar'));
81
    }
82
83
    public function testGeneratesTypeDeclarationForIntegers()
84
    {
85
        self::assertEquals(
86
            'INT',
87
            $this->platform->getIntegerTypeDeclarationSQL([])
88
        );
89
        self::assertEquals(
90
            'INT AUTO_INCREMENT',
91
            $this->platform->getIntegerTypeDeclarationSQL(['autoincrement' => true])
92
        );
93
        self::assertEquals(
94
            'INT AUTO_INCREMENT',
95
            $this->platform->getIntegerTypeDeclarationSQL(
96
                ['autoincrement' => true, 'primary' => true]
97
            )
98
        );
99
    }
100
101
    public function testGeneratesTypeDeclarationForStrings()
102
    {
103
        self::assertEquals(
104
            'CHAR(10)',
105
            $this->platform->getVarcharTypeDeclarationSQL(
106
                ['length' => 10, 'fixed' => true]
107
            )
108
        );
109
        self::assertEquals(
110
            'VARCHAR(50)',
111
            $this->platform->getVarcharTypeDeclarationSQL(['length' => 50]),
112
            'Variable string declaration is not correct'
113
        );
114
        self::assertEquals(
115
            'VARCHAR(255)',
116
            $this->platform->getVarcharTypeDeclarationSQL([]),
117
            'Long string declaration is not correct'
118
        );
119
    }
120
121
    public function testPrefersIdentityColumns()
122
    {
123
        self::assertTrue($this->platform->prefersIdentityColumns());
124
    }
125
126
    public function testSupportsIdentityColumns()
127
    {
128
        self::assertTrue($this->platform->supportsIdentityColumns());
129
    }
130
131
    public function testDoesSupportSavePoints()
132
    {
133
        self::assertTrue($this->platform->supportsSavepoints());
134
    }
135
136
    public function getGenerateIndexSql()
137
    {
138
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
139
    }
140
141
    public function getGenerateUniqueIndexSql()
142
    {
143
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
144
    }
145
146
    public function getGenerateForeignKeySql()
147
    {
148
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
149
    }
150
151
    /**
152
     * @group DBAL-126
153
     */
154
    public function testUniquePrimaryKey()
155
    {
156
        $keyTable = new Table('foo');
157
        $keyTable->addColumn('bar', 'integer');
158
        $keyTable->addColumn('baz', 'string');
159
        $keyTable->setPrimaryKey(['bar']);
160
        $keyTable->addUniqueIndex(['baz']);
161
162
        $oldTable = new Table('foo');
163
        $oldTable->addColumn('bar', 'integer');
164
        $oldTable->addColumn('baz', 'string');
165
166
        $c    = new Comparator();
167
        $diff = $c->diffTable($oldTable, $keyTable);
168
169
        $sql = $this->platform->getAlterTableSQL($diff);
0 ignored issues
show
Bug introduced by
It seems like $diff can also be of type false; however, parameter $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() 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

169
        $sql = $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $diff);
Loading history...
170
171
        self::assertEquals([
172
            'ALTER TABLE foo ADD PRIMARY KEY (bar)',
173
            'CREATE UNIQUE INDEX UNIQ_8C73652178240498 ON foo (baz)',
174
        ], $sql);
175
    }
176
177
    public function testModifyLimitQuery()
178
    {
179
        $sql = $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 0);
180
        self::assertEquals('SELECT * FROM user LIMIT 10', $sql);
181
    }
182
183
    public function testModifyLimitQueryWithEmptyOffset()
184
    {
185
        $sql = $this->platform->modifyLimitQuery('SELECT * FROM user', 10);
186
        self::assertEquals('SELECT * FROM user LIMIT 10', $sql);
187
    }
188
189
    /**
190
     * @group DDC-118
191
     */
192
    public function testGetDateTimeTypeDeclarationSql()
193
    {
194
        self::assertEquals('DATETIME', $this->platform->getDateTimeTypeDeclarationSQL(['version' => false]));
195
        self::assertEquals('TIMESTAMP', $this->platform->getDateTimeTypeDeclarationSQL(['version' => true]));
196
        self::assertEquals('DATETIME', $this->platform->getDateTimeTypeDeclarationSQL([]));
197
    }
198
199
    public function getCreateTableColumnCommentsSQL()
200
    {
201
        return ["CREATE TABLE test (id INT NOT NULL COMMENT 'This is a comment', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"];
202
    }
203
204
    public function getAlterTableColumnCommentsSQL()
205
    {
206
        return ["ALTER TABLE mytable ADD quota INT NOT NULL COMMENT 'A comment', CHANGE foo foo VARCHAR(255) NOT NULL, CHANGE bar baz VARCHAR(255) NOT NULL COMMENT 'B comment'"];
207
    }
208
209
    public function getCreateTableColumnTypeCommentsSQL()
210
    {
211
        return ["CREATE TABLE test (id INT NOT NULL, data LONGTEXT NOT NULL COMMENT '(DC2Type:array)', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"];
212
    }
213
214
    /**
215
     * @group DBAL-237
216
     */
217
    public function testChangeIndexWithForeignKeys()
218
    {
219
        $index  = new Index('idx', ['col'], false);
220
        $unique = new Index('uniq', ['col'], true);
221
222
        $diff = new TableDiff('test', [], [], [], [$unique], [], [$index]);
223
        $sql  = $this->platform->getAlterTableSQL($diff);
224
        self::assertEquals(['ALTER TABLE test DROP INDEX idx, ADD UNIQUE INDEX uniq (col)'], $sql);
225
226
        $diff = new TableDiff('test', [], [], [], [$index], [], [$unique]);
227
        $sql  = $this->platform->getAlterTableSQL($diff);
228
        self::assertEquals(['ALTER TABLE test DROP INDEX uniq, ADD INDEX idx (col)'], $sql);
229
    }
230
231
    protected function getQuotedColumnInPrimaryKeySQL()
232
    {
233
        return ['CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, PRIMARY KEY(`create`)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'];
234
    }
235
236
    protected function getQuotedColumnInIndexSQL()
237
    {
238
        return ['CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, INDEX IDX_22660D028FD6E0FB (`create`)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'];
239
    }
240
241
    protected function getQuotedNameInIndexSQL()
242
    {
243
        return ['CREATE TABLE test (column1 VARCHAR(255) NOT NULL, INDEX `key` (column1)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'];
244
    }
245
246
    protected function getQuotedColumnInForeignKeySQL()
247
    {
248
        return [
249
            'CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, `bar` VARCHAR(255) NOT NULL) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB',
250
            'ALTER TABLE `quoted` ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY (`create`, foo, `bar`) REFERENCES `foreign` (`create`, bar, `foo-bar`)',
251
            'ALTER TABLE `quoted` ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY (`create`, foo, `bar`) REFERENCES foo (`create`, bar, `foo-bar`)',
252
            'ALTER TABLE `quoted` ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY (`create`, foo, `bar`) REFERENCES `foo-bar` (`create`, bar, `foo-bar`)',
253
        ];
254
    }
255
256
    public function testCreateTableWithFulltextIndex()
257
    {
258
        $table = new Table('fulltext_table');
259
        $table->addOption('engine', 'MyISAM');
260
        $table->addColumn('text', 'text');
261
        $table->addIndex(['text'], 'fulltext_text');
262
263
        $index = $table->getIndex('fulltext_text');
264
        $index->addFlag('fulltext');
265
266
        $sql = $this->platform->getCreateTableSQL($table);
267
        self::assertEquals(['CREATE TABLE fulltext_table (text LONGTEXT NOT NULL, FULLTEXT INDEX fulltext_text (text)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = MyISAM'], $sql);
268
    }
269
270
    public function testCreateTableWithSpatialIndex()
271
    {
272
        $table = new Table('spatial_table');
273
        $table->addOption('engine', 'MyISAM');
274
        $table->addColumn('point', 'text'); // This should be a point type
275
        $table->addIndex(['point'], 'spatial_text');
276
277
        $index = $table->getIndex('spatial_text');
278
        $index->addFlag('spatial');
279
280
        $sql = $this->platform->getCreateTableSQL($table);
281
        self::assertEquals(['CREATE TABLE spatial_table (point LONGTEXT NOT NULL, SPATIAL INDEX spatial_text (point)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = MyISAM'], $sql);
282
    }
283
284
    public function testClobTypeDeclarationSQL()
285
    {
286
        self::assertEquals('TINYTEXT', $this->platform->getClobTypeDeclarationSQL(['length' => 1]));
287
        self::assertEquals('TINYTEXT', $this->platform->getClobTypeDeclarationSQL(['length' => 255]));
288
        self::assertEquals('TEXT', $this->platform->getClobTypeDeclarationSQL(['length' => 256]));
289
        self::assertEquals('TEXT', $this->platform->getClobTypeDeclarationSQL(['length' => 65535]));
290
        self::assertEquals('MEDIUMTEXT', $this->platform->getClobTypeDeclarationSQL(['length' => 65536]));
291
        self::assertEquals('MEDIUMTEXT', $this->platform->getClobTypeDeclarationSQL(['length' => 16777215]));
292
        self::assertEquals('LONGTEXT', $this->platform->getClobTypeDeclarationSQL(['length' => 16777216]));
293
        self::assertEquals('LONGTEXT', $this->platform->getClobTypeDeclarationSQL([]));
294
    }
295
296
    public function testBlobTypeDeclarationSQL()
297
    {
298
        self::assertEquals('TINYBLOB', $this->platform->getBlobTypeDeclarationSQL(['length' => 1]));
299
        self::assertEquals('TINYBLOB', $this->platform->getBlobTypeDeclarationSQL(['length' => 255]));
300
        self::assertEquals('BLOB', $this->platform->getBlobTypeDeclarationSQL(['length' => 256]));
301
        self::assertEquals('BLOB', $this->platform->getBlobTypeDeclarationSQL(['length' => 65535]));
302
        self::assertEquals('MEDIUMBLOB', $this->platform->getBlobTypeDeclarationSQL(['length' => 65536]));
303
        self::assertEquals('MEDIUMBLOB', $this->platform->getBlobTypeDeclarationSQL(['length' => 16777215]));
304
        self::assertEquals('LONGBLOB', $this->platform->getBlobTypeDeclarationSQL(['length' => 16777216]));
305
        self::assertEquals('LONGBLOB', $this->platform->getBlobTypeDeclarationSQL([]));
306
    }
307
308
    /**
309
     * @group DBAL-400
310
     */
311
    public function testAlterTableAddPrimaryKey()
312
    {
313
        $table = new Table('alter_table_add_pk');
314
        $table->addColumn('id', 'integer');
315
        $table->addColumn('foo', 'integer');
316
        $table->addIndex(['id'], 'idx_id');
317
318
        $comparator = new Comparator();
319
        $diffTable  = clone $table;
320
321
        $diffTable->dropIndex('idx_id');
322
        $diffTable->setPrimaryKey(['id']);
323
324
        self::assertEquals(
325
            ['DROP INDEX idx_id ON alter_table_add_pk', 'ALTER TABLE alter_table_add_pk ADD PRIMARY KEY (id)'],
326
            $this->platform->getAlterTableSQL($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 $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() 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

326
            $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable))
Loading history...
327
        );
328
    }
329
330
    /**
331
     * @group DBAL-1132
332
     */
333
    public function testAlterPrimaryKeyWithAutoincrementColumn()
334
    {
335
        $table = new Table('alter_primary_key');
336
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
337
        $table->addColumn('foo', 'integer');
338
        $table->setPrimaryKey(['id']);
339
340
        $comparator = new Comparator();
341
        $diffTable  = clone $table;
342
343
        $diffTable->dropPrimaryKey();
344
        $diffTable->setPrimaryKey(['foo']);
345
346
        self::assertEquals(
347
            [
348
                'ALTER TABLE alter_primary_key MODIFY id INT NOT NULL',
349
                'ALTER TABLE alter_primary_key DROP PRIMARY KEY',
350
                'ALTER TABLE alter_primary_key ADD PRIMARY KEY (foo)',
351
            ],
352
            $this->platform->getAlterTableSQL($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 $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() 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

352
            $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable))
Loading history...
353
        );
354
    }
355
356
    /**
357
     * @group DBAL-464
358
     */
359
    public function testDropPrimaryKeyWithAutoincrementColumn()
360
    {
361
        $table = new Table('drop_primary_key');
362
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
363
        $table->addColumn('foo', 'integer');
364
        $table->addColumn('bar', 'integer');
365
        $table->setPrimaryKey(['id', 'foo']);
366
367
        $comparator = new Comparator();
368
        $diffTable  = clone $table;
369
370
        $diffTable->dropPrimaryKey();
371
372
        self::assertEquals(
373
            [
374
                'ALTER TABLE drop_primary_key MODIFY id INT NOT NULL',
375
                'ALTER TABLE drop_primary_key DROP PRIMARY KEY',
376
            ],
377
            $this->platform->getAlterTableSQL($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 $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() 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

377
            $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable))
Loading history...
378
        );
379
    }
380
381
    /**
382
     * @group DBAL-2302
383
     */
384
    public function testDropNonAutoincrementColumnFromCompositePrimaryKeyWithAutoincrementColumn()
385
    {
386
        $table = new Table('tbl');
387
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
388
        $table->addColumn('foo', 'integer');
389
        $table->addColumn('bar', 'integer');
390
        $table->setPrimaryKey(['id', 'foo']);
391
392
        $comparator = new Comparator();
393
        $diffTable  = clone $table;
394
395
        $diffTable->dropPrimaryKey();
396
        $diffTable->setPrimaryKey(['id']);
397
398
        self::assertSame(
399
            [
400
                'ALTER TABLE tbl MODIFY id INT NOT NULL',
401
                'ALTER TABLE tbl DROP PRIMARY KEY',
402
                'ALTER TABLE tbl ADD PRIMARY KEY (id)',
403
            ],
404
            $this->platform->getAlterTableSQL($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 $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() 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

404
            $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable))
Loading history...
405
        );
406
    }
407
408
    /**
409
     * @group DBAL-2302
410
     */
411
    public function testAddNonAutoincrementColumnToPrimaryKeyWithAutoincrementColumn()
412
    {
413
        $table = new Table('tbl');
414
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
415
        $table->addColumn('foo', 'integer');
416
        $table->addColumn('bar', 'integer');
417
        $table->setPrimaryKey(['id']);
418
419
        $comparator = new Comparator();
420
        $diffTable  = clone $table;
421
422
        $diffTable->dropPrimaryKey();
423
        $diffTable->setPrimaryKey(['id', 'foo']);
424
425
        self::assertSame(
426
            [
427
                'ALTER TABLE tbl MODIFY id INT NOT NULL',
428
                'ALTER TABLE tbl DROP PRIMARY KEY',
429
                'ALTER TABLE tbl ADD PRIMARY KEY (id, foo)',
430
            ],
431
            $this->platform->getAlterTableSQL($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 $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() 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

431
            $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable))
Loading history...
432
        );
433
    }
434
435
    /**
436
     * @group DBAL-586
437
     */
438
    public function testAddAutoIncrementPrimaryKey()
439
    {
440
        $keyTable = new Table('foo');
441
        $keyTable->addColumn('id', 'integer', ['autoincrement' => true]);
442
        $keyTable->addColumn('baz', 'string');
443
        $keyTable->setPrimaryKey(['id']);
444
445
        $oldTable = new Table('foo');
446
        $oldTable->addColumn('baz', 'string');
447
448
        $c    = new Comparator();
449
        $diff = $c->diffTable($oldTable, $keyTable);
450
451
        $sql = $this->platform->getAlterTableSQL($diff);
0 ignored issues
show
Bug introduced by
It seems like $diff can also be of type false; however, parameter $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() 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

451
        $sql = $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $diff);
Loading history...
452
453
        self::assertEquals(['ALTER TABLE foo ADD id INT AUTO_INCREMENT NOT NULL, ADD PRIMARY KEY (id)'], $sql);
454
    }
455
456
    public function testNamedPrimaryKey()
457
    {
458
        $diff                              = new TableDiff('mytable');
459
        $diff->changedIndexes['foo_index'] = new Index('foo_index', ['foo'], true, true);
460
461
        $sql = $this->platform->getAlterTableSQL($diff);
462
463
        self::assertEquals([
464
            'ALTER TABLE mytable DROP PRIMARY KEY',
465
            'ALTER TABLE mytable ADD PRIMARY KEY (foo)',
466
        ], $sql);
467
    }
468
469
    public function testAlterPrimaryKeyWithNewColumn()
470
    {
471
        $table = new Table('yolo');
472
        $table->addColumn('pkc1', 'integer');
473
        $table->addColumn('col_a', 'integer');
474
        $table->setPrimaryKey(['pkc1']);
475
476
        $comparator = new Comparator();
477
        $diffTable  = clone $table;
478
479
        $diffTable->addColumn('pkc2', 'integer');
480
        $diffTable->dropPrimaryKey();
481
        $diffTable->setPrimaryKey(['pkc1', 'pkc2']);
482
483
        self::assertSame(
484
            [
485
                'ALTER TABLE yolo DROP PRIMARY KEY',
486
                'ALTER TABLE yolo ADD pkc2 INT NOT NULL',
487
                'ALTER TABLE yolo ADD PRIMARY KEY (pkc1, pkc2)',
488
            ],
489
            $this->platform->getAlterTableSQL($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 $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() 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

489
            $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable))
Loading history...
490
        );
491
    }
492
493
    public function testInitializesDoctrineTypeMappings()
494
    {
495
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('binary'));
496
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('binary'));
497
498
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('varbinary'));
499
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('varbinary'));
500
    }
501
502
    protected function getBinaryMaxLength()
503
    {
504
        return 65535;
505
    }
506
507
    public function testReturnsBinaryTypeDeclarationSQL()
508
    {
509
        self::assertSame('VARBINARY(255)', $this->platform->getBinaryTypeDeclarationSQL([]));
510
        self::assertSame('VARBINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 0]));
511
        self::assertSame('VARBINARY(65535)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 65535]));
512
        self::assertSame('VARBINARY(65536)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 65536]));
513
514
        self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
515
        self::assertSame('BINARY(255)', $this->platform->getBinaryTypeDeclarationSQL([
516
            'fixed' => true,
517
            'length' => 0,
518
        ]));
519
        self::assertSame('BINARY(65535)', $this->platform->getBinaryTypeDeclarationSQL([
520
            'fixed' => true,
521
            'length' => 65535,
522
        ]));
523
        self::assertSame('BINARY(65536)', $this->platform->getBinaryTypeDeclarationSQL([
524
            'fixed' => true,
525
            'length' => 65536,
526
        ]));
527
    }
528
529
    public function testDoesNotPropagateForeignKeyCreationForNonSupportingEngines()
530
    {
531
        $table = new Table('foreign_table');
532
        $table->addColumn('id', 'integer');
533
        $table->addColumn('fk_id', 'integer');
534
        $table->addForeignKeyConstraint('foreign_table', ['fk_id'], ['id']);
535
        $table->setPrimaryKey(['id']);
536
        $table->addOption('engine', 'MyISAM');
537
538
        self::assertSame(
539
            ['CREATE TABLE foreign_table (id INT NOT NULL, fk_id INT NOT NULL, INDEX IDX_5690FFE2A57719D0 (fk_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = MyISAM'],
540
            $this->platform->getCreateTableSQL(
541
                $table,
542
                AbstractPlatform::CREATE_INDEXES|AbstractPlatform::CREATE_FOREIGNKEYS
543
            )
544
        );
545
546
        $table = clone $table;
547
        $table->addOption('engine', 'InnoDB');
548
549
        self::assertSame(
550
            [
551
                'CREATE TABLE foreign_table (id INT NOT NULL, fk_id INT NOT NULL, INDEX IDX_5690FFE2A57719D0 (fk_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB',
552
                'ALTER TABLE foreign_table ADD CONSTRAINT FK_5690FFE2A57719D0 FOREIGN KEY (fk_id) REFERENCES foreign_table (id)',
553
            ],
554
            $this->platform->getCreateTableSQL(
555
                $table,
556
                AbstractPlatform::CREATE_INDEXES|AbstractPlatform::CREATE_FOREIGNKEYS
557
            )
558
        );
559
    }
560
561
    public function testDoesNotPropagateForeignKeyAlterationForNonSupportingEngines()
562
    {
563
        $table = new Table('foreign_table');
564
        $table->addColumn('id', 'integer');
565
        $table->addColumn('fk_id', 'integer');
566
        $table->addForeignKeyConstraint('foreign_table', ['fk_id'], ['id']);
567
        $table->setPrimaryKey(['id']);
568
        $table->addOption('engine', 'MyISAM');
569
570
        $addedForeignKeys   = [new ForeignKeyConstraint(['fk_id'], 'foo', ['id'], 'fk_add')];
571
        $changedForeignKeys = [new ForeignKeyConstraint(['fk_id'], 'bar', ['id'], 'fk_change')];
572
        $removedForeignKeys = [new ForeignKeyConstraint(['fk_id'], 'baz', ['id'], 'fk_remove')];
573
574
        $tableDiff                     = new TableDiff('foreign_table');
575
        $tableDiff->fromTable          = $table;
576
        $tableDiff->addedForeignKeys   = $addedForeignKeys;
577
        $tableDiff->changedForeignKeys = $changedForeignKeys;
578
        $tableDiff->removedForeignKeys = $removedForeignKeys;
579
580
        self::assertEmpty($this->platform->getAlterTableSQL($tableDiff));
581
582
        $table->addOption('engine', 'InnoDB');
583
584
        $tableDiff                     = new TableDiff('foreign_table');
585
        $tableDiff->fromTable          = $table;
586
        $tableDiff->addedForeignKeys   = $addedForeignKeys;
587
        $tableDiff->changedForeignKeys = $changedForeignKeys;
588
        $tableDiff->removedForeignKeys = $removedForeignKeys;
589
590
        self::assertSame(
591
            [
592
                'ALTER TABLE foreign_table DROP FOREIGN KEY fk_remove',
593
                'ALTER TABLE foreign_table DROP FOREIGN KEY fk_change',
594
                'ALTER TABLE foreign_table ADD CONSTRAINT fk_add FOREIGN KEY (fk_id) REFERENCES foo (id)',
595
                'ALTER TABLE foreign_table ADD CONSTRAINT fk_change FOREIGN KEY (fk_id) REFERENCES bar (id)',
596
            ],
597
            $this->platform->getAlterTableSQL($tableDiff)
598
        );
599
    }
600
601
    /**
602
     * @group DBAL-234
603
     */
604
    protected function getAlterTableRenameIndexSQL()
605
    {
606
        return [
607
            'DROP INDEX idx_foo ON mytable',
608
            'CREATE INDEX idx_bar ON mytable (id)',
609
        ];
610
    }
611
612
    /**
613
     * @group DBAL-234
614
     */
615
    protected function getQuotedAlterTableRenameIndexSQL()
616
    {
617
        return [
618
            'DROP INDEX `create` ON `table`',
619
            'CREATE INDEX `select` ON `table` (id)',
620
            'DROP INDEX `foo` ON `table`',
621
            'CREATE INDEX `bar` ON `table` (id)',
622
        ];
623
    }
624
625
    /**
626
     * @group DBAL-807
627
     */
628
    protected function getAlterTableRenameIndexInSchemaSQL()
629
    {
630
        return [
631
            'DROP INDEX idx_foo ON myschema.mytable',
632
            'CREATE INDEX idx_bar ON myschema.mytable (id)',
633
        ];
634
    }
635
636
    /**
637
     * @group DBAL-807
638
     */
639
    protected function getQuotedAlterTableRenameIndexInSchemaSQL()
640
    {
641
        return [
642
            'DROP INDEX `create` ON `schema`.`table`',
643
            'CREATE INDEX `select` ON `schema`.`table` (id)',
644
            'DROP INDEX `foo` ON `schema`.`table`',
645
            'CREATE INDEX `bar` ON `schema`.`table` (id)',
646
        ];
647
    }
648
649
    protected function getQuotesDropForeignKeySQL()
650
    {
651
        return 'ALTER TABLE `table` DROP FOREIGN KEY `select`';
652
    }
653
654
    protected function getQuotesDropConstraintSQL()
655
    {
656
        return 'ALTER TABLE `table` DROP CONSTRAINT `select`';
657
    }
658
659
    public function testDoesNotPropagateDefaultValuesForUnsupportedColumnTypes()
660
    {
661
        $table = new Table('text_blob_default_value');
662
        $table->addColumn('def_text', 'text', ['default' => 'def']);
663
        $table->addColumn('def_text_null', 'text', ['notnull' => false, 'default' => 'def']);
664
        $table->addColumn('def_blob', 'blob', ['default' => 'def']);
665
        $table->addColumn('def_blob_null', 'blob', ['notnull' => false, 'default' => 'def']);
666
667
        self::assertSame(
668
            ['CREATE TABLE text_blob_default_value (def_text LONGTEXT NOT NULL, def_text_null LONGTEXT DEFAULT NULL, def_blob LONGBLOB NOT NULL, def_blob_null LONGBLOB DEFAULT NULL) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'],
669
            $this->platform->getCreateTableSQL($table)
670
        );
671
672
        $diffTable = clone $table;
673
        $diffTable->changeColumn('def_text', ['default' => null]);
674
        $diffTable->changeColumn('def_text_null', ['default' => null]);
675
        $diffTable->changeColumn('def_blob', ['default' => null]);
676
        $diffTable->changeColumn('def_blob_null', ['default' => null]);
677
678
        $comparator = new Comparator();
679
680
        self::assertEmpty($this->platform->getAlterTableSQL($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 $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() 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

680
        self::assertEmpty($this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $comparator->diffTable($table, $diffTable)));
Loading history...
681
    }
682
683
    /**
684
     * {@inheritdoc}
685
     */
686
    protected function getQuotedAlterTableRenameColumnSQL()
687
    {
688
        return ['ALTER TABLE mytable ' .
689
            "CHANGE unquoted1 unquoted INT NOT NULL COMMENT 'Unquoted 1', " .
690
            "CHANGE unquoted2 `where` INT NOT NULL COMMENT 'Unquoted 2', " .
691
            "CHANGE unquoted3 `foo` INT NOT NULL COMMENT 'Unquoted 3', " .
692
            "CHANGE `create` reserved_keyword INT NOT NULL COMMENT 'Reserved keyword 1', " .
693
            "CHANGE `table` `from` INT NOT NULL COMMENT 'Reserved keyword 2', " .
694
            "CHANGE `select` `bar` INT NOT NULL COMMENT 'Reserved keyword 3', " .
695
            "CHANGE quoted1 quoted INT NOT NULL COMMENT 'Quoted 1', " .
696
            "CHANGE quoted2 `and` INT NOT NULL COMMENT 'Quoted 2', " .
697
            "CHANGE quoted3 `baz` INT NOT NULL COMMENT 'Quoted 3'",
698
        ];
699
    }
700
701
    /**
702
     * {@inheritdoc}
703
     */
704
    protected function getQuotedAlterTableChangeColumnLengthSQL()
705
    {
706
        return ['ALTER TABLE mytable ' .
707
            "CHANGE unquoted1 unquoted1 VARCHAR(255) NOT NULL COMMENT 'Unquoted 1', " .
708
            "CHANGE unquoted2 unquoted2 VARCHAR(255) NOT NULL COMMENT 'Unquoted 2', " .
709
            "CHANGE unquoted3 unquoted3 VARCHAR(255) NOT NULL COMMENT 'Unquoted 3', " .
710
            "CHANGE `create` `create` VARCHAR(255) NOT NULL COMMENT 'Reserved keyword 1', " .
711
            "CHANGE `table` `table` VARCHAR(255) NOT NULL COMMENT 'Reserved keyword 2', " .
712
            "CHANGE `select` `select` VARCHAR(255) NOT NULL COMMENT 'Reserved keyword 3'",
713
        ];
714
    }
715
716
    /**
717
     * @group DBAL-423
718
     */
719
    public function testReturnsGuidTypeDeclarationSQL()
720
    {
721
        self::assertSame('CHAR(36)', $this->platform->getGuidTypeDeclarationSQL([]));
722
    }
723
724
    /**
725
     * {@inheritdoc}
726
     */
727
    public function getAlterTableRenameColumnSQL()
728
    {
729
        return ["ALTER TABLE foo CHANGE bar baz INT DEFAULT 666 NOT NULL COMMENT 'rename test'"];
730
    }
731
732
    /**
733
     * {@inheritdoc}
734
     */
735
    protected function getQuotesTableIdentifiersInAlterTableSQL()
736
    {
737
        return [
738
            'ALTER TABLE `foo` DROP FOREIGN KEY fk1',
739
            'ALTER TABLE `foo` DROP FOREIGN KEY fk2',
740
            'ALTER TABLE `foo` RENAME TO `table`, ADD bloo INT NOT NULL, DROP baz, CHANGE bar bar INT DEFAULT NULL, ' .
741
            'CHANGE id war INT NOT NULL',
742
            'ALTER TABLE `table` ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
743
            'ALTER TABLE `table` ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
744
        ];
745
    }
746
747
    /**
748
     * {@inheritdoc}
749
     */
750
    protected function getCommentOnColumnSQL()
751
    {
752
        return [
753
            "COMMENT ON COLUMN foo.bar IS 'comment'",
754
            "COMMENT ON COLUMN `Foo`.`BAR` IS 'comment'",
755
            "COMMENT ON COLUMN `select`.`from` IS 'comment'",
756
        ];
757
    }
758
759
    /**
760
     * {@inheritdoc}
761
     */
762
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL()
763
    {
764
        return 'CONSTRAINT `select` UNIQUE (foo)';
765
    }
766
767
    /**
768
     * {@inheritdoc}
769
     */
770
    protected function getQuotesReservedKeywordInIndexDeclarationSQL()
771
    {
772
        return 'INDEX `select` (foo)';
773
    }
774
775
    /**
776
     * {@inheritdoc}
777
     */
778
    protected function getQuotesReservedKeywordInTruncateTableSQL()
779
    {
780
        return 'TRUNCATE `select`';
781
    }
782
783
    /**
784
     * {@inheritdoc}
785
     */
786
    protected function getAlterStringToFixedStringSQL()
787
    {
788
        return ['ALTER TABLE mytable CHANGE name name CHAR(2) NOT NULL'];
789
    }
790
791
    /**
792
     * {@inheritdoc}
793
     */
794
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL()
795
    {
796
        return [
797
            'ALTER TABLE mytable DROP FOREIGN KEY fk_foo',
798
            'DROP INDEX idx_foo ON mytable',
799
            'CREATE INDEX idx_foo_renamed ON mytable (foo)',
800
            'ALTER TABLE mytable ADD CONSTRAINT fk_foo FOREIGN KEY (foo) REFERENCES foreign_table (id)',
801
        ];
802
    }
803
804
    /**
805
     * {@inheritdoc}
806
     */
807
    public function getGeneratesDecimalTypeDeclarationSQL()
808
    {
809
        return [
810
            [[], 'NUMERIC(10, 0)'],
811
            [['unsigned' => true], 'NUMERIC(10, 0) UNSIGNED'],
812
            [['unsigned' => false], 'NUMERIC(10, 0)'],
813
            [['precision' => 5], 'NUMERIC(5, 0)'],
814
            [['scale' => 5], 'NUMERIC(10, 5)'],
815
            [['precision' => 8, 'scale' => 2], 'NUMERIC(8, 2)'],
816
        ];
817
    }
818
819
    /**
820
     * {@inheritdoc}
821
     */
822
    public function getGeneratesFloatDeclarationSQL()
823
    {
824
        return [
825
            [[], 'DOUBLE PRECISION'],
826
            [['unsigned' => true], 'DOUBLE PRECISION UNSIGNED'],
827
            [['unsigned' => false], 'DOUBLE PRECISION'],
828
            [['precision' => 5], 'DOUBLE PRECISION'],
829
            [['scale' => 5], 'DOUBLE PRECISION'],
830
            [['precision' => 8, 'scale' => 2], 'DOUBLE PRECISION'],
831
        ];
832
    }
833
834
    /**
835
     * @group DBAL-2436
836
     */
837
    public function testQuotesTableNameInListTableIndexesSQL()
838
    {
839
        self::assertContains("'Foo''Bar\\\\'", $this->platform->getListTableIndexesSQL("Foo'Bar\\", 'foo_db'), '', true);
840
    }
841
842
    /**
843
     * @group DBAL-2436
844
     */
845
    public function testQuotesDatabaseNameInListTableIndexesSQL()
846
    {
847
        self::assertContains("'Foo''Bar\\\\'", $this->platform->getListTableIndexesSQL('foo_table', "Foo'Bar\\"), '', true);
848
    }
849
850
    /**
851
     * @group DBAL-2436
852
     */
853
    public function testQuotesDatabaseNameInListViewsSQL()
854
    {
855
        self::assertContains("'Foo''Bar\\\\'", $this->platform->getListViewsSQL("Foo'Bar\\"), '', true);
856
    }
857
858
    /**
859
     * @group DBAL-2436
860
     */
861
    public function testQuotesTableNameInListTableForeignKeysSQL()
862
    {
863
        self::assertContains("'Foo''Bar\\\\'", $this->platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true);
864
    }
865
866
    /**
867
     * @group DBAL-2436
868
     */
869
    public function testQuotesDatabaseNameInListTableForeignKeysSQL()
870
    {
871
        self::assertContains("'Foo''Bar\\\\'", $this->platform->getListTableForeignKeysSQL('foo_table', "Foo'Bar\\"), '', true);
0 ignored issues
show
Unused Code introduced by
The call to Doctrine\DBAL\Platforms\...stTableForeignKeysSQL() has too many arguments starting with 'Foo'Bar\'. ( Ignorable by Annotation )

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

871
        self::assertContains("'Foo''Bar\\\\'", $this->platform->/** @scrutinizer ignore-call */ getListTableForeignKeysSQL('foo_table', "Foo'Bar\\"), '', true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
872
    }
873
874
    /**
875
     * @group DBAL-2436
876
     */
877
    public function testQuotesTableNameInListTableColumnsSQL()
878
    {
879
        self::assertContains("'Foo''Bar\\\\'", $this->platform->getListTableColumnsSQL("Foo'Bar\\"), '', true);
880
    }
881
882
    /**
883
     * @group DBAL-2436
884
     */
885
    public function testQuotesDatabaseNameInListTableColumnsSQL()
886
    {
887
        self::assertContains("'Foo''Bar\\\\'", $this->platform->getListTableColumnsSQL('foo_table', "Foo'Bar\\"), '', true);
888
    }
889
890
    public function testListTableForeignKeysSQLEvaluatesDatabase()
891
    {
892
        $sql = $this->platform->getListTableForeignKeysSQL('foo');
893
894
        self::assertContains('DATABASE()', $sql);
895
896
        $sql = $this->platform->getListTableForeignKeysSQL('foo', 'bar');
897
898
        self::assertContains('bar', $sql);
899
        self::assertNotContains('DATABASE()', $sql);
900
    }
901
902
    public function testColumnCharsetDeclarationSQL() : void
903
    {
904
        self::assertSame(
905
            'CHARACTER SET ascii',
906
            $this->platform->getColumnCharsetDeclarationSQL('ascii')
907
        );
908
    }
909
910
    public function testSupportsColumnCollation() : void
911
    {
912
        self::assertTrue($this->platform->supportsColumnCollation());
913
    }
914
915
    public function testColumnCollationDeclarationSQL() : void
916
    {
917
        self::assertSame(
918
            'COLLATE ascii_general_ci',
919
            $this->platform->getColumnCollationDeclarationSQL('ascii_general_ci')
920
        );
921
    }
922
923
    public function testGetCreateTableSQLWithColumnCollation() : void
924
    {
925
        $table = new Table('foo');
926
        $table->addColumn('no_collation', 'string');
927
        $table->addColumn('column_collation', 'string')->setPlatformOption('collation', 'ascii_general_ci');
928
929
        self::assertSame(
930
            ['CREATE TABLE foo (no_collation VARCHAR(255) NOT NULL, column_collation VARCHAR(255) NOT NULL COLLATE ascii_general_ci) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'],
931
            $this->platform->getCreateTableSQL($table),
932
            'Column "no_collation" will use the default collation from the table/database and "column_collation" overwrites the collation on this column'
933
        );
934
    }
935
}
936