Failed Conditions
Push — 3.0.x ( f82f5c...40cc9b )
by Grégoire
24s queued 15s
created

SQLAnywhere16PlatformTest   F

Complexity

Total Complexity 108

Size/Duplication

Total Lines 1225
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 108
eloc 533
dl 0
loc 1225
rs 2
c 0
b 0
f 0

107 Methods

Rating   Name   Duplication   Size   Complexity  
A testModifiesLimitQueryWithEmptyOffset() 0 5 1
B testGeneratesSQLSnippets() 0 71 1
A supportsInlineIndexDeclaration() 0 3 1
A testHasCorrectMaxIdentifierLength() 0 3 1
A testGeneratesTransactionsCommands() 0 17 1
A testCannotGenerateCustomConstraintWithCreateConstraintSQL() 0 5 1
A testGeneratesCreateTableSQLWithCommonIndexes() 0 16 1
A testSupportsTransactions() 0 3 1
A testPrefersIdentityColumns() 0 3 1
A testDoesNotPreferSequences() 0 3 1
A testGeneratesDDLSnippets() 0 21 1
A getCreateTableColumnCommentsSQL() 0 5 1
A testSupportsReleasePoints() 0 3 1
A testFixesSchemaElementNames() 0 19 2
A testGeneratesColumnTypesDeclarationSQL() 0 28 1
A testQuotesSchemaNameInListTableIndexesSQL() 0 5 1
A getBinaryMaxLength() 0 3 1
A getGenerateUniqueIndexSql() 0 3 1
A testGeneratesCreateTableSQLWithCheckConstraints() 0 11 1
A getBinaryDefaultLength() 0 3 1
A testCannotGenerateUniqueConstraintDeclarationSQLWithEmptyColumns() 0 5 1
A testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers() 0 13 1
A testCannotGenerateDropIndexSQLWithInvalidIndexParameter() 0 5 1
A getReturnsForeignKeyReferentialActionSQL() 0 9 1
A getQuotedAlterTableChangeColumnLengthSQL() 0 3 1
A testModifiesLimitQueryWithOffset() 0 9 1
A testDoesNotSupportSequences() 0 3 1
A testHasCorrectDefaultTransactionIsolationLevel() 0 5 1
A getGenerateIndexSql() 0 3 1
A testQuotesSchemaNameInListTableForeignKeysSQL() 0 5 1
A createPlatform() 0 3 1
A testSupportsIdentityColumns() 0 3 1
A getAlterTableRenameIndexSQL() 0 3 1
A testSupportsCommentOnStatement() 0 3 1
A getGenerateTableSql() 0 3 1
A testCannotGeneratePrimaryKeyDeclarationSQLWithEmptyColumns() 0 5 1
A getCreateTableColumnTypeCommentsSQL() 0 5 1
A testModifiesLimitQueryWithoutLimit() 0 5 1
A testCannotGenerateForeignKeyConstraintSQLWithEmptyLocalColumns() 0 4 1
A testQuotesTableNameInListTableIndexesSQL() 0 5 1
A testAppendsLockHint() 0 6 1
A getQuotedColumnInForeignKeySQL() 0 3 1
A testSupportsSchemas() 0 3 1
A getQuotesReservedKeywordInIndexDeclarationSQL() 0 3 1
A testReturnsBinaryTypeDeclarationSQL() 0 9 1
A testQuotesSchemaNameInListTableConstraintsSQL() 0 5 1
A testSupportsAlterTable() 0 3 1
A testReturnsBinaryTypeLongerThanMaxDeclarationSQL() 0 4 1
A testSupportsForeignKeyOnUpdate() 0 3 1
A testReturnsGuidTypeDeclarationSQL() 0 3 1
A testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignTableName() 0 4 1
A getAlterTableRenameColumnSQL() 0 3 1
A testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignColumns() 0 4 1
A testCannotGenerateCommonIndexWithCreateConstraintSQL() 0 5 1
A testModifiesLimitQueryWithSubSelect() 0 5 1
A testQuotesSchemaNameInListTableColumnsSQL() 0 5 1
A testCannotGenerateInvalidForeignKeyMatchClauseSQL() 0 5 1
A getGenerateTableWithMultiColumnUniqueIndexSql() 0 5 1
A getAlterTableColumnCommentsSQL() 0 7 1
A getQuotedAlterTableRenameIndexSQL() 0 5 1
A testThrowsExceptionOnInvalidWithNullsNotDistinctIndexOptions() 0 13 1
A getQuotedColumnInIndexSQL() 0 5 1
A testHasCorrectDateTimeTzFormatString() 0 3 1
A testDoesNotSupportIndexDeclarationInCreateAlterTableStatements() 0 5 1
A testSupportsCreateDropDatabase() 0 3 1
A getQuotedAlterTableRenameColumnSQL() 0 12 1
A testCannotGenerateTransactionCommandWithInvalidIsolationLevel() 0 5 1
A getQuotesTableIdentifiersInAlterTableSQL() 0 10 1
B testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL() 0 100 1
A testHasCorrectPlatformName() 0 3 1
A testSupportsPrimaryConstraints() 0 3 1
A testGeneratesPrimaryKeyDeclarationSQL() 0 13 1
A getAlterStringToFixedStringSQL() 0 3 1
A getQuotesReservedKeywordInUniqueConstraintDeclarationSQL() 0 3 1
A testInitializesDateTimeTzTypeMapping() 0 4 1
A testSupportsIndexes() 0 3 1
A getQuotesReservedKeywordInTruncateTableSQL() 0 3 1
A testGeneratesSequenceSqlCommands() 0 26 1
A testQuotesTableNameInListTableConstraintsSQL() 0 3 1
A testGeneratesUniqueConstraintDeclarationSQL() 0 12 1
A testGeneratesDropIndexSQL() 0 9 1
A getGenerateAlterTableSql() 0 5 1
A testDoesNotSupportInlineColumnComments() 0 3 1
A getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() 0 3 1
A testInitializesDoctrineTypeMappings() 0 10 1
A getQuotedAlterTableRenameIndexInSchemaSQL() 0 5 1
A testGeneratesCreateTableSQLWithForeignKeyConstraints() 0 22 1
A testQuotesTableNameInListTableForeignKeysSQL() 0 5 1
A testGeneratesDateTimeTzColumnTypeDeclarationSQL() 0 9 1
A testHasNativeGuidType() 0 3 1
A getCommentOnColumnSQL() 0 6 1
A testGeneratesForeignKeyMatchClausesSQL() 0 6 1
A testSupportsForeignKeyConstraints() 0 3 1
A getLockHints() 0 10 1
A getQuotedNameInIndexSQL() 0 5 1
A testModifiesLimitQuery() 0 5 1
A testCannotEmulateSchemas() 0 3 1
A testCannotGenerateDropIndexSQLWithInvalidTableParameter() 0 5 1
A testSupportsSequences() 0 3 1
A getGenerateForeignKeySql() 0 3 1
A getAlterTableRenameIndexInSchemaSQL() 0 3 1
A testGeneratesTableAlterationWithRemovedColumnCommentSql() 0 16 1
A testSupportsSavePoints() 0 3 1
A getQuotedColumnInPrimaryKeySQL() 0 3 1
A testGeneratesCreateUnnamedPrimaryKeySQL() 0 14 1
A testGeneratesForeignKeyConstraintsWithAdvancedPlatformOptionsSQL() 0 23 1
A testSupportsGettingAffectedRows() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like SQLAnywhere16PlatformTest 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 SQLAnywhere16PlatformTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Doctrine\Tests\DBAL\Platforms;
4
5
use Doctrine\DBAL\DBALException;
6
use Doctrine\DBAL\LockMode;
7
use Doctrine\DBAL\Platforms\AbstractPlatform;
8
use Doctrine\DBAL\Platforms\SQLAnywhere16Platform;
9
use Doctrine\DBAL\Platforms\TrimMode;
10
use Doctrine\DBAL\Schema\Column;
11
use Doctrine\DBAL\Schema\ColumnDiff;
12
use Doctrine\DBAL\Schema\Comparator;
13
use Doctrine\DBAL\Schema\Constraint;
14
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
15
use Doctrine\DBAL\Schema\Index;
16
use Doctrine\DBAL\Schema\Sequence;
17
use Doctrine\DBAL\Schema\Table;
18
use Doctrine\DBAL\Schema\TableDiff;
19
use Doctrine\DBAL\TransactionIsolationLevel;
20
use Doctrine\DBAL\Types\Type;
21
use InvalidArgumentException;
22
use function mt_rand;
23
use function strlen;
24
use function substr;
25
26
class SQLAnywhere16PlatformTest extends AbstractPlatformTestCase
27
{
28
    /** @var SQLAnywhere16Platform */
29
    protected $platform;
30
31
    public function createPlatform() : AbstractPlatform
32
    {
33
        return new SQLAnywhere16Platform();
34
    }
35
36
    /**
37
     * {@inheritDoc}
38
     */
39
    public function getGenerateAlterTableSql() : array
40
    {
41
        return [
42
            "ALTER TABLE mytable ADD quota INT DEFAULT NULL, DROP foo, ALTER baz VARCHAR(1) DEFAULT 'def' NOT NULL, ALTER bloo BIT DEFAULT '0' NOT NULL",
43
            'ALTER TABLE mytable RENAME userlist',
44
        ];
45
    }
46
47
    public function getGenerateForeignKeySql() : string
48
    {
49
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
50
    }
51
52
    public function getGenerateIndexSql() : string
53
    {
54
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
55
    }
56
57
    public function getGenerateTableSql() : string
58
    {
59
        return 'CREATE TABLE test (id INT IDENTITY NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id))';
60
    }
61
62
    /**
63
     * {@inheritDoc}
64
     */
65
    public function getGenerateTableWithMultiColumnUniqueIndexSql() : array
66
    {
67
        return [
68
            'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)',
69
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)',
70
        ];
71
    }
