DB2PlatformTest   F
last analyzed

Complexity

Total Complexity 63

Size/Duplication

Total Lines 724
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 301
dl 0
loc 724
rs 3.36
c 0
b 0
f 0
wmc 63

61 Methods

Rating   Name   Duplication   Size   Complexity  
A testDoesNotSupportCreateDropDatabase() 0 3 1
A testDoesNotSupportSavePoints() 0 3 1
A testDoesNotSupportReleasePoints() 0 3 1
A testModifiesLimitQuery() 0 24 1
A testPrefersIdentityColumns() 0 3 1
A testReturnsSQLResultCasing() 0 3 1
A testSupportsIdentityColumns() 0 3 1
A testGeneratesCreateTableSQLWithCommonIndexes() 0 16 1
A testGeneratesColumnTypesDeclarationSQL() 0 25 1
A getGenerateForeignKeySql() 0 3 1
A getQuotedColumnInPrimaryKeySQL() 0 3 1
A testGeneratesCreateTableSQLWithForeignKeyConstraints() 0 23 1
A getExpectedVariableLengthBinaryTypeDeclarationSQLNoLength() 0 3 1
A getAlterStringToFixedStringSQL() 0 5 1
A testGeneratesSQLSnippets() 0 27 1
A getQuotedColumnInForeignKeySQL() 0 7 1
A getBitAndComparisonExpressionSql() 0 3 1
A testQuotesTableNameInListTableColumnsSQL() 0 5 1
A getGenerateIndexSql() 0 3 1
A getIsCommentedDoctrineType() 0 11 2
A getQuotedAlterTableChangeColumnLengthSQL() 0 3 1
A getQuotedAlterTableRenameColumnSQL() 0 12 1
A testGetVariableLengthBinaryTypeDeclarationSQLNoLength() 0 5 1
A getExpectedFixedLengthBinaryTypeDeclarationSQLWithLength() 0 3 1
A testHasCorrectPlatformName() 0 3 1
A testReturnsGuidTypeDeclarationSQL() 0 3 1
A testInitializesDoctrineTypeMappings() 0 42 1
A getAlterTableRenameIndexInSchemaSQL() 0 3 1
A getBitOrComparisonExpressionSql() 0 3 1
A getGenerateUniqueIndexSql() 0 3 1
A getQuotedNameInIndexSQL() 0 5 1
A testQuotesTableNameInListTableForeignKeysSQL() 0 5 1
A getQuotedColumnInIndexSQL() 0 5 1
A supportsCommentOnStatement() 0 3 1
A testGeneratesCreateUnnamedPrimaryKeySQL() 0 7 1
A testGetVariableLengthStringTypeDeclarationSQLNoLength() 0 5 1
A getCreateTableColumnTypeCommentsSQL() 0 5 1
A getQuotesTableIdentifiersInAlterTableSQL() 0 14 1
A getExpectedVariableLengthBinaryTypeDeclarationSQLWithLength() 0 3 1
A getAlterTableColumnCommentsSQL() 0 9 1
A getGenerateTableSql() 0 3 1
A testGeneratesDDLSnippets() 0 10 1
A getGeneratesAlterColumnSQL() 0 57 1
A getGenerateAlterTableSql() 0 14 1
A getQuotedAlterTableRenameIndexSQL() 0 5 1
A getQuotesReservedKeywordInUniqueConstraintDeclarationSQL() 0 3 1
A getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() 0 3 1
A getExpectedFixedLengthBinaryTypeDeclarationSQLNoLength() 0 3 1
A getCreateTableColumnCommentsSQL() 0 5 1
A testGeneratesCreateTableSQLWithCheckConstraints() 0 11 1
A getCommentOnColumnSQL() 0 6 1
A testQuotesTableNameInListTableIndexesSQL() 0 5 1
A createPlatform() 0 3 1
A getQuotesReservedKeywordInTruncateTableSQL() 0 3 1
A getAlterTableRenameIndexSQL() 0 3 1
A supportsInlineIndexDeclaration() 0 3 1
A getAlterTableRenameColumnSQL() 0 3 1
A getGenerateTableWithMultiColumnUniqueIndexSql() 0 5 1
A getQuotesReservedKeywordInIndexDeclarationSQL() 0 3 1
A getQuotedAlterTableRenameIndexInSchemaSQL() 0 5 1
A testGeneratesAlterColumnSQL() 0 15 2

