Failed Conditions
Pull Request — master (#3260)
by Michael
61:30
created

DB2PlatformTest   D

Complexity

Total Complexity 59

Size/Duplication

Total Lines 688
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 59
eloc 302
dl 0
loc 688
rs 4.08
c 0
b 0
f 0

58 Methods

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

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\Tests\DBAL\Platforms;
6
7
use Doctrine\DBAL\Platforms\AbstractPlatform;
8
use Doctrine\DBAL\Platforms\DB2Platform;
9
use Doctrine\DBAL\Schema\Column;
10
use Doctrine\DBAL\Schema\ColumnDiff;
11
use Doctrine\DBAL\Schema\Index;
12
use Doctrine\DBAL\Schema\Table;
13
use Doctrine\DBAL\Schema\TableDiff;
14
use Doctrine\DBAL\Types\Type;
15
use Doctrine\DBAL\Types\Types;
16
17
class DB2PlatformTest extends AbstractPlatformTestCase
18
{
19
    /** @var DB2Platform */
20
    protected $platform;
21
22
    public function createPlatform()
23
    {
24
        return new DB2Platform();
25
    }
26
27
    public function getGenerateAlterTableSql()
28
    {
29
        return [
30
            'ALTER TABLE mytable ALTER COLUMN baz SET DATA TYPE VARCHAR(255)',
31
            'ALTER TABLE mytable ALTER COLUMN baz SET NOT NULL',
32
            "ALTER TABLE mytable ALTER COLUMN baz SET DEFAULT 'def'",
33
            'ALTER TABLE mytable ALTER COLUMN bloo SET DATA TYPE SMALLINT',
34
            'ALTER TABLE mytable ALTER COLUMN bloo SET NOT NULL',
35
            "ALTER TABLE mytable ALTER COLUMN bloo SET DEFAULT '0'",
36
            'ALTER TABLE mytable ' .
37
            'ADD COLUMN quota INTEGER DEFAULT NULL ' .
38
            'DROP COLUMN foo',
39
            "CALL SYSPROC.ADMIN_CMD ('REORG TABLE mytable')",
40
            'RENAME TABLE mytable TO userlist',
41
        ];
42
    }
43
44
    public function getGenerateForeignKeySql()
45
    {
46
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
47
    }
48
49
    public function getGenerateIndexSql()
50
    {
51
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
52
    }
53
54
    public function getGenerateTableSql()
55
    {
56
        return 'CREATE TABLE test (id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))';
57
    }
58
59
    public function getGenerateTableWithMultiColumnUniqueIndexSql()
60
    {
61
        return [
62
            'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)',
63
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)',
64
        ];
65
    }
66
67
    public function getGenerateUniqueIndexSql()
68
    {
69
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
70
    }
71
72
    protected function getQuotedColumnInForeignKeySQL()
73
    {
74
        return [
75
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL)',
76
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES "foreign" ("create", bar, "foo-bar")',
77
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foo ("create", bar, "foo-bar")',
78
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar")',
79
        ];
80
    }
81
82
    protected function getQuotedColumnInIndexSQL()
83
    {
84
        return [
85
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)',
86
            'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")',
87
        ];
88
    }
89
90
    protected function getQuotedNameInIndexSQL()
91
    {
92
        return [
93
            'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)',
94
            'CREATE INDEX "key" ON test (column1)',
95
        ];
96
    }
97
98
    protected function getQuotedColumnInPrimaryKeySQL()
99
    {
100
        return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, PRIMARY KEY("create"))'];
101
    }
102
103
    protected function getBitAndComparisonExpressionSql($value1, $value2)
104
    {
105
        return 'BITAND(' . $value1 . ', ' . $value2 . ')';
106
    }
107
108
    protected function getBitOrComparisonExpressionSql($value1, $value2)
109
    {
110
        return 'BITOR(' . $value1 . ', ' . $value2 . ')';
111
    }
112
113
    public function getCreateTableColumnCommentsSQL()
114
    {
115
        return [
116
            'CREATE TABLE test (id INTEGER NOT NULL, PRIMARY KEY(id))',
117
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
118
        ];
119
    }
120
121
    public function getAlterTableColumnCommentsSQL()