72
73
    public function getGenerateUniqueIndexSql() : string
74
    {
75
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
76
    }
77
78
    /**
79
     * {@inheritDoc}
80
     */
81
    protected function getQuotedColumnInForeignKeySQL() : array
82
    {
83
        return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL, CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES "foreign" ("create", bar, "foo-bar"), CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foo ("create", bar, "foo-bar"), CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar"))'];
84
    }
85
86
    /**
87
     * {@inheritDoc}
88
     */
89
    protected function getQuotedColumnInIndexSQL() : array
90
    {
91
        return [
92
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)',
93
            'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")',
94
        ];
95
    }
96
97
    /**
98
     * {@inheritDoc}
99
     */
100
    protected function getQuotedNameInIndexSQL() : array
101
    {
102
        return [
103
            'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)',
104
            'CREATE INDEX "key" ON test (column1)',
105
        ];
106
    }
107
108
    /**
109
     * {@inheritDoc}
110
     */
111
    protected function getQuotedColumnInPrimaryKeySQL() : array
112
    {
113
        return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, PRIMARY KEY ("create"))'];
114
    }
115
116
    /**
117
     * {@inheritDoc}
118
     */
119
    public function getCreateTableColumnCommentsSQL() : array
120
    {
121
        return [
122
            'CREATE TABLE test (id INT NOT NULL, PRIMARY KEY (id))',
123
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
124
        ];
125
    }
126
127
    /**
128
     * {@inheritDoc}
129
     */
130
    public function getAlterTableColumnCommentsSQL() : array
131
    {
132
        return [
133
            'ALTER TABLE mytable ADD quota INT NOT NULL',
134
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
135
            'COMMENT ON COLUMN mytable.foo IS NULL',
136
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
137
        ];
138
    }
139
140
    /**
141
     * {@inheritDoc}
142
     */
143
    public function getCreateTableColumnTypeCommentsSQL() : array
144
    {
145
        return [
146
            'CREATE TABLE test (id INT NOT NULL, data TEXT NOT NULL, PRIMARY KEY (id))',
147
            "COMMENT ON COLUMN test.data IS '(DC2Type:array)'",
148
        ];
149
    }
150
151
    public function testHasCorrectPlatformName() : void
152
    {
153
        self::assertEquals('sqlanywhere', $this->platform->getName());
154
    }
155
156
    public function testGeneratesCreateTableSQLWithCommonIndexes() : void
157
    {
158
        $table = new Table('test');
159
        $table->addColumn('id', 'integer');
160
        $table->addColumn('name', 'string', ['length' => 50]);
161
        $table->setPrimaryKey(['id']);
162
        $table->addIndex(['name']);
163
        $table->addIndex(['id', 'name'], 'composite_idx');
164
165
        self::assertEquals(
166
            [
167
                'CREATE TABLE test (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id))',
168
                'CREATE INDEX IDX_D87F7E0C5E237E06 ON test (name)',
169
                'CREATE INDEX composite_idx ON test (id, name)',
170
            ],
171
            $this->platform->getCreateTableSQL($table)
172
        );
173
    }
174
175
    public function testGeneratesCreateTableSQLWithForeignKeyConstraints() : void
176
    {
177
        $table = new Table('test');
178
        $table->addColumn('id', 'integer');
179
        $table->addColumn('fk_1', 'integer');
180
        $table->addColumn('fk_2', 'integer');
181
        $table->setPrimaryKey(['id']);
182
        $table->addForeignKeyConstraint('foreign_table', ['fk_1', 'fk_2'], ['pk_1', 'pk_2']);
183
        $table->addForeignKeyConstraint(
184
            'foreign_table2',
185
            ['fk_1', 'fk_2'],
186
            ['pk_1', 'pk_2'],
187
            [],
188
            'named_fk'
189
        );
190
191
        self::assertEquals(
192
            ['CREATE TABLE test (id INT NOT NULL, fk_1 INT NOT NULL, fk_2 INT NOT NULL, ' .
193
                'CONSTRAINT FK_D87F7E0C177612A38E7F4319 FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table (pk_1, pk_2), ' .
194
                'CONSTRAINT named_fk FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table2 (pk_1, pk_2))',
195
            ],
196
            $this->platform->getCreateTableSQL($table, AbstractPlatform::CREATE_FOREIGNKEYS)
197
        );
198
    }
199
200
    public function testGeneratesCreateTableSQLWithCheckConstraints() : void
201
    {
202
        $table = new Table('test');
203
        $table->addColumn('id', 'integer');
204
        $table->addColumn('check_max', 'integer', ['platformOptions' => ['max' => 10]]);
205
        $table->addColumn('check_min', 'integer', ['platformOptions' => ['min' => 10]]);
206
        $table->setPrimaryKey(['id']);
207
208
        self::assertEquals(
209
            ['CREATE TABLE test (id INT NOT NULL, check_max INT NOT NULL, check_min INT NOT NULL, PRIMARY KEY (id), CHECK (check_max <= 10), CHECK (check_min >= 10))'],
210
            $this->platform->getCreateTableSQL($table)
211
        );
212
    }