How to fix   Complexity   

Complex Class

Complex classes like DB2PlatformTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DB2PlatformTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Tests\Platforms;
6
7
use Doctrine\DBAL\Exception\ColumnLengthRequired;
8
use Doctrine\DBAL\Platforms\AbstractPlatform;
9
use Doctrine\DBAL\Platforms\DB2Platform;
10
use Doctrine\DBAL\Schema\Column;
11
use Doctrine\DBAL\Schema\ColumnDiff;
12
use Doctrine\DBAL\Schema\Index;
13
use Doctrine\DBAL\Schema\Table;
14
use Doctrine\DBAL\Schema\TableDiff;
15
use Doctrine\DBAL\Types\Type;
16
use Doctrine\DBAL\Types\Types;
17
18
class DB2PlatformTest extends AbstractPlatformTestCase
19
{
20
    /** @var DB2Platform */
21
    protected $platform;
22
23
    public function createPlatform() : AbstractPlatform
24
    {
25
        return new DB2Platform();
26
    }
27
28
    /**
29
     * {@inheritDoc}
30
     */
31
    public function getGenerateAlterTableSql() : array
32
    {
33
        return [
34
            'ALTER TABLE mytable ALTER COLUMN baz SET DATA TYPE VARCHAR(255)',
35
            'ALTER TABLE mytable ALTER COLUMN baz SET NOT NULL',
36
            "ALTER TABLE mytable ALTER COLUMN baz SET DEFAULT 'def'",
37
            'ALTER TABLE mytable ALTER COLUMN bloo SET DATA TYPE SMALLINT',
38
            'ALTER TABLE mytable ALTER COLUMN bloo SET NOT NULL',
39
            "ALTER TABLE mytable ALTER COLUMN bloo SET DEFAULT '0'",
40
            'ALTER TABLE mytable ' .
41
            'ADD COLUMN quota INTEGER DEFAULT NULL ' .
42
            'DROP COLUMN foo',
43
            "CALL SYSPROC.ADMIN_CMD ('REORG TABLE mytable')",
44
            'RENAME TABLE mytable TO userlist',
45
        ];
46
    }
47
48
    public function getGenerateForeignKeySql() : string
49
    {
50
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
51
    }
52
53
    public function getGenerateIndexSql() : string
54
    {
55
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
56
    }
57
58
    public function getGenerateTableSql() : string
59
    {
60
        return 'CREATE TABLE test (id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))';
61
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66
    public function getGenerateTableWithMultiColumnUniqueIndexSql() : array
67
    {
68
        return [
69
            'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)',
70
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)',
71
        ];
72
    }
73
74
    public function getGenerateUniqueIndexSql() : string
75
    {
76
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
77
    }
78
79
    /**
80
     * {@inheritDoc}
81
     */
82
    protected function getQuotedColumnInForeignKeySQL() : array
83
    {
84
        return [
85
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL)',
86
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES "foreign" ("create", bar, "foo-bar")',
87
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foo ("create", bar, "foo-bar")',
88
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar")',
89
        ];
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95
    protected function getQuotedColumnInIndexSQL() : array
96
    {
97
        return [
98
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)',
99
            'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")',
100
        ];
101
    }
102
103
    /**
104
     * {@inheritDoc}
105
     */
106
    protected function getQuotedNameInIndexSQL() : array
107
    {
108
        return [
109
            'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)',
110
            'CREATE INDEX "key" ON test (column1)',
111
        ];
112
    }
113
114
    /**
115
     * {@inheritDoc}
116
     */
117
    protected function getQuotedColumnInPrimaryKeySQL() : array
118
    {
119
        return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, PRIMARY KEY("create"))'];
120
    }
121
122
    protected function getBitAndComparisonExpressionSql(string $value1, string $value2) : string
123
    {
124
        return 'BITAND(' . $value1 . ', ' . $value2 . ')';
125
    }
126
127
    protected function getBitOrComparisonExpressionSql(string $value1, string $value2) : string
128
    {
129
        return 'BITOR(' . $value1 . ', ' . $value2 . ')';
130
    }
131
132
    /**
133
     * {@inheritDoc}
134
     */
135
    public function getCreateTableColumnCommentsSQL() : array
136
    {
137
        return [
138
            'CREATE TABLE test (id INTEGER NOT NULL, PRIMARY KEY(id))',
139
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
140
        ];
141
    }