122
    {
123
        return [
124
            'ALTER TABLE mytable ' .
125
            'ADD COLUMN quota INTEGER NOT NULL WITH DEFAULT',
126
            "CALL SYSPROC.ADMIN_CMD ('REORG TABLE mytable')",
127
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
128
            "COMMENT ON COLUMN mytable.foo IS ''",
129
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
130
        ];
131
    }
132
133
    public function getCreateTableColumnTypeCommentsSQL()
134
    {
135
        return [
136
            'CREATE TABLE test (id INTEGER NOT NULL, "data" CLOB(1M) NOT NULL, PRIMARY KEY(id))',
137
            'COMMENT ON COLUMN test."data" IS \'(DC2Type:array)\'',
138
        ];
139
    }
140
141
    public function testHasCorrectPlatformName()
142
    {
143
        self::assertEquals('db2', $this->platform->getName());
144
    }
145
146
    public function testGeneratesCreateTableSQLWithCommonIndexes()
147
    {
148
        $table = new Table('test');
149
        $table->addColumn('id', 'integer');
150
        $table->addColumn('name', 'string', ['length' => 50]);
151
        $table->setPrimaryKey(['id']);
152
        $table->addIndex(['name']);
153
        $table->addIndex(['id', 'name'], 'composite_idx');
154
155
        self::assertEquals(
156
            [
157
                'CREATE TABLE test (id INTEGER NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id))',
158
                'CREATE INDEX IDX_D87F7E0C5E237E06 ON test (name)',
159
                'CREATE INDEX composite_idx ON test (id, name)',
160
            ],
161
            $this->platform->getCreateTableSQL($table)
162
        );
163
    }
164
165
    public function testGeneratesCreateTableSQLWithForeignKeyConstraints()
166
    {
167
        $table = new Table('test');
168
        $table->addColumn('id', 'integer');
169
        $table->addColumn('fk_1', 'integer');
170
        $table->addColumn('fk_2', 'integer');
171
        $table->setPrimaryKey(['id']);
172
        $table->addForeignKeyConstraint('foreign_table', ['fk_1', 'fk_2'], ['pk_1', 'pk_2']);
173
        $table->addForeignKeyConstraint(
174
            'foreign_table2',
175
            ['fk_1', 'fk_2'],
176
            ['pk_1', 'pk_2'],
177
            [],
178
            'named_fk'
179
        );
180
181
        self::assertEquals(
182
            [
183
                'CREATE TABLE test (id INTEGER NOT NULL, fk_1 INTEGER NOT NULL, fk_2 INTEGER NOT NULL)',
184
                'ALTER TABLE test ADD CONSTRAINT FK_D87F7E0C177612A38E7F4319 FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table (pk_1, pk_2)',
185
                'ALTER TABLE test ADD CONSTRAINT named_fk FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table2 (pk_1, pk_2)',
186
            ],
187
            $this->platform->getCreateTableSQL($table, AbstractPlatform::CREATE_FOREIGNKEYS)
188
        );
189
    }
190
191
    public function testGeneratesCreateTableSQLWithCheckConstraints()
192
    {
193
        $table = new Table('test');
194
        $table->addColumn('id', 'integer');
195
        $table->addColumn('check_max', 'integer', ['platformOptions' => ['max' => 10]]);
196
        $table->addColumn('check_min', 'integer', ['platformOptions' => ['min' => 10]]);
197
        $table->setPrimaryKey(['id']);
198
199
        self::assertEquals(
200
            ['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))'],
201
            $this->platform->getCreateTableSQL($table)
202
        );
203
    }
204
205
    public function testGeneratesColumnTypesDeclarationSQL()