213
214
    public function testGeneratesTableAlterationWithRemovedColumnCommentSql() : void
215
    {
216
        $table = new Table('mytable');
217
        $table->addColumn('foo', 'string', ['comment' => 'foo comment']);
218
219
        $tableDiff                        = new TableDiff('mytable');
220
        $tableDiff->fromTable             = $table;
221
        $tableDiff->changedColumns['foo'] = new ColumnDiff(
222
            'foo',
223
            new Column('foo', Type::getType('string')),
224
            ['comment']
225
        );
226
227
        self::assertEquals(
228
            ['COMMENT ON COLUMN mytable.foo IS NULL'],
229
            $this->platform->getAlterTableSQL($tableDiff)
230
        );
231
    }
232
233
    /**
234
     * @param int|bool|null $lockMode
235
     *
236
     * @dataProvider getLockHints
237
     */
238
    public function testAppendsLockHint($lockMode, string $lockHint) : void
239
    {
240
        $fromClause     = 'FROM users';
241
        $expectedResult = $fromClause . $lockHint;
242
243
        self::assertSame($expectedResult, $this->platform->appendLockHint($fromClause, $lockMode));
244
    }
245
246
    /**
247
     * @return mixed[][]
248
     */
249
    public static function getLockHints() : iterable
250
    {
251
        return [
252
            [null, ''],
253
            [false, ''],
254
            [true, ''],
255
            [LockMode::NONE, ' WITH (NOLOCK)'],
256
            [LockMode::OPTIMISTIC, ''],
257
            [LockMode::PESSIMISTIC_READ, ' WITH (UPDLOCK)'],
258
            [LockMode::PESSIMISTIC_WRITE, ' WITH (XLOCK)'],
259
        ];
260
    }
261
262
    public function testHasCorrectMaxIdentifierLength() : void
263
    {
264
        self::assertEquals(128, $this->platform->getMaxIdentifierLength());
265
    }
266
267
    public function testFixesSchemaElementNames() : void
268
    {
269
        $maxIdentifierLength = $this->platform->getMaxIdentifierLength();
270
        $characters          = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
271
        $schemaElementName   = '';
272
273
        for ($i = 0; $i < $maxIdentifierLength + 100; $i++) {
274
            $schemaElementName .= $characters[mt_rand(0, strlen($characters) - 1)];
275
        }
276
277
        $fixedSchemaElementName = substr($schemaElementName, 0, $maxIdentifierLength);
278
279
        self::assertEquals(
280
            $fixedSchemaElementName,
281
            $this->platform->fixSchemaElementName($schemaElementName)
282
        );
283
        self::assertEquals(
284
            $fixedSchemaElementName,
285
            $this->platform->fixSchemaElementName($fixedSchemaElementName)
286
        );
287
    }
288
289
    public function testGeneratesColumnTypesDeclarationSQL() : void