142
143
    /**
144
     * {@inheritDoc}
145
     */
146
    public function getAlterTableColumnCommentsSQL() : array
147
    {
148
        return [
149
            'ALTER TABLE mytable ' .
150
            'ADD COLUMN quota INTEGER NOT NULL WITH DEFAULT',
151
            "CALL SYSPROC.ADMIN_CMD ('REORG TABLE mytable')",
152
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
153
            "COMMENT ON COLUMN mytable.foo IS ''",
154
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
155
        ];
156
    }
157
158
    /**
159
     * {@inheritDoc}
160
     */
161
    public function getCreateTableColumnTypeCommentsSQL() : array
162
    {
163
        return [
164
            'CREATE TABLE test (id INTEGER NOT NULL, "data" CLOB(1M) NOT NULL, PRIMARY KEY(id))',
165
            'COMMENT ON COLUMN test."data" IS \'(DC2Type:array)\'',
166
        ];
167
    }
168
169
    public function testHasCorrectPlatformName() : void
170
    {
171
        self::assertEquals('db2', $this->platform->getName());
172
    }
173
174
    public function testGeneratesCreateTableSQLWithCommonIndexes() : void
175
    {
176
        $table = new Table('test');
177
        $table->addColumn('id', 'integer');
178
        $table->addColumn('name', 'string', ['length' => 50]);
179
        $table->setPrimaryKey(['id']);
180
        $table->addIndex(['name']);
181
        $table->addIndex(['id', 'name'], 'composite_idx');
182
183
        self::assertEquals(
184
            [
185
                'CREATE TABLE test (id INTEGER NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id))',
186
                'CREATE INDEX IDX_D87F7E0C5E237E06 ON test (name)',
187
                'CREATE INDEX composite_idx ON test (id, name)',
188
            ],
189
            $this->platform->getCreateTableSQL($table)
190
        );
191
    }
192
193
    public function testGeneratesCreateTableSQLWithForeignKeyConstraints() : void
194
    {
195
        $table = new Table('test');
196
        $table->addColumn('id', 'integer');
197
        $table->addColumn('fk_1', 'integer');
198
        $table->addColumn('fk_2', 'integer');
199
        $table->setPrimaryKey(['id']);
200
        $table->addForeignKeyConstraint('foreign_table', ['fk_1', 'fk_2'], ['pk_1', 'pk_2']);
201
        $table->addForeignKeyConstraint(
202
            'foreign_table2',
203
            ['fk_1', 'fk_2'],
204
            ['pk_1', 'pk_2'],
205
            [],
206
            'named_fk'
207
        );
208
209
        self::assertEquals(
210
            [
211
                'CREATE TABLE test (id INTEGER NOT NULL, fk_1 INTEGER NOT NULL, fk_2 INTEGER NOT NULL)',
212
                'ALTER TABLE test ADD CONSTRAINT FK_D87F7E0C177612A38E7F4319 FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table (pk_1, pk_2)',
213
                'ALTER TABLE test ADD CONSTRAINT named_fk FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table2 (pk_1, pk_2)',
214
            ],
215
            $this->platform->getCreateTableSQL($table, AbstractPlatform::CREATE_FOREIGNKEYS)
216
        );
217
    }
218
219
    public function testGeneratesCreateTableSQLWithCheckConstraints() : void
220
    {
221
        $table = new Table('test');
222
        $table->addColumn('id', 'integer');
223
        $table->addColumn('check_max', 'integer', ['platformOptions' => ['max' => 10]]);
224
        $table->addColumn('check_min', 'integer', ['platformOptions' => ['min' => 10]]);
225
        $table->setPrimaryKey(['id']);
226
227
        self::assertEquals(
228
            ['CREATE TABLE test (id INTEGER NOT NULL, check_max INTEGER NOT NULL, check_min INTEGER NOT NULL, PRIMARY KEY(id), CHECK (check_max <= 10), CHECK (check_min >= 10))'],
229
            $this->platform->getCreateTableSQL($table)
230
        );
231
    }
232
233
    public function testGeneratesColumnTypesDeclarationSQL() : void