206
    {
207
        $fullColumnDef = [
208
            'length' => 10,
209
            'fixed' => true,
210
            'unsigned' => true,
211
            'autoincrement' => true,
212
        ];
213
214
        self::assertEquals('VARCHAR(255)', $this->platform->getVarcharTypeDeclarationSQL([]));
215
        self::assertEquals('VARCHAR(10)', $this->platform->getVarcharTypeDeclarationSQL(['length' => 10]));
216
        self::assertEquals('CHAR(254)', $this->platform->getVarcharTypeDeclarationSQL(['fixed' => true]));
217
        self::assertEquals('CHAR(10)', $this->platform->getVarcharTypeDeclarationSQL($fullColumnDef));
218
219
        self::assertEquals('SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL([]));
220
        self::assertEquals('SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL(['unsigned' => true]));
221
        self::assertEquals('SMALLINT GENERATED BY DEFAULT AS IDENTITY', $this->platform->getSmallIntTypeDeclarationSQL($fullColumnDef));
222
        self::assertEquals('INTEGER', $this->platform->getIntegerTypeDeclarationSQL([]));
223
        self::assertEquals('INTEGER', $this->platform->getIntegerTypeDeclarationSQL(['unsigned' => true]));
224
        self::assertEquals('INTEGER GENERATED BY DEFAULT AS IDENTITY', $this->platform->getIntegerTypeDeclarationSQL($fullColumnDef));
225
        self::assertEquals('BIGINT', $this->platform->getBigIntTypeDeclarationSQL([]));
226
        self::assertEquals('BIGINT', $this->platform->getBigIntTypeDeclarationSQL(['unsigned' => true]));
227
        self::assertEquals('BIGINT GENERATED BY DEFAULT AS IDENTITY', $this->platform->getBigIntTypeDeclarationSQL($fullColumnDef));
228
        self::assertEquals('BLOB(1M)', $this->platform->getBlobTypeDeclarationSQL($fullColumnDef));
229
        self::assertEquals('SMALLINT', $this->platform->getBooleanTypeDeclarationSQL($fullColumnDef));
230
        self::assertEquals('CLOB(1M)', $this->platform->getClobTypeDeclarationSQL($fullColumnDef));
231
        self::assertEquals('DATE', $this->platform->getDateTypeDeclarationSQL($fullColumnDef));
232
        self::assertEquals('TIMESTAMP(0) WITH DEFAULT', $this->platform->getDateTimeTypeDeclarationSQL(['version' => true]));
233
        self::assertEquals('TIMESTAMP(0)', $this->platform->getDateTimeTypeDeclarationSQL($fullColumnDef));
234
        self::assertEquals('TIME', $this->platform->getTimeTypeDeclarationSQL($fullColumnDef));
235
    }
236
237
    public function testInitializesDoctrineTypeMappings()
238
    {
239
        $this->platform->initializeDoctrineTypeMappings();
240
241
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('smallint'));
242
        self::assertSame('smallint', $this->platform->getDoctrineTypeMapping('smallint'));
243
244
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('bigint'));
245
        self::assertSame('bigint', $this->platform->getDoctrineTypeMapping('bigint'));
246
247
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('integer'));
248
        self::assertSame('integer', $this->platform->getDoctrineTypeMapping('integer'));
249
250
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('time'));
251
        self::assertSame('time', $this->platform->getDoctrineTypeMapping('time'));
252
253
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('date'));
254
        self::assertSame('date', $this->platform->getDoctrineTypeMapping('date'));
255
256
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('varchar'));
257
        self::assertSame('string', $this->platform->getDoctrineTypeMapping('varchar'));
258
259
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('character'));
260
        self::assertSame('string', $this->platform->getDoctrineTypeMapping('character'));
261
262
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('clob'));
263
        self::assertSame('text', $this->platform->getDoctrineTypeMapping('clob'));
264
265
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('blob'));
266
        self::assertSame('blob', $this->platform->getDoctrineTypeMapping('blob'));
267
268
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('decimal'));
269
        self::assertSame('decimal', $this->platform->getDoctrineTypeMapping('decimal'));
270
271
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('double'));
272
        self::assertSame('float', $this->platform->getDoctrineTypeMapping('double'));
273
274
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('real'));
275
        self::assertSame('float', $this->platform->getDoctrineTypeMapping('real'));
276
277
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp'));
278
        self::assertSame('datetime', $this->platform->getDoctrineTypeMapping('timestamp'));
279
    }
280
281
    public function getIsCommentedDoctrineType()
282
    {
283
        $data = parent::getIsCommentedDoctrineType();
284
285
        $data[Types::BOOLEAN] = [Type::getType(Types::BOOLEAN), true];
286
287
        return $data;
288
    }
289
290
    public function testGeneratesDDLSnippets()