290
    {
291
        $fullColumnDef = [
292
            'length' => 10,
293
            'fixed' => true,
294
            'unsigned' => true,
295
            'autoincrement' => true,
296
        ];
297
298
        self::assertEquals('SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL([]));
299
        self::assertEquals('UNSIGNED SMALLINT', $this->platform->getSmallIntTypeDeclarationSQL(['unsigned' => true]));
300
        self::assertEquals('UNSIGNED SMALLINT IDENTITY', $this->platform->getSmallIntTypeDeclarationSQL($fullColumnDef));
301
        self::assertEquals('INT', $this->platform->getIntegerTypeDeclarationSQL([]));
302
        self::assertEquals('UNSIGNED INT', $this->platform->getIntegerTypeDeclarationSQL(['unsigned' => true]));
303
        self::assertEquals('UNSIGNED INT IDENTITY', $this->platform->getIntegerTypeDeclarationSQL($fullColumnDef));
304
        self::assertEquals('BIGINT', $this->platform->getBigIntTypeDeclarationSQL([]));
305
        self::assertEquals('UNSIGNED BIGINT', $this->platform->getBigIntTypeDeclarationSQL(['unsigned' => true]));
306
        self::assertEquals('UNSIGNED BIGINT IDENTITY', $this->platform->getBigIntTypeDeclarationSQL($fullColumnDef));
307
        self::assertEquals('LONG BINARY', $this->platform->getBlobTypeDeclarationSQL($fullColumnDef));
308
        self::assertEquals('BIT', $this->platform->getBooleanTypeDeclarationSQL($fullColumnDef));
309
        self::assertEquals('TEXT', $this->platform->getClobTypeDeclarationSQL($fullColumnDef));
310
        self::assertEquals('DATE', $this->platform->getDateTypeDeclarationSQL($fullColumnDef));
311
        self::assertEquals('DATETIME', $this->platform->getDateTimeTypeDeclarationSQL($fullColumnDef));
312
        self::assertEquals('TIME', $this->platform->getTimeTypeDeclarationSQL($fullColumnDef));
313
        self::assertEquals('UNIQUEIDENTIFIER', $this->platform->getGuidTypeDeclarationSQL($fullColumnDef));
314
315
        self::assertEquals(1, $this->platform->getVarcharDefaultLength());
316
        self::assertEquals(32767, $this->platform->getVarcharMaxLength());
317
    }
318
319
    public function testHasNativeGuidType() : void
320
    {
321
        self::assertTrue($this->platform->hasNativeGuidType());
322
    }
323
324
    public function testGeneratesDDLSnippets() : void
325
    {
326
        self::assertEquals("CREATE DATABASE 'foobar'", $this->platform->getCreateDatabaseSQL('foobar'));
327
        self::assertEquals("CREATE DATABASE 'foobar'", $this->platform->getCreateDatabaseSQL('"foobar"'));
328
        self::assertEquals("CREATE DATABASE 'create'", $this->platform->getCreateDatabaseSQL('create'));
329
        self::assertEquals("DROP DATABASE 'foobar'", $this->platform->getDropDatabaseSQL('foobar'));
330
        self::assertEquals("DROP DATABASE 'foobar'", $this->platform->getDropDatabaseSQL('"foobar"'));
331
        self::assertEquals("DROP DATABASE 'create'", $this->platform->getDropDatabaseSQL('create'));
332
        self::assertEquals('CREATE GLOBAL TEMPORARY TABLE', $this->platform->getCreateTemporaryTableSnippetSQL());
333
        self::assertEquals("START DATABASE 'foobar' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('foobar'));
334
        self::assertEquals("START DATABASE 'foobar' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('"foobar"'));
335
        self::assertEquals("START DATABASE 'create' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('create'));
336
        self::assertEquals('STOP DATABASE "foobar" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('foobar'));
337
        self::assertEquals('STOP DATABASE "foobar" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('"foobar"'));
338
        self::assertEquals('STOP DATABASE "create" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('create'));
339
        self::assertEquals('TRUNCATE TABLE foobar', $this->platform->getTruncateTableSQL('foobar'));
340
        self::assertEquals('TRUNCATE TABLE foobar', $this->platform->getTruncateTableSQL('foobar'), true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $message of PHPUnit\Framework\Assert::assertEquals(). ( Ignorable by Annotation )

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

340
        self::assertEquals('TRUNCATE TABLE foobar', $this->platform->getTruncateTableSQL('foobar'), /** @scrutinizer ignore-type */ true);
Loading history...
341
342
        $viewSql = 'SELECT * FROM footable';
343
        self::assertEquals('CREATE VIEW fooview AS ' . $viewSql, $this->platform->getCreateViewSQL('fooview', $viewSql));
344
        self::assertEquals('DROP VIEW fooview', $this->platform->getDropViewSQL('fooview'));
345
    }
346
347
    public function testGeneratesPrimaryKeyDeclarationSQL() : void
348
    {
349
        self::assertEquals(
350
            'CONSTRAINT pk PRIMARY KEY CLUSTERED (a, b)',
351
            $this->platform->getPrimaryKeyDeclarationSQL(
352
                new Index(null, ['a', 'b'], true, true, ['clustered']),
353
                'pk'
354
            )
355
        );
356
        self::assertEquals(
357
            'PRIMARY KEY (a, b)',
358
            $this->platform->getPrimaryKeyDeclarationSQL(
359
                new Index(null, ['a', 'b'], true, true)
360
            )
361
        );
362
    }
363
364
    public function testCannotGeneratePrimaryKeyDeclarationSQLWithEmptyColumns() : void
365
    {
366
        $this->expectException(InvalidArgumentException::class);
367
368
        $this->platform->getPrimaryKeyDeclarationSQL(new Index('pk', [], true, true));
369
    }
370
371
    public function testGeneratesCreateUnnamedPrimaryKeySQL() : void
372
    {
373
        self::assertEquals(
374
            'ALTER TABLE foo ADD PRIMARY KEY CLUSTERED (a, b)',
375
            $this->platform->getCreatePrimaryKeySQL(
376
                new Index('pk', ['a', 'b'], true, true, ['clustered']),
377
                'foo'
378
            )
379
        );
380
        self::assertEquals(
381
            'ALTER TABLE foo ADD PRIMARY KEY (a, b)',
382
            $this->platform->getCreatePrimaryKeySQL(
383
                new Index('any_pk_name', ['a', 'b'], true, true),
384
                new Table('foo')
385
            )
386
        );
387
    }
388
389
    public function testGeneratesUniqueConstraintDeclarationSQL() : void
390
    {
391
        self::assertEquals(
392
            'CONSTRAINT unique_constraint UNIQUE CLUSTERED (a, b)',
393
            $this->platform->getUniqueConstraintDeclarationSQL(
394
                'unique_constraint',
395
                new Index(null, ['a', 'b'], true, false, ['clustered'])
396
            )
397
        );
398
        self::assertEquals(
399
            'UNIQUE (a, b)',
400
            $this->platform->getUniqueConstraintDeclarationSQL(null, new Index(null, ['a', 'b'], true, false))
401
        );
402
    }
403
404
    public function testCannotGenerateUniqueConstraintDeclarationSQLWithEmptyColumns() : void
405
    {
406
        $this->expectException(InvalidArgumentException::class);
407
408
        $this->platform->getUniqueConstraintDeclarationSQL('constr', new Index('constr', [], true));
409
    }
410
411
    public function testGeneratesForeignKeyConstraintsWithAdvancedPlatformOptionsSQL() : void
412
    {
413
        self::assertEquals(
414
            'CONSTRAINT fk ' .
415
                'NOT NULL FOREIGN KEY (a, b) ' .
416
                'REFERENCES foreign_table (c, d) ' .
417
                'MATCH UNIQUE SIMPLE ON UPDATE CASCADE ON DELETE SET NULL CHECK ON COMMIT CLUSTERED FOR OLAP WORKLOAD',
418
            $this->platform->getForeignKeyDeclarationSQL(
419
                new ForeignKeyConstraint(['a', 'b'], 'foreign_table', ['c', 'd'], 'fk', [
420
                    'notnull' => true,
421
                    'match' => SQLAnywhere16Platform::FOREIGN_KEY_MATCH_SIMPLE_UNIQUE,
422
                    'onUpdate' => 'CASCADE',
423
                    'onDelete' => 'SET NULL',
424
                    'check_on_commit' => true,
425
                    'clustered' => true,
426
                    'for_olap_workload' => true,
427
                ])
428
            )
429
        );
430
        self::assertEquals(
431
            'FOREIGN KEY (a, b) REFERENCES foreign_table (c, d)',
432
            $this->platform->getForeignKeyDeclarationSQL(
433
                new ForeignKeyConstraint(['a', 'b'], 'foreign_table', ['c', 'd'])
434
            )
435
        );
436
    }
437
438
    public function testGeneratesForeignKeyMatchClausesSQL() : void
439
    {
440
        self::assertEquals('SIMPLE', $this->platform->getForeignKeyMatchClauseSQL(1));
441
        self::assertEquals('FULL', $this->platform->getForeignKeyMatchClauseSQL(2));
442
        self::assertEquals('UNIQUE SIMPLE', $this->platform->getForeignKeyMatchClauseSQL(129));
443
        self::assertEquals('UNIQUE FULL', $this->platform->getForeignKeyMatchClauseSQL(130));
444
    }
445
446
    public function testCannotGenerateInvalidForeignKeyMatchClauseSQL() : void
447
    {
448
        $this->expectException(InvalidArgumentException::class);
449
450
        $this->platform->getForeignKeyMatchCLauseSQL(3);
451
    }
452
453
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyLocalColumns() : void
454
    {
455
        $this->expectException(InvalidArgumentException::class);
456
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint([], 'foreign_tbl', ['c', 'd']));
457
    }
458
459
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignColumns() : void
460
    {
461
        $this->expectException(InvalidArgumentException::class);
462
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint(['a', 'b'], 'foreign_tbl', []));
463
    }
464
465
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignTableName() : void
466
    {
467
        $this->expectException(InvalidArgumentException::class);
468
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint(['a', 'b'], '', ['c', 'd']));
469
    }
470
471
    public function testCannotGenerateCommonIndexWithCreateConstraintSQL() : void
472
    {
473
        $this->expectException(InvalidArgumentException::class);
474
475
        $this->platform->getCreateConstraintSQL(new Index('fooindex', []), new Table('footable'));
476
    }
477
478
    public function testCannotGenerateCustomConstraintWithCreateConstraintSQL() : void
479
    {
480
        $this->expectException(InvalidArgumentException::class);
481
482
        $this->platform->getCreateConstraintSQL($this->createMock(Constraint::class), 'footable');
483
    }
484
485
    public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL() : void
486
    {
487
        self::assertEquals(
488
            'CREATE UNIQUE INDEX fooindex ON footable (a, b) WITH NULLS DISTINCT',
489
            $this->platform->getCreateIndexSQL(
490
                new Index(
491
                    'fooindex',
492
                    ['a', 'b'],
493
                    true,
494
                    false,
495
                    ['with_nulls_distinct']
496
                ),
497
                'footable'
498
            )
499
        );
500
501
        // WITH NULLS DISTINCT clause not available on primary indexes.
502
        self::assertEquals(
503
            'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
504
            $this->platform->getCreateIndexSQL(
505
                new Index(
506
                    'fooindex',
507
                    ['a', 'b'],
508
                    false,
509
                    true,
510
                    ['with_nulls_distinct']
511
                ),
512
                'footable'
513
            )
514
        );
515
516
        // WITH NULLS DISTINCT clause not available on non-unique indexes.
517
        self::assertEquals(
518
            'CREATE INDEX fooindex ON footable (a, b)',
519
            $this->platform->getCreateIndexSQL(
520
                new Index(
521
                    'fooindex',
522
                    ['a', 'b'],
523
                    false,
524
                    false,
525
                    ['with_nulls_distinct']
526
                ),
527
                'footable'
528
            )
529
        );
530
531
        self::assertEquals(
532
            'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b) WITH NULLS NOT DISTINCT FOR OLAP WORKLOAD',
533
            $this->platform->getCreateIndexSQL(
534
                new Index(
535
                    'fooindex',
536
                    ['a', 'b'],
537
                    true,
538
                    false,
539
                    ['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
540
                ),
541
                'footable'
542
            )
543
        );
544
        self::assertEquals(
545
            'CREATE VIRTUAL CLUSTERED INDEX fooindex ON footable (a, b) FOR OLAP WORKLOAD',
546
            $this->platform->getCreateIndexSQL(
547
                new Index(
548
                    'fooindex',
549
                    ['a', 'b'],
550
                    false,
551
                    false,
552
                    ['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
553
                ),
554
                'footable'
555
            )
556
        );
557
558
        // WITH NULLS NOT DISTINCT clause not available on primary indexes.
559
        self::assertEquals(
560
            'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
561
            $this->platform->getCreateIndexSQL(
562
                new Index(
563
                    'fooindex',
564
                    ['a', 'b'],
565
                    false,
566
                    true,
567
                    ['with_nulls_not_distinct']
568
                ),
569
                'footable'
570
            )
571
        );
572
573
        // WITH NULLS NOT DISTINCT clause not available on non-unique indexes.
574
        self::assertEquals(
575
            'CREATE INDEX fooindex ON footable (a, b)',
576
            $this->platform->getCreateIndexSQL(
577
                new Index(
578
                    'fooindex',
579
                    ['a', 'b'],
580
                    false,
581
                    false,
582
                    ['with_nulls_not_distinct']
583
                ),
584
                'footable'
585
            )
586
        );
587
    }
588
589
    public function testThrowsExceptionOnInvalidWithNullsNotDistinctIndexOptions() : void
590
    {
591
        $this->expectException('UnexpectedValueException');
592
593
        $this->platform->getCreateIndexSQL(
594
            new Index(
595
                'fooindex',
596
                ['a', 'b'],
597
                false,
598
                false,
599
                ['with_nulls_distinct', 'with_nulls_not_distinct']
600
            ),
601
            'footable'
602
        );
603
    }
604
605
    public function testDoesNotSupportIndexDeclarationInCreateAlterTableStatements() : void
606
    {
607
        $this->expectException(DBALException::class);
608
609
        $this->platform->getIndexDeclarationSQL('index', new Index('index', []));
610
    }
611
612
    public function testGeneratesDropIndexSQL() : void
613
    {
614
        $index = new Index('fooindex', []);
615
616
        self::assertEquals('DROP INDEX fooindex', $this->platform->getDropIndexSQL($index));
617
        self::assertEquals('DROP INDEX footable.fooindex', $this->platform->getDropIndexSQL($index, 'footable'));
618
        self::assertEquals('DROP INDEX footable.fooindex', $this->platform->getDropIndexSQL(
619
            $index,
620
            new Table('footable')
621
        ));
622
    }
623
624
    public function testCannotGenerateDropIndexSQLWithInvalidIndexParameter() : void
625
    {
626
        $this->expectException(InvalidArgumentException::class);
627
628
        $this->platform->getDropIndexSQL(['index'], 'table');
629
    }
630
631
    public function testCannotGenerateDropIndexSQLWithInvalidTableParameter() : void
632
    {
633
        $this->expectException(InvalidArgumentException::class);
634
635
        $this->platform->getDropIndexSQL('index', ['table']);
636
    }
637
638
    public function testGeneratesSQLSnippets() : void
639
    {
640
        self::assertEquals('STRING(column1, "string1", column2, "string2")', $this->platform->getConcatExpression(
641
            'column1',
642
            '"string1"',
643
            'column2',
644
            '"string2"'
645
        ));
646
        self::assertEquals('CURRENT DATE', $this->platform->getCurrentDateSQL());
647
        self::assertEquals('CURRENT TIME', $this->platform->getCurrentTimeSQL());
648
        self::assertEquals('CURRENT TIMESTAMP', $this->platform->getCurrentTimestampSQL());
649
        self::assertEquals("DATEADD(DAY, 4, '1987/05/02')", $this->platform->getDateAddDaysExpression("'1987/05/02'", 4));
650
        self::assertEquals("DATEADD(HOUR, 12, '1987/05/02')", $this->platform->getDateAddHourExpression("'1987/05/02'", 12));
651
        self::assertEquals("DATEADD(MINUTE, 2, '1987/05/02')", $this->platform->getDateAddMinutesExpression("'1987/05/02'", 2));
652
        self::assertEquals("DATEADD(MONTH, 102, '1987/05/02')", $this->platform->getDateAddMonthExpression("'1987/05/02'", 102));
653
        self::assertEquals("DATEADD(QUARTER, 5, '1987/05/02')", $this->platform->getDateAddQuartersExpression("'1987/05/02'", 5));
654
        self::assertEquals("DATEADD(SECOND, 1, '1987/05/02')", $this->platform->getDateAddSecondsExpression("'1987/05/02'", 1));
655
        self::assertEquals("DATEADD(WEEK, 3, '1987/05/02')", $this->platform->getDateAddWeeksExpression("'1987/05/02'", 3));
656
        self::assertEquals("DATEADD(YEAR, 10, '1987/05/02')", $this->platform->getDateAddYearsExpression("'1987/05/02'", 10));
657
        self::assertEquals("DATEDIFF(day, '1987/04/01', '1987/05/02')", $this->platform->getDateDiffExpression("'1987/05/02'", "'1987/04/01'"));
658
        self::assertEquals("DATEADD(DAY, -1 * 4, '1987/05/02')", $this->platform->getDateSubDaysExpression("'1987/05/02'", 4));
659
        self::assertEquals("DATEADD(HOUR, -1 * 12, '1987/05/02')", $this->platform->getDateSubHourExpression("'1987/05/02'", 12));
660
        self::assertEquals("DATEADD(MINUTE, -1 * 2, '1987/05/02')", $this->platform->getDateSubMinutesExpression("'1987/05/02'", 2));
661
        self::assertEquals("DATEADD(MONTH, -1 * 102, '1987/05/02')", $this->platform->getDateSubMonthExpression("'1987/05/02'", 102));
662
        self::assertEquals("DATEADD(QUARTER, -1 * 5, '1987/05/02')", $this->platform->getDateSubQuartersExpression("'1987/05/02'", 5));
663
        self::assertEquals("DATEADD(SECOND, -1 * 1, '1987/05/02')", $this->platform->getDateSubSecondsExpression("'1987/05/02'", 1));
664
        self::assertEquals("DATEADD(WEEK, -1 * 3, '1987/05/02')", $this->platform->getDateSubWeeksExpression("'1987/05/02'", 3));
665
        self::assertEquals("DATEADD(YEAR, -1 * 10, '1987/05/02')", $this->platform->getDateSubYearsExpression("'1987/05/02'", 10));
666
        self::assertEquals('Y-m-d H:i:s.u', $this->platform->getDateTimeFormatString());
667
        self::assertEquals('H:i:s.u', $this->platform->getTimeFormatString());
668
        self::assertEquals('', $this->platform->getForUpdateSQL());
669
        self::assertEquals('NEWID()', $this->platform->getGuidExpression());
670
        self::assertEquals('LOCATE(string_column, substring_column)', $this->platform->getLocateExpression('string_column', 'substring_column'));
671
        self::assertEquals('LOCATE(string_column, substring_column, 1)', $this->platform->getLocateExpression('string_column', 'substring_column', 1));
672
        self::assertEquals("HASH(column, 'MD5')", $this->platform->getMd5Expression('column'));
673
        self::assertEquals('SUBSTRING(column, 5)', $this->platform->getSubstringExpression('column', 5));
674
        self::assertEquals('SUBSTRING(column, 5, 2)', $this->platform->getSubstringExpression('column', 5, 2));
675
        self::assertEquals('GLOBAL TEMPORARY', $this->platform->getTemporaryTableSQL());
676
        self::assertEquals(
677
            'LTRIM(column)',
678
            $this->platform->getTrimExpression('column', TrimMode::LEADING)
679
        );
680
        self::assertEquals(
681
            'RTRIM(column)',
682
            $this->platform->getTrimExpression('column', TrimMode::TRAILING)
683
        );
684
        self::assertEquals(
685
            'TRIM(column)',
686
            $this->platform->getTrimExpression('column')
687
        );
688
        self::assertEquals(
689
            'TRIM(column)',
690
            $this->platform->getTrimExpression('column', TrimMode::UNSPECIFIED)
691
        );
692
        self::assertEquals(
693
            "SUBSTR(column, PATINDEX('%[^' + c + ']%', column))",
694
            $this->platform->getTrimExpression('column', TrimMode::LEADING, 'c')
695
        );
696
        self::assertEquals(
697
            "REVERSE(SUBSTR(REVERSE(column), PATINDEX('%[^' + c + ']%', REVERSE(column))))",
698
            $this->platform->getTrimExpression('column', TrimMode::TRAILING, 'c')
699
        );
700
        self::assertEquals(
701
            "REVERSE(SUBSTR(REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))), PATINDEX('%[^' + c + ']%', " .
702
            "REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))))))",
703
            $this->platform->getTrimExpression('column', null, 'c')
704
        );
705
        self::assertEquals(
706
            "REVERSE(SUBSTR(REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))), PATINDEX('%[^' + c + ']%', " .
707
            "REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))))))",
708
            $this->platform->getTrimExpression('column', TrimMode::UNSPECIFIED, 'c')
709
        );
710
    }
711
712
    public function testHasCorrectDateTimeTzFormatString() : void
713
    {
714
        self::assertEquals('Y-m-d H:i:s.uP', $this->platform->getDateTimeTzFormatString());
715
    }
716
717
    public function testGeneratesDateTimeTzColumnTypeDeclarationSQL() : void
718
    {
719
        self::assertEquals(
720
            'TIMESTAMP WITH TIME ZONE',
721
            $this->platform->getDateTimeTzTypeDeclarationSQL([
722
                'length' => 10,
723
                'fixed' => true,
724
                'unsigned' => true,
725
                'autoincrement' => true,
726
            ])
727
        );
728
    }
729
730
    public function testInitializesDateTimeTzTypeMapping() : void
731
    {
732
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp with time zone'));
733
        self::assertEquals('datetime', $this->platform->getDoctrineTypeMapping('timestamp with time zone'));
734
    }
735
736
    public function testHasCorrectDefaultTransactionIsolationLevel() : void
737
    {
738
        self::assertEquals(
739
            TransactionIsolationLevel::READ_UNCOMMITTED,
740
            $this->platform->getDefaultTransactionIsolationLevel()
741
        );
742
    }
743
744
    public function testGeneratesTransactionsCommands() : void
745
    {
746
        self::assertEquals(
747
            'SET TEMPORARY OPTION isolation_level = 0',
748
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_UNCOMMITTED)
749
        );
750
        self::assertEquals(
751
            'SET TEMPORARY OPTION isolation_level = 1',
752
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_COMMITTED)
753
        );
754
        self::assertEquals(
755
            'SET TEMPORARY OPTION isolation_level = 2',
756
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::REPEATABLE_READ)
757
        );
758
        self::assertEquals(
759
            'SET TEMPORARY OPTION isolation_level = 3',
760
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::SERIALIZABLE)
761
        );
762
    }
763
764
    public function testCannotGenerateTransactionCommandWithInvalidIsolationLevel() : void
765
    {
766
        $this->expectException(InvalidArgumentException::class);
767
768
        $this->platform->getSetTransactionIsolationSQL('invalid_transaction_isolation_level');
769
    }
770
771
    public function testModifiesLimitQuery() : void
772
    {
773
        self::assertEquals(
774
            'SELECT TOP 10 * FROM user',
775
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 0)
776
        );
777
    }
778
779
    public function testModifiesLimitQueryWithEmptyOffset() : void
780
    {
781
        self::assertEquals(
782
            'SELECT TOP 10 * FROM user',
783
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10)
784
        );
785
    }
786
787
    public function testModifiesLimitQueryWithOffset() : void
788
    {
789
        self::assertEquals(
790
            'SELECT TOP 10 START AT 6 * FROM user',
791
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 5)
792
        );
793
        self::assertEquals(
794
            'SELECT TOP 0 START AT 6 * FROM user',
795
            $this->platform->modifyLimitQuery('SELECT * FROM user', 0, 5)
796
        );
797
    }