234
    {
235
        $fullColumnDef = [
236
            'length' => 10,
237
            'fixed' => true,
238
            'unsigned' => true,
239
            'autoincrement' => true,
240
        ];
241
242
        self::assertEquals('SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL([]));
243
        self::assertEquals('SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL(['unsigned' => true]));
244
        self::assertEquals('SMALLINT GENERATED BY DEFAULT AS IDENTITY', $this->platform->getSmallIntTypeDeclarationSQL($fullColumnDef));
245
        self::assertEquals('INTEGER', $this->platform->getIntegerTypeDeclarationSQL([]));
246
        self::assertEquals('INTEGER', $this->platform->getIntegerTypeDeclarationSQL(['unsigned' => true]));
247
        self::assertEquals('INTEGER GENERATED BY DEFAULT AS IDENTITY', $this->platform->getIntegerTypeDeclarationSQL($fullColumnDef));
248
        self::assertEquals('BIGINT', $this->platform->getBigIntTypeDeclarationSQL([]));
249
        self::assertEquals('BIGINT', $this->platform->getBigIntTypeDeclarationSQL(['unsigned' => true]));
250
        self::assertEquals('BIGINT GENERATED BY DEFAULT AS IDENTITY', $this->platform->getBigIntTypeDeclarationSQL($fullColumnDef));
251
        self::assertEquals('BLOB(1M)', $this->platform->getBlobTypeDeclarationSQL($fullColumnDef));
252
        self::assertEquals('SMALLINT', $this->platform->getBooleanTypeDeclarationSQL($fullColumnDef));
253
        self::assertEquals('CLOB(1M)', $this->platform->getClobTypeDeclarationSQL($fullColumnDef));
254
        self::assertEquals('DATE', $this->platform->getDateTypeDeclarationSQL($fullColumnDef));
255
        self::assertEquals('TIMESTAMP(0) WITH DEFAULT', $this->platform->getDateTimeTypeDeclarationSQL(['version' => true]));
256
        self::assertEquals('TIMESTAMP(0)', $this->platform->getDateTimeTypeDeclarationSQL($fullColumnDef));
257
        self::assertEquals('TIME', $this->platform->getTimeTypeDeclarationSQL($fullColumnDef));
258
    }
259
260
    public function testInitializesDoctrineTypeMappings() : void
261
    {
262
        $this->platform->initializeDoctrineTypeMappings();
263
264
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('smallint'));
265
        self::assertSame('smallint', $this->platform->getDoctrineTypeMapping('smallint'));
266
267
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('bigint'));
268
        self::assertSame('bigint', $this->platform->getDoctrineTypeMapping('bigint'));
269
270
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('integer'));
271
        self::assertSame('integer', $this->platform->getDoctrineTypeMapping('integer'));
272
273
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('time'));
274
        self::assertSame('time', $this->platform->getDoctrineTypeMapping('time'));
275
276
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('date'));
277
        self::assertSame('date', $this->platform->getDoctrineTypeMapping('date'));
278
279
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('varchar'));
280
        self::assertSame('string', $this->platform->getDoctrineTypeMapping('varchar'));
281
282
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('character'));
283
        self::assertSame('string', $this->platform->getDoctrineTypeMapping('character'));
284
285
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('clob'));
286
        self::assertSame('text', $this->platform->getDoctrineTypeMapping('clob'));
287
288
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('blob'));
289
        self::assertSame('blob', $this->platform->getDoctrineTypeMapping('blob'));
290
291
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('decimal'));
292
        self::assertSame('decimal', $this->platform->getDoctrineTypeMapping('decimal'));
293
294
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('double'));
295
        self::assertSame('float', $this->platform->getDoctrineTypeMapping('double'));
296
297
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('real'));
298
        self::assertSame('float', $this->platform->getDoctrineTypeMapping('real'));
299
300
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp'));
301
        self::assertSame('datetime', $this->platform->getDoctrineTypeMapping('timestamp'));
302
    }
303
304
    /**
305
     * {@inheritDoc}
306
     */
307
    public function getIsCommentedDoctrineType() : iterable
308
    {
309
        $types = [];
310
311
        foreach (parent::getIsCommentedDoctrineType() as $key => $value) {
312
            $types[$key] = $value;
313
        }
314
315
        $types[Types::BOOLEAN] = [Type::getType(Types::BOOLEAN), true];
316
317
        return $types;
318
    }
319
320
    public function testGeneratesDDLSnippets() : void