291
    {
292
        self::assertEquals('CREATE DATABASE foobar', $this->platform->getCreateDatabaseSQL('foobar'));
293
        self::assertEquals('DROP DATABASE foobar', $this->platform->getDropDatabaseSQL('foobar'));
294
        self::assertEquals('DECLARE GLOBAL TEMPORARY TABLE', $this->platform->getCreateTemporaryTableSnippetSQL());
295
        self::assertEquals('TRUNCATE foobar IMMEDIATE', $this->platform->getTruncateTableSQL('foobar'));
296
297
        $viewSql = 'SELECT * FROM footable';
298
        self::assertEquals('CREATE VIEW fooview AS ' . $viewSql, $this->platform->getCreateViewSQL('fooview', $viewSql));
299
        self::assertEquals('DROP VIEW fooview', $this->platform->getDropViewSQL('fooview'));
300
    }
301
302
    public function testGeneratesCreateUnnamedPrimaryKeySQL()
303
    {
304
        self::assertEquals(
305
            'ALTER TABLE foo ADD PRIMARY KEY (a, b)',
306
            $this->platform->getCreatePrimaryKeySQL(
307
                new Index('any_pk_name', ['a', 'b'], true, true),
308
                'foo'
309
            )
310
        );
311
    }
312
313
    public function testGeneratesSQLSnippets()
314
    {
315
        self::assertEquals('CURRENT DATE', $this->platform->getCurrentDateSQL());
316
        self::assertEquals('CURRENT TIME', $this->platform->getCurrentTimeSQL());
317
        self::assertEquals('CURRENT TIMESTAMP', $this->platform->getCurrentTimestampSQL());
318
        self::assertEquals("'1987/05/02' + 4 DAY", $this->platform->getDateAddDaysExpression("'1987/05/02'", '4'));
319
        self::assertEquals("'1987/05/02' + 12 HOUR", $this->platform->getDateAddHourExpression("'1987/05/02'", '12'));
320
        self::assertEquals("'1987/05/02' + 2 MINUTE", $this->platform->getDateAddMinutesExpression("'1987/05/02'", '2'));
321
        self::assertEquals("'1987/05/02' + 102 MONTH", $this->platform->getDateAddMonthExpression("'1987/05/02'", '102'));
322
        self::assertEquals("'1987/05/02' + (5 * 3) MONTH", $this->platform->getDateAddQuartersExpression("'1987/05/02'", '5'));
323
        self::assertEquals("'1987/05/02' + 1 SECOND", $this->platform->getDateAddSecondsExpression("'1987/05/02'", '1'));
324
        self::assertEquals("'1987/05/02' + (3 * 7) DAY", $this->platform->getDateAddWeeksExpression("'1987/05/02'", '3'));
325
        self::assertEquals("'1987/05/02' + 10 YEAR", $this->platform->getDateAddYearsExpression("'1987/05/02'", '10'));
326
        self::assertEquals("DAYS('1987/05/02') - DAYS('1987/04/01')", $this->platform->getDateDiffExpression("'1987/05/02'", "'1987/04/01'"));
327
        self::assertEquals("'1987/05/02' - 4 DAY", $this->platform->getDateSubDaysExpression("'1987/05/02'", '4'));
328
        self::assertEquals("'1987/05/02' - 12 HOUR", $this->platform->getDateSubHourExpression("'1987/05/02'", '12'));
329
        self::assertEquals("'1987/05/02' - 2 MINUTE", $this->platform->getDateSubMinutesExpression("'1987/05/02'", '2'));
330
        self::assertEquals("'1987/05/02' - 102 MONTH", $this->platform->getDateSubMonthExpression("'1987/05/02'", '102'));
331
        self::assertEquals("'1987/05/02' - (5 * 3) MONTH", $this->platform->getDateSubQuartersExpression("'1987/05/02'", '5'));
332
        self::assertEquals("'1987/05/02' - 1 SECOND", $this->platform->getDateSubSecondsExpression("'1987/05/02'", '1'));
333
        self::assertEquals("'1987/05/02' - (3 * 7) DAY", $this->platform->getDateSubWeeksExpression("'1987/05/02'", '3'));
334
        self::assertEquals("'1987/05/02' - 10 YEAR", $this->platform->getDateSubYearsExpression("'1987/05/02'", '10'));
335
        self::assertEquals(' WITH RR USE AND KEEP UPDATE LOCKS', $this->platform->getForUpdateSQL());
336
        self::assertEquals('LOCATE(substring_column, string_column)', $this->platform->getLocateExpression('string_column', 'substring_column'));
337
        self::assertEquals('LOCATE(substring_column, string_column, 1)', $this->platform->getLocateExpression('string_column', 'substring_column', '1'));
338
        self::assertEquals('SUBSTR(column, 5)', $this->platform->getSubstringExpression('column', '5'));
339
        self::assertEquals('SUBSTR(column, 5, 2)', $this->platform->getSubstringExpression('column', '5', '2'));
340
    }