798
799
    public function testModifiesLimitQueryWithSubSelect() : void
800
    {
801
        self::assertEquals(
802
            'SELECT TOP 10 * FROM (SELECT u.id as uid, u.name as uname FROM user) AS doctrine_tbl',
803
            $this->platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname FROM user) AS doctrine_tbl', 10)
804
        );
805
    }
806
807
    public function testModifiesLimitQueryWithoutLimit() : void
808
    {
809
        self::assertEquals(
810
            'SELECT TOP ALL START AT 11 n FROM Foo',
811
            $this->platform->modifyLimitQuery('SELECT n FROM Foo', null, 10)
812
        );
813
    }
814
815
    public function testPrefersIdentityColumns() : void
816
    {
817
        self::assertTrue($this->platform->prefersIdentityColumns());
818
    }
819
820
    public function testDoesNotPreferSequences() : void
821
    {
822
        self::assertFalse($this->platform->prefersSequences());
823
    }
824
825
    public function testSupportsIdentityColumns() : void
826
    {
827
        self::assertTrue($this->platform->supportsIdentityColumns());
828
    }
829
830
    public function testSupportsPrimaryConstraints() : void
831
    {
832
        self::assertTrue($this->platform->supportsPrimaryConstraints());
833
    }
834
835
    public function testSupportsForeignKeyConstraints() : void