321
    {
322
        self::assertEquals('CREATE DATABASE foobar', $this->platform->getCreateDatabaseSQL('foobar'));
323
        self::assertEquals('DROP DATABASE foobar', $this->platform->getDropDatabaseSQL('foobar'));
324
        self::assertEquals('DECLARE GLOBAL TEMPORARY TABLE', $this->platform->getCreateTemporaryTableSnippetSQL());
325
        self::assertEquals('TRUNCATE foobar IMMEDIATE', $this->platform->getTruncateTableSQL('foobar'));
326
327
        $viewSql = 'SELECT * FROM footable';
328
        self::assertEquals('CREATE VIEW fooview AS ' . $viewSql, $this->platform->getCreateViewSQL('fooview', $viewSql));
329
        self::assertEquals('DROP VIEW fooview', $this->platform->getDropViewSQL('fooview'));
330
    }
331
332
    public function testGeneratesCreateUnnamedPrimaryKeySQL() : void
333
    {
334
        self::assertEquals(
335
            'ALTER TABLE foo ADD PRIMARY KEY (a, b)',
336
            $this->platform->getCreatePrimaryKeySQL(
337
                new Index('any_pk_name', ['a', 'b'], true, true),
338
                'foo'
339
            )
340
        );
341
    }
342
343
    public function testGeneratesSQLSnippets() : void
344
    {
345
        self::assertEquals('CURRENT DATE', $this->platform->getCurrentDateSQL());
346
        self::assertEquals('CURRENT TIME', $this->platform->getCurrentTimeSQL());
347
        self::assertEquals('CURRENT TIMESTAMP', $this->platform->getCurrentTimestampSQL());
348
        self::assertEquals("'1987/05/02' + 4 DAY", $this->platform->getDateAddDaysExpression("'1987/05/02'", '4'));
349
        self::assertEquals("'1987/05/02' + 12 HOUR", $this->platform->getDateAddHourExpression("'1987/05/02'", '12'));
350
        self::assertEquals("'1987/05/02' + 2 MINUTE", $this->platform->getDateAddMinutesExpression("'1987/05/02'", '2'));
351
        self::assertEquals("'1987/05/02' + 102 MONTH", $this->platform->getDateAddMonthExpression("'1987/05/02'", '102'));
352
        self::assertEquals("'1987/05/02' + (5 * 3) MONTH", $this->platform->getDateAddQuartersExpression("'1987/05/02'", '5'));
353
        self::assertEquals("'1987/05/02' + 1 SECOND", $this->platform->getDateAddSecondsExpression("'1987/05/02'", '1'));
354
        self::assertEquals("'1987/05/02' + (3 * 7) DAY", $this->platform->getDateAddWeeksExpression("'1987/05/02'", '3'));
355
        self::assertEquals("'1987/05/02' + 10 YEAR", $this->platform->getDateAddYearsExpression("'1987/05/02'", '10'));
356
        self::assertEquals("DAYS('1987/05/02') - DAYS('1987/04/01')", $this->platform->getDateDiffExpression("'1987/05/02'", "'1987/04/01'"));
357
        self::assertEquals("'1987/05/02' - 4 DAY", $this->platform->getDateSubDaysExpression("'1987/05/02'", '4'));
358
        self::assertEquals("'1987/05/02' - 12 HOUR", $this->platform->getDateSubHourExpression("'1987/05/02'", '12'));
359
        self::assertEquals("'1987/05/02' - 2 MINUTE", $this->platform->getDateSubMinutesExpression("'1987/05/02'", '2'));
360
        self::assertEquals("'1987/05/02' - 102 MONTH", $this->platform->getDateSubMonthExpression("'1987/05/02'", '102'));
361
        self::assertEquals("'1987/05/02' - (5 * 3) MONTH", $this->platform->getDateSubQuartersExpression("'1987/05/02'", '5'));
362
        self::assertEquals("'1987/05/02' - 1 SECOND", $this->platform->getDateSubSecondsExpression("'1987/05/02'", '1'));
363
        self::assertEquals("'1987/05/02' - (3 * 7) DAY", $this->platform->getDateSubWeeksExpression("'1987/05/02'", '3'));
364
        self::assertEquals("'1987/05/02' - 10 YEAR", $this->platform->getDateSubYearsExpression("'1987/05/02'", '10'));
365
        self::assertEquals(' WITH RR USE AND KEEP UPDATE LOCKS', $this->platform->getForUpdateSQL());
366
        self::assertEquals('LOCATE(substring_column, string_column)', $this->platform->getLocateExpression('string_column', 'substring_column'));
367
        self::assertEquals('LOCATE(substring_column, string_column, 1)', $this->platform->getLocateExpression('string_column', 'substring_column', '1'));
368
        self::assertEquals('SUBSTR(column, 5)', $this->platform->getSubstringExpression('column', '5'));
369
        self::assertEquals('SUBSTR(column, 5, 2)', $this->platform->getSubstringExpression('column', '5', '2'));
370
    }