341
342
    public function testModifiesLimitQuery()
343
    {
344
        self::assertEquals(
345
            'SELECT * FROM user',
346
            $this->platform->modifyLimitQuery('SELECT * FROM user', null, 0)
347
        );
348
349
        self::assertEquals(
350
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM <= 10',
351
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 0)
352
        );
353
354
        self::assertEquals(
355
            'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM <= 10',
356
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10)
357
        );
358
359
        self::assertEquals(
360
            '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',
361
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 5)
362
        );
363
        self::assertEquals(
364
            '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',
365
            $this->platform->modifyLimitQuery('SELECT * FROM user', 0, 5)
366
        );
367
    }
368
369
    public function testPrefersIdentityColumns()
370
    {
371
        self::assertTrue($this->platform->prefersIdentityColumns());
372
    }
373
374
    public function testSupportsIdentityColumns()
375
    {
376
        self::assertTrue($this->platform->supportsIdentityColumns());
377
    }
378
379
    public function testDoesNotSupportSavePoints()
380
    {
381
        self::assertFalse($this->platform->supportsSavepoints());
382
    }
383
384
    public function testDoesNotSupportReleasePoints()
385
    {
386
        self::assertFalse($this->platform->supportsReleaseSavepoints());
387
    }
388
389
    public function testDoesNotSupportCreateDropDatabase()
390
    {
391
        self::assertFalse($this->platform->supportsCreateDropDatabase());
392
    }
393
394
    public function testReturnsSQLResultCasing()
395
    {
396
        self::assertSame('COL', $this->platform->getSQLResultCasing('cOl'));
397
    }
398
399
    protected function getBinaryDefaultLength()
400
    {
401
        return 1;
402
    }
403
404
    protected function getBinaryMaxLength()
405
    {
406
        return 32704;
407
    }
408
409
    public function testReturnsBinaryTypeDeclarationSQL()
410
    {
411
        self::assertSame('VARCHAR(1) FOR BIT DATA', $this->platform->getBinaryTypeDeclarationSQL([]));
412
        self::assertSame('VARCHAR(255) FOR BIT DATA', $this->platform->getBinaryTypeDeclarationSQL(['length' => 0]));
413
        self::assertSame('VARCHAR(32704) FOR BIT DATA', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32704]));