836
    {
837
        self::assertTrue($this->platform->supportsForeignKeyConstraints());
838
    }
839
840
    public function testSupportsForeignKeyOnUpdate() : void
841
    {
842
        self::assertTrue($this->platform->supportsForeignKeyOnUpdate());
843
    }
844
845
    public function testSupportsAlterTable() : void
846
    {
847
        self::assertTrue($this->platform->supportsAlterTable());
848
    }
849
850
    public function testSupportsTransactions() : void
851
    {
852
        self::assertTrue($this->platform->supportsTransactions());
853
    }
854
855
    public function testSupportsSchemas() : void
856
    {
857
        self::assertFalse($this->platform->supportsSchemas());
858
    }
859
860
    public function testSupportsIndexes() : void
861
    {
862
        self::assertTrue($this->platform->supportsIndexes());
863
    }
864
865
    public function testSupportsCommentOnStatement() : void
866
    {
867
        self::assertTrue($this->platform->supportsCommentOnStatement());
868
    }
869
870
    public function testSupportsSavePoints() : void
871
    {
872
        self::assertTrue($this->platform->supportsSavepoints());
873
    }
874
875
    public function testSupportsReleasePoints() : void
876
    {
877
        self::assertTrue($this->platform->supportsReleaseSavepoints());
878
    }