371
372
    public function testModifiesLimitQuery() : void
373
    {
374
        self::assertEquals(
375
            'SELECT * FROM user',
376
            $this->platform->modifyLimitQuery('SELECT * FROM user', null, 0)
377
        );
378
379
        self::assertEquals(
380
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM <= 10',
381
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 0)
382
        );
383
384
        self::assertEquals(
385
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM <= 10',
386
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10)
387
        );
388
389
        self::assertEquals(
390
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM >= 6 AND db22.DC_ROWNUM <= 15',
391
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 5)
392
        );
393
        self::assertEquals(
394
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM >= 6 AND db22.DC_ROWNUM <= 5',
395
            $this->platform->modifyLimitQuery('SELECT * FROM user', 0, 5)
396
        );
397
    }
398
399
    public function testPrefersIdentityColumns() : void
400
    {
401
        self::assertTrue($this->platform->prefersIdentityColumns());
402
    }
403
404
    public function testSupportsIdentityColumns() : void
405
    {
406
        self::assertTrue($this->platform->supportsIdentityColumns());
407
    }
408
409
    public function testDoesNotSupportSavePoints() : void
410
    {
411
        self::assertFalse($this->platform->supportsSavepoints());
412
    }
413
414
    public function testDoesNotSupportReleasePoints() : void
415
    {
416
        self::assertFalse($this->platform->supportsReleaseSavepoints());
417
    }
418
419
    public function testDoesNotSupportCreateDropDatabase() : void
420
    {
421
        self::assertFalse($this->platform->supportsCreateDropDatabase());
422
    }
423
424
    public function testReturnsSQLResultCasing() : void
425
    {
426
        self::assertSame('COL', $this->platform->getSQLResultCasing('cOl'));
427
    }
428
429
    public function testGetVariableLengthStringTypeDeclarationSQLNoLength() : void
430
    {
431
        $this->expectException(ColumnLengthRequired::class);
432
433
        parent::testGetVariableLengthStringTypeDeclarationSQLNoLength();
434
    }
435
436
    public function getExpectedFixedLengthBinaryTypeDeclarationSQLNoLength() : string
437
    {
438
        return 'CHAR FOR BIT DATA';
439
    }
440
441
    public function getExpectedFixedLengthBinaryTypeDeclarationSQLWithLength() : string
442
    {
443
        return 'CHAR(16) FOR BIT DATA';
444
    }
445
446
    public function getExpectedVariableLengthBinaryTypeDeclarationSQLNoLength() : string
447
    {
448
        return 'CHAR(16) FOR BIT DATA';
449
    }
450
451
    public function testGetVariableLengthBinaryTypeDeclarationSQLNoLength() : void
452
    {
453
        $this->expectException(ColumnLengthRequired::class);
454
455
        parent::testGetVariableLengthBinaryTypeDeclarationSQLNoLength();
456
    }
457
458
    public function getExpectedVariableLengthBinaryTypeDeclarationSQLWithLength() : string
459
    {
460
        return 'VARCHAR(16) FOR BIT DATA';
461
    }
462
463
    /**
464
     * {@inheritDoc}
465
     *
466
     * @group DBAL-234
467
     */
468
    protected function getAlterTableRenameIndexSQL() : array
469
    {
470
        return ['RENAME INDEX idx_foo TO idx_bar'];
471
    }
472
473
    /**
474
     * {@inheritDoc}
475
     *
476
     * @group DBAL-234
477
     */
478
    protected function getQuotedAlterTableRenameIndexSQL() : array
479
    {
480
        return [
481
            'RENAME INDEX "create" TO "select"',
482
            'RENAME INDEX "foo" TO "bar"',
483
        ];
484
    }
485
486
    /**
487
     * {@inheritdoc}
488
     */
489
    protected function getQuotedAlterTableRenameColumnSQL() : array