414
415
        self::assertSame('CHAR(1) FOR BIT DATA', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
416
        self::assertSame('CHAR(254) FOR BIT DATA', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
417
    }
418
419
    /**
420
     * @group DBAL-234
421
     */
422
    protected function getAlterTableRenameIndexSQL()
423
    {
424
        return ['RENAME INDEX idx_foo TO idx_bar'];
425
    }
426
427
    /**
428
     * @group DBAL-234
429
     */
430
    protected function getQuotedAlterTableRenameIndexSQL()
431
    {
432
        return [
433
            'RENAME INDEX "create" TO "select"',
434
            'RENAME INDEX "foo" TO "bar"',
435
        ];
436
    }
437
438
    /**
439
     * {@inheritdoc}
440
     */
441
    protected function getQuotedAlterTableRenameColumnSQL()
442
    {
443
        return ['ALTER TABLE mytable ' .
444
            'RENAME COLUMN unquoted1 TO unquoted ' .
445
            'RENAME COLUMN unquoted2 TO "where" ' .
446
            'RENAME COLUMN unquoted3 TO "foo" ' .
447
            'RENAME COLUMN "create" TO reserved_keyword ' .
448
            'RENAME COLUMN "table" TO "from" ' .
449
            'RENAME COLUMN "select" TO "bar" ' .
450
            'RENAME COLUMN quoted1 TO quoted ' .
451
            'RENAME COLUMN quoted2 TO "and" ' .
452
            'RENAME COLUMN quoted3 TO "baz"',
453
        ];
454
    }
455
456
    /**
457
     * {@inheritdoc}
458
     */
459
    protected function getQuotedAlterTableChangeColumnLengthSQL()
460
    {
461
        $this->markTestIncomplete('Not implemented yet');
462
    }
463
464
    /**
465
     * @group DBAL-807
466
     */
467
    protected function getAlterTableRenameIndexInSchemaSQL()
468
    {
469
        return ['RENAME INDEX myschema.idx_foo TO idx_bar'];
470
    }
471
472
    /**
473
     * @group DBAL-807
474
     */
475
    protected function getQuotedAlterTableRenameIndexInSchemaSQL()
476
    {
477
        return [
478
            'RENAME INDEX "schema"."create" TO "select"',
479
            'RENAME INDEX "schema"."foo" TO "bar"',
480
        ];
481
    }
482
483
    /**
484
     * @group DBAL-423
485
     */
486
    public function testReturnsGuidTypeDeclarationSQL()
487
    {
488
        self::assertSame('CHAR(36)', $this->platform->getGuidTypeDeclarationSQL([]));
489
    }
490
491
    /**
492
     * {@inheritdoc}
493
     */
494
    public function getAlterTableRenameColumnSQL()
495
    {
496
        return ['ALTER TABLE foo RENAME COLUMN bar TO baz'];
497
    }
498
499
    /**
500
     * {@inheritdoc}
501
     */
502
    protected function getQuotesTableIdentifiersInAlterTableSQL()
503
    {
504
        return [
505
            'ALTER TABLE "foo" DROP FOREIGN KEY fk1',
506
            'ALTER TABLE "foo" DROP FOREIGN KEY fk2',
507
            'ALTER TABLE "foo" ' .
508
            'ADD COLUMN bloo INTEGER NOT NULL WITH DEFAULT ' .
509
            'DROP COLUMN baz ' .
510
            'ALTER COLUMN bar DROP NOT NULL ' .
511
            'RENAME COLUMN id TO war',
512
            'CALL SYSPROC.ADMIN_CMD (\'REORG TABLE "foo"\')',
513
            'RENAME TABLE "foo" TO "table"',
514
            'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
515
            'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
516
        ];
517
    }
518
519
    /**
520
     * {@inheritdoc}
521
     */
522
    protected function getCommentOnColumnSQL()
523
    {
524
        return [
525
            'COMMENT ON COLUMN foo.bar IS \'comment\'',
526
            'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
527
            'COMMENT ON COLUMN "select"."from" IS \'comment\'',
528
        ];
529
    }
530
531
    /**
532
     * @group DBAL-944
533
     * @dataProvider getGeneratesAlterColumnSQL
534
     */
535
    public function testGeneratesAlterColumnSQL($changedProperty, Column $column, $expectedSQLClause = null)
536
    {
537
        $tableDiff                        = new TableDiff('foo');
538
        $tableDiff->fromTable             = new Table('foo');
539
        $tableDiff->changedColumns['bar'] = new ColumnDiff('bar', $column, [$changedProperty]);
540
541
        $expectedSQL = [];
542
543
        if ($expectedSQLClause !== null) {
544
            $expectedSQL[] = 'ALTER TABLE foo ALTER COLUMN bar ' . $expectedSQLClause;
545
        }
546
547
        $expectedSQL[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE foo')";
548
549
        self::assertSame($expectedSQL, $this->platform->getAlterTableSQL($tableDiff));
550
    }
551
552
    /**
553
     * @return mixed[]
554
     */
555
    public function getGeneratesAlterColumnSQL()
556
    {
557
        return [
558
            [
559
                'columnDefinition',
560
                new Column('bar', Type::getType('decimal'), ['columnDefinition' => 'MONEY NOT NULL']),
561
                'MONEY NOT NULL',
562
            ],
563
            [
564
                'type',
565
                new Column('bar', Type::getType('integer')),
566
                'SET DATA TYPE INTEGER',
567
            ],
568
            [
569
                'length',
570
                new Column('bar', Type::getType('string'), ['length' => 100]),
571
                'SET DATA TYPE VARCHAR(100)',
572
            ],
573
            [
574
                'precision',
575
                new Column('bar', Type::getType('decimal'), ['precision' => 10, 'scale' => 2]),
576
                'SET DATA TYPE NUMERIC(10, 2)',
577
            ],
578
            [
579
                'scale',
580
                new Column('bar', Type::getType('decimal'), ['precision' => 5, 'scale' => 4]),
581
                'SET DATA TYPE NUMERIC(5, 4)',
582
            ],
583
            [
584
                'fixed',
585
                new Column('bar', Type::getType('string'), ['length' => 20, 'fixed' => true]),
586
                'SET DATA TYPE CHAR(20)',
587
            ],
588
            [
589
                'notnull',
590
                new Column('bar', Type::getType('string'), ['notnull' => true]),
591
                'SET NOT NULL',
592
            ],
593
            [
594
                'notnull',
595
                new Column('bar', Type::getType('string'), ['notnull' => false]),
596
                'DROP NOT NULL',
597
            ],
598
            [
599
                'default',
600
                new Column('bar', Type::getType('string'), ['default' => 'foo']),
601
                "SET DEFAULT 'foo'",
602
            ],
603
            [
604
                'default',
605
                new Column('bar', Type::getType('integer'), ['autoincrement' => true, 'default' => 666]),
606
                null,
607
            ],
608
            [
609
                'default',
610
                new Column('bar', Type::getType('string')),
611
                'DROP DEFAULT',
612
            ],
613
        ];
614
    }
615
616
    /**
617
     * {@inheritdoc}
618
     */
619
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL()
620
    {
621
        return 'CONSTRAINT "select" UNIQUE (foo)';
622
    }
623
624
    /**
625
     * {@inheritdoc}
626
     */
627
    protected function getQuotesReservedKeywordInIndexDeclarationSQL()
628
    {
629
        return ''; // not supported by this platform
630
    }
631
632
    /**
633
     * {@inheritdoc}
634
     */
635
    protected function getQuotesReservedKeywordInTruncateTableSQL()
636
    {
637
        return 'TRUNCATE "select" IMMEDIATE';
638
    }
639
640
    /**
641
     * {@inheritdoc}
642
     */
643
    protected function supportsInlineIndexDeclaration()
644
    {
645
        return false;
646
    }
647
648
    /**
649
     * {@inheritdoc}
650
     */
651
    protected function supportsCommentOnStatement()
652
    {
653
        return true;
654
    }
655
656
    /**
657
     * {@inheritdoc}
658
     */
659
    protected function getAlterStringToFixedStringSQL()
660
    {
661
        return [
662
            'ALTER TABLE mytable ALTER COLUMN name SET DATA TYPE CHAR(2)',
663
            'CALL SYSPROC.ADMIN_CMD (\'REORG TABLE mytable\')',
664
        ];
665
    }
666
667
    /**
668
     * {@inheritdoc}
669
     */
670
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL()
671
    {
672
        return ['RENAME INDEX idx_foo TO idx_foo_renamed'];
673
    }
674
675
    /**
676
     * @group DBAL-2436
677
     */
678
    public function testQuotesTableNameInListTableColumnsSQL()
679
    {
680
        self::assertStringContainsStringIgnoringCase(
681
            "'Foo''Bar\\'",
682
            $this->platform->getListTableColumnsSQL("Foo'Bar\\")
683
        );
684
    }
685
686
    /**
687
     * @group DBAL-2436
688
     */
689
    public function testQuotesTableNameInListTableIndexesSQL()
690
    {
691
        self::assertStringContainsStringIgnoringCase(
692
            "'Foo''Bar\\'",
693
            $this->platform->getListTableIndexesSQL("Foo'Bar\\")
694
        );
695
    }
696
697
    /**
698
     * @group DBAL-2436
699
     */
700
    public function testQuotesTableNameInListTableForeignKeysSQL()
701
    {
702
        self::assertStringContainsStringIgnoringCase(
703
            "'Foo''Bar\\'",
704
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\")
705
        );
706
    }
707
}
708