879
880
    public function testSupportsCreateDropDatabase() : void
881
    {
882
        self::assertTrue($this->platform->supportsCreateDropDatabase());
883
    }
884
885
    public function testSupportsGettingAffectedRows() : void
886
    {
887
        self::assertTrue($this->platform->supportsGettingAffectedRows());
888
    }
889
890
    public function testDoesNotSupportSequences() : void
891
    {
892
        self::markTestSkipped('This version of the platform now supports sequences.');
893
    }
894
895
    public function testSupportsSequences() : void
896
    {
897
        self::assertTrue($this->platform->supportsSequences());
898
    }
899
900
    public function testGeneratesSequenceSqlCommands() : void
901
    {
902
        $sequence = new Sequence('myseq', 20, 1);
903
        self::assertEquals(
904
            'CREATE SEQUENCE myseq INCREMENT BY 20 START WITH 1 MINVALUE 1',
905
            $this->platform->getCreateSequenceSQL($sequence)
906
        );
907
        self::assertEquals(
908
            'ALTER SEQUENCE myseq INCREMENT BY 20',
909
            $this->platform->getAlterSequenceSQL($sequence)
910
        );
911
        self::assertEquals(
912
            'DROP SEQUENCE myseq',
913
            $this->platform->getDropSequenceSQL('myseq')
914
        );
915
        self::assertEquals(
916
            'DROP SEQUENCE myseq',
917
            $this->platform->getDropSequenceSQL($sequence)
918
        );
919
        self::assertEquals(
920
            'SELECT myseq.NEXTVAL',
921
            $this->platform->getSequenceNextValSQL('myseq')
922
        );
923
        self::assertEquals(
924
            'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE',
925
            $this->platform->getListSequencesSQL(null)
926
        );
927
    }
928
929
    public function testDoesNotSupportInlineColumnComments() : void
930
    {
931
        self::assertFalse($this->platform->supportsInlineColumnComments());
932
    }
933
934
    public function testCannotEmulateSchemas() : void
935
    {
936
        self::assertFalse($this->platform->canEmulateSchemas());
937
    }
938
939
    public function testInitializesDoctrineTypeMappings() : void
940
    {
941
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('integer'));
942
        self::assertSame('integer', $this->platform->getDoctrineTypeMapping('integer'));
943
944
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('binary'));
945
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('binary'));
946
947
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('varbinary'));
948
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('varbinary'));
949
    }
950
951
    protected function getBinaryDefaultLength() : int
952
    {
953
        return 1;
954
    }
955
956
    protected function getBinaryMaxLength() : int
957
    {
958
        return 32767;
959
    }
960
961
    public function testReturnsBinaryTypeDeclarationSQL() : void
962
    {
963
        self::assertSame('VARBINARY(1)', $this->platform->getBinaryTypeDeclarationSQL([]));
964
        self::assertSame('VARBINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 0]));
965
        self::assertSame('VARBINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32767]));
966
967
        self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true]));
968
        self::assertSame('BINARY(1)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 0]));
969
        self::assertSame('BINARY(32767)', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 32767]));
970
    }
971
972
    /**
973
     * @group legacy
974
     * @expectedDeprecation Binary field length 32768 is greater than supported by the platform (32767). Reduce the field length or use a BLOB field instead.
975
     */
976
    public function testReturnsBinaryTypeLongerThanMaxDeclarationSQL() : void
977
    {
978
        self::assertSame('LONG BINARY', $this->platform->getBinaryTypeDeclarationSQL(['length' => 32768]));
979
        self::assertSame('LONG BINARY', $this->platform->getBinaryTypeDeclarationSQL(['fixed' => true, 'length' => 32768]));
980
    }
981
982
    /**
983
     * {@inheritDoc}
984
     *
985
     * @group DBAL-234
986
     */
987
    protected function getAlterTableRenameIndexSQL() : array
988
    {
989
        return ['ALTER INDEX idx_foo ON mytable RENAME TO idx_bar'];
990
    }
991
992
    /**
993
     * {@inheritDoc}
994
     *
995
     * @group DBAL-234
996
     */
997
    protected function getQuotedAlterTableRenameIndexSQL() : array
998
    {
999
        return [
1000
            'ALTER INDEX "create" ON "table" RENAME TO "select"',
1001
            'ALTER INDEX "foo" ON "table" RENAME TO "bar"',
1002
        ];
1003
    }
1004
1005
    /**
1006
     * {@inheritdoc}
1007
     */
1008
    protected function getQuotedAlterTableRenameColumnSQL() : array
1009
    {
1010
        return [
1011
            'ALTER TABLE mytable RENAME unquoted1 TO unquoted',
1012
            'ALTER TABLE mytable RENAME unquoted2 TO "where"',
1013
            'ALTER TABLE mytable RENAME unquoted3 TO "foo"',
1014
            'ALTER TABLE mytable RENAME "create" TO reserved_keyword',
1015
            'ALTER TABLE mytable RENAME "table" TO "from"',
1016
            'ALTER TABLE mytable RENAME "select" TO "bar"',
1017
            'ALTER TABLE mytable RENAME quoted1 TO quoted',
1018
            'ALTER TABLE mytable RENAME quoted2 TO "and"',
1019
            'ALTER TABLE mytable RENAME quoted3 TO "baz"',
1020
        ];
1021
    }
1022
1023
    /**
1024
     * {@inheritdoc}
1025
     */
1026
    protected function getQuotedAlterTableChangeColumnLengthSQL() : array
1027
    {
1028
        $this->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...
1029
    }
1030
1031
    /**
1032
     * {@inheritDoc}
1033
     *
1034
     * @group DBAL-807
1035
     */
1036
    protected function getAlterTableRenameIndexInSchemaSQL() : array
1037
    {
1038
        return ['ALTER INDEX idx_foo ON myschema.mytable RENAME TO idx_bar'];
1039
    }
1040
1041
    /**
1042
     * {@inheritDoc}
1043
     *
1044
     * @group DBAL-807
1045
     */
1046
    protected function getQuotedAlterTableRenameIndexInSchemaSQL() : array
1047
    {
1048
        return [
1049
            'ALTER INDEX "create" ON "schema"."table" RENAME TO "select"',
1050
            'ALTER INDEX "foo" ON "schema"."table" RENAME TO "bar"',
1051
        ];
1052
    }
1053
1054
    /**
1055
     * @group DBAL-423
1056
     */