490
    {
491
        return ['ALTER TABLE mytable ' .
492
            'RENAME COLUMN unquoted1 TO unquoted ' .
493
            'RENAME COLUMN unquoted2 TO "where" ' .
494
            'RENAME COLUMN unquoted3 TO "foo" ' .
495
            'RENAME COLUMN "create" TO reserved_keyword ' .
496
            'RENAME COLUMN "table" TO "from" ' .
497
            'RENAME COLUMN "select" TO "bar" ' .
498
            'RENAME COLUMN quoted1 TO quoted ' .
499
            'RENAME COLUMN quoted2 TO "and" ' .
500
            'RENAME COLUMN quoted3 TO "baz"',
501
        ];
502
    }
503
504
    /**
505
     * {@inheritdoc}
506
     */
507
    protected function getQuotedAlterTableChangeColumnLengthSQL() : array
508
    {
509
        self::markTestIncomplete('Not implemented yet');
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
510
    }
511
512
    /**
513
     * {@inheritDoc}
514
     *
515
     * @group DBAL-807
516
     */
517
    protected function getAlterTableRenameIndexInSchemaSQL() : array
518
    {
519
        return ['RENAME INDEX myschema.idx_foo TO idx_bar'];
520
    }
521
522
    /**
523
     * {@inheritDoc}
524
     *
525
     * @group DBAL-807
526
     */
527
    protected function getQuotedAlterTableRenameIndexInSchemaSQL() : array
528
    {
529
        return [
530
            'RENAME INDEX "schema"."create" TO "select"',
531
            'RENAME INDEX "schema"."foo" TO "bar"',
532
        ];
533
    }
534
535
    /**
536
     * @group DBAL-423
537
     */
538
    public function testReturnsGuidTypeDeclarationSQL() : void
539
    {
540
        self::assertSame('CHAR(36)', $this->platform->getGuidTypeDeclarationSQL([]));
541
    }
542
543
    /**
544
     * {@inheritdoc}
545
     */
546
    public function getAlterTableRenameColumnSQL() : array
547
    {
548
        return ['ALTER TABLE foo RENAME COLUMN bar TO baz'];
549
    }
550
551
    /**
552
     * {@inheritdoc}
553
     */
554
    protected function getQuotesTableIdentifiersInAlterTableSQL() : array
555
    {
556
        return [
557
            'ALTER TABLE "foo" DROP FOREIGN KEY fk1',
558
            'ALTER TABLE "foo" DROP FOREIGN KEY fk2',
559
            'ALTER TABLE "foo" ' .
560
            'ADD COLUMN bloo INTEGER NOT NULL WITH DEFAULT ' .
561
            'DROP COLUMN baz ' .
562
            'ALTER COLUMN bar DROP NOT NULL ' .
563
            'RENAME COLUMN id TO war',
564
            'CALL SYSPROC.ADMIN_CMD (\'REORG TABLE "foo"\')',
565
            'RENAME TABLE "foo" TO "table"',
566
            'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
567
            'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
568
        ];
569
    }
570
571
    /**
572
     * {@inheritdoc}
573
     */
574
    protected function getCommentOnColumnSQL() : array
575
    {
576
        return [
577
            'COMMENT ON COLUMN foo.bar IS \'comment\'',
578
            'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
579
            'COMMENT ON COLUMN "select"."from" IS \'comment\'',
580
        ];
581
    }
582
583
    /**
584
     * @group DBAL-944
585
     * @dataProvider getGeneratesAlterColumnSQL
586
     */
587
    public function testGeneratesAlterColumnSQL(string $changedProperty, Column $column, ?string $expectedSQLClause = null) : void