1057
    public function testReturnsGuidTypeDeclarationSQL() : void
1058
    {
1059
        self::assertSame('UNIQUEIDENTIFIER', $this->platform->getGuidTypeDeclarationSQL([]));
1060
    }
1061
1062
    /**
1063
     * {@inheritdoc}
1064
     */
1065
    public function getAlterTableRenameColumnSQL() : array
1066
    {
1067
        return ['ALTER TABLE foo RENAME bar TO baz'];
1068
    }
1069
1070
    /**
1071
     * {@inheritdoc}
1072
     */
1073
    protected function getQuotesTableIdentifiersInAlterTableSQL() : array
1074
    {
1075
        return [
1076
            'ALTER TABLE "foo" DROP FOREIGN KEY fk1',
1077
            'ALTER TABLE "foo" DROP FOREIGN KEY fk2',
1078
            'ALTER TABLE "foo" RENAME id TO war',
1079
            'ALTER TABLE "foo" ADD bloo INT NOT NULL, DROP baz, ALTER bar INT DEFAULT NULL',
1080
            'ALTER TABLE "foo" RENAME "table"',
1081
            'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
1082
            'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
1083
        ];
1084
    }
1085
1086
    /**
1087
     * {@inheritdoc}
1088
     */
1089
    protected function getCommentOnColumnSQL() : array
1090
    {
1091
        return [
1092
            'COMMENT ON COLUMN foo.bar IS \'comment\'',
1093
            'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
1094
            'COMMENT ON COLUMN "select"."from" IS \'comment\'',
1095
        ];
1096
    }
1097
1098
    /**
1099
     * @group DBAL-1004
1100
     */
1101
    public function testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers() : void
1102
    {
1103
        $table1 = new Table('"foo"', [new Column('"bar"', Type::getType('integer'))]);
1104
        $table2 = new Table('"foo"', [new Column('"bar"', Type::getType('integer'), ['comment' => 'baz'])]);
1105
1106
        $comparator = new Comparator();
1107
1108
        $tableDiff = $comparator->diffTable($table1, $table2);
1109
1110
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1111
        self::assertSame(
1112
            ['COMMENT ON COLUMN "foo"."bar" IS \'baz\''],
1113
            $this->platform->getAlterTableSQL($tableDiff)
0 ignored issues
show
Bug introduced by
It seems like $tableDiff 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

1113
            $this->platform->getAlterTableSQL(/** @scrutinizer ignore-type */ $tableDiff)
Loading history...
1114
        );
1115
    }
1116
1117
    /**
1118
     * {@inheritdoc}
1119
     */
1120
    public static function getReturnsForeignKeyReferentialActionSQL() : iterable
1121
    {
1122
        return [
1123
            ['CASCADE', 'CASCADE'],
1124
            ['SET NULL', 'SET NULL'],
1125
            ['NO ACTION', 'RESTRICT'],
1126
            ['RESTRICT', 'RESTRICT'],
1127
            ['SET DEFAULT', 'SET DEFAULT'],
1128
            ['CaScAdE', 'CASCADE'],
1129
        ];
1130
    }
1131
1132
    /**
1133
     * {@inheritdoc}
1134
     */
1135
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL() : string
1136
    {
1137
        return 'CONSTRAINT "select" UNIQUE (foo)';
1138
    }
1139
1140
    /**
1141
     * {@inheritdoc}
1142
     */
1143
    protected function getQuotesReservedKeywordInIndexDeclarationSQL() : string
1144
    {
1145
        return ''; // not supported by this platform
1146
    }
1147
1148
    /**
1149
     * {@inheritdoc}
1150
     */
1151
    protected function getQuotesReservedKeywordInTruncateTableSQL() : string
1152
    {
1153
        return 'TRUNCATE TABLE "select"';
1154
    }
1155
1156
    /**
1157
     * {@inheritdoc}
1158
     */
1159
    protected function supportsInlineIndexDeclaration() : bool
1160
    {
1161
        return false;
1162
    }
1163
1164
    /**
1165
     * {@inheritdoc}
1166
     */
1167
    protected function getAlterStringToFixedStringSQL() : array
1168
    {
1169
        return ['ALTER TABLE mytable ALTER name CHAR(2) NOT NULL'];
1170
    }
1171
1172
    /**
1173
     * {@inheritdoc}
1174
     */
1175
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() : array
1176
    {
1177
        return ['ALTER INDEX idx_foo ON mytable RENAME TO idx_foo_renamed'];
1178
    }
1179
1180
    /**
1181
     * @group DBAL-2436
1182
     */
1183
    public function testQuotesSchemaNameInListTableColumnsSQL() : void
1184
    {
1185
        self::assertStringContainsStringIgnoringCase(
1186
            "'Foo''Bar\\'",
1187
            $this->platform->getListTableColumnsSQL("Foo'Bar\\.baz_table")
1188
        );
1189
    }
1190
1191
    /**
1192
     * @group DBAL-2436
1193
     */
1194
    public function testQuotesTableNameInListTableConstraintsSQL() : void
1195
    {
1196
        self::assertStringContainsStringIgnoringCase("'Foo''Bar\\'", $this->platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true);
0 ignored issues
show
Unused Code introduced by
The call to PHPUnit\Framework\Assert...insStringIgnoringCase() has too many arguments starting with true. ( Ignorable by Annotation )

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

1196
        self::/** @scrutinizer ignore-call */ 
1197
              assertStringContainsStringIgnoringCase("'Foo''Bar\\'", $this->platform->getListTableConstraintsSQL("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...
1197
    }
1198
1199
    /**
1200
     * @group DBAL-2436
1201
     */
1202
    public function testQuotesSchemaNameInListTableConstraintsSQL() : void
1203
    {
1204
        self::assertStringContainsStringIgnoringCase(
1205
            "'Foo''Bar\\'",
1206
            $this->platform->getListTableConstraintsSQL("Foo'Bar\\.baz_table")
1207
        );
1208
    }
1209
1210
    /**
1211
     * @group DBAL-2436
1212
     */
1213
    public function testQuotesTableNameInListTableForeignKeysSQL() : void
1214
    {
1215
        self::assertStringContainsStringIgnoringCase(
1216
            "'Foo''Bar\\'",
1217
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\")
1218
        );
1219
    }
1220
1221
    /**
1222
     * @group DBAL-2436
1223
     */
1224
    public function testQuotesSchemaNameInListTableForeignKeysSQL() : void
1225
    {
1226
        self::assertStringContainsStringIgnoringCase(
1227
            "'Foo''Bar\\'",
1228
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\.baz_table")
1229
        );
1230
    }
1231
1232
    /**
1233
     * @group DBAL-2436
1234
     */
1235
    public function testQuotesTableNameInListTableIndexesSQL() : void
1236
    {
1237
        self::assertStringContainsStringIgnoringCase(
1238
            "'Foo''Bar\\'",
1239
            $this->platform->getListTableIndexesSQL("Foo'Bar\\")
1240
        );
1241
    }
1242
1243
    /**
1244
     * @group DBAL-2436
1245
     */
1246
    public function testQuotesSchemaNameInListTableIndexesSQL() : void
1247
    {
1248
        self::assertStringContainsStringIgnoringCase(
1249
            "'Foo''Bar\\'",
1250
            $this->platform->getListTableIndexesSQL("Foo'Bar\\.baz_table")
1251
        );
1252
    }
1253
}
1254