588
    {
589
        $tableDiff                        = new TableDiff('foo');
590
        $tableDiff->fromTable             = new Table('foo');
591
        $tableDiff->changedColumns['bar'] = new ColumnDiff('bar', $column, [$changedProperty]);
592
593
        $expectedSQL = [];
594
595
        if ($expectedSQLClause !== null) {
596
            $expectedSQL[] = 'ALTER TABLE foo ALTER COLUMN bar ' . $expectedSQLClause;
597
        }
598
599
        $expectedSQL[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE foo')";
600
601
        self::assertSame($expectedSQL, $this->platform->getAlterTableSQL($tableDiff));
602
    }
603
604
    /**
605
     * @return mixed[][]
606
     */
607
    public static function getGeneratesAlterColumnSQL() : iterable
608
    {
609
        return [
610
            [
611
                'columnDefinition',
612
                new Column('bar', Type::getType('decimal'), ['columnDefinition' => 'MONEY NOT NULL']),
613
                'MONEY NOT NULL',
614
            ],
615
            [
616
                'type',
617
                new Column('bar', Type::getType('integer')),
618
                'SET DATA TYPE INTEGER',
619
            ],
620
            [
621
                'length',
622
                new Column('bar', Type::getType('string'), ['length' => 100]),
623
                'SET DATA TYPE VARCHAR(100)',
624
            ],
625
            [
626
                'precision',
627
                new Column('bar', Type::getType('decimal'), ['precision' => 10, 'scale' => 2]),
628
                'SET DATA TYPE NUMERIC(10, 2)',
629
            ],
630
            [
631
                'scale',
632
                new Column('bar', Type::getType('decimal'), ['precision' => 5, 'scale' => 4]),
633
                'SET DATA TYPE NUMERIC(5, 4)',
634
            ],
635
            [
636
                'fixed',
637
                new Column('bar', Type::getType('string'), ['length' => 20, 'fixed' => true]),
638
                'SET DATA TYPE CHAR(20)',
639
            ],
640
            [
641
                'notnull',
642
                new Column('bar', Type::getType('string'), ['notnull' => true]),
643
                'SET NOT NULL',
644
            ],
645
            [
646
                'notnull',
647
                new Column('bar', Type::getType('string'), ['notnull' => false]),
648
                'DROP NOT NULL',
649
            ],
650
            [
651
                'default',
652
                new Column('bar', Type::getType('string'), ['default' => 'foo']),
653
                "SET DEFAULT 'foo'",
654
            ],
655
            [
656
                'default',
657
                new Column('bar', Type::getType('integer'), ['autoincrement' => true, 'default' => 666]),
658
                null,
659
            ],
660
            [
661
                'default',
662
                new Column('bar', Type::getType('string')),
663
                'DROP DEFAULT',
664
            ],
665
        ];
666
    }
667
668
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL() : string
669
    {
670
        return 'CONSTRAINT "select" UNIQUE (foo)';
671
    }
672
673
    protected function getQuotesReservedKeywordInIndexDeclarationSQL() : string
674
    {
675
        return ''; // not supported by this platform
676
    }
677
678
    protected function getQuotesReservedKeywordInTruncateTableSQL() : string
679
    {
680
        return 'TRUNCATE "select" IMMEDIATE';
681
    }
682
683
    protected function supportsInlineIndexDeclaration() : bool
684
    {
685
        return false;
686
    }
687
688
    protected function supportsCommentOnStatement() : bool
689
    {
690
        return true;
691
    }
692
693
    /**
694
     * {@inheritdoc}
695
     */
696
    protected function getAlterStringToFixedStringSQL() : array
697
    {
698
        return [
699
            'ALTER TABLE mytable ALTER COLUMN name SET DATA TYPE CHAR(2)',
700
            'CALL SYSPROC.ADMIN_CMD (\'REORG TABLE mytable\')',
701
        ];
702
    }
703
704
    /**
705
     * {@inheritdoc}
706
     */
707
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() : array
708
    {
709
        return ['RENAME INDEX idx_foo TO idx_foo_renamed'];
710
    }
711
712
    /**
713
     * @group DBAL-2436
714
     */
715
    public function testQuotesTableNameInListTableColumnsSQL() : void
716
    {
717
        self::assertStringContainsStringIgnoringCase(
718
            "'Foo''Bar\\'",
719
            $this->platform->getListTableColumnsSQL("Foo'Bar\\")
720
        );
721
    }
722
723
    /**
724
     * @group DBAL-2436
725
     */
726
    public function testQuotesTableNameInListTableIndexesSQL() : void
727
    {
728
        self::assertStringContainsStringIgnoringCase(
729
            "'Foo''Bar\\'",
730
            $this->platform->getListTableIndexesSQL("Foo'Bar\\")
731
        );
732
    }
733
734
    /**
735
     * @group DBAL-2436
736
     */
737
    public function testQuotesTableNameInListTableForeignKeysSQL() : void
738
    {
739
        self::assertStringContainsStringIgnoringCase(
740
            "'Foo''Bar\\'",
741
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\")
742
        );
743
    }
744
}
745