SQLAnywhere16PlatformTest   F
last analyzed

Complexity

Total Complexity 103

Size/Duplication

Total Lines 1157
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 508
dl 0
loc 1157
rs 2
c 0
b 0
f 0
wmc 103

102 Methods

Rating   Name   Duplication   Size   Complexity  
A testHasCorrectMaxIdentifierLength() 0 3 1
A testFixesSchemaElementNames() 0 19 2
A createPlatform() 0 3 1
A testSupportsAlterTable() 0 3 1
A testSupportsIndexes() 0 3 1
A getQuotesReservedKeywordInIndexDeclarationSQL() 0 3 1
A testSupportsReleasePoints() 0 3 1
A getQuotesReservedKeywordInTruncateTableSQL() 0 3 1
A testGeneratesDropIndexSQL() 0 9 1
A testQuotesSchemaNameInListTableConstraintsSQL() 0 5 1
A getQuotedColumnInIndexSQL() 0 5 1
A testCannotGenerateCustomConstraintWithCreateConstraintSQL() 0 5 1
A testGeneratesCreateUnnamedPrimaryKeySQL() 0 14 1
B testGeneratesSQLSnippets() 0 65 1
A testCannotEmulateSchemas() 0 3 1
A getGenerateUniqueIndexSql() 0 3 1
A testGeneratesPrimaryKeyDeclarationSQL() 0 13 1
A testGeneratesDateTimeTzColumnTypeDeclarationSQL() 0 9 1
A testSupportsCreateDropDatabase() 0 3 1
A testInitializesDoctrineTypeMappings() 0 10 1
A getQuotedAlterTableRenameColumnSQL() 0 12 1
A testHasNativeGuidType() 0 3 1
A testGetVariableLengthStringTypeDeclarationSQLNoLength() 0 5 1
A testSupportsSchemas() 0 3 1
A testGeneratesCreateTableSQLWithForeignKeyConstraints() 0 22 1
A testSupportsGettingAffectedRows() 0 3 1
A testGeneratesCreateTableSQLWithCommonIndexes() 0 16 1
A getGenerateTableSql() 0 3 1
A getCommentOnColumnSQL() 0 6 1
A testGeneratesForeignKeyConstraintsWithAdvancedPlatformOptionsSQL() 0 23 1
A testQuotesSchemaNameInListTableColumnsSQL() 0 5 1
A testModifiesLimitQueryWithSubSelect() 0 5 1
A testModifiesLimitQueryWithEmptyOffset() 0 5 1
A testSupportsCommentOnStatement() 0 3 1
A getAlterTableRenameIndexInSchemaSQL() 0 3 1
A testAppendsLockHint() 0 6 1
A testQuotesTableNameInListTableConstraintsSQL() 0 3 1
A testGeneratesColumnTypesDeclarationSQL() 0 25 1
A testSupportsSavePoints() 0 3 1
A testGeneratesTransactionsCommands() 0 17 1
A testGetVariableLengthBinaryTypeDeclarationSQLNoLength() 0 5 1
A testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers() 0 13 1
B testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL() 0 100 1
A testQuotesTableNameInListTableIndexesSQL() 0 5 1
A testQuotesTableNameInListTableForeignKeysSQL() 0 5 1
A testModifiesLimitQueryWithOffset() 0 9 1
A getReturnsForeignKeyReferentialActionSQL() 0 9 1
A getQuotedAlterTableChangeColumnLengthSQL() 0 3 1
A getAlterStringToFixedStringSQL() 0 3 1
A testGeneratesForeignKeyMatchClausesSQL() 0 6 1
A testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignColumns() 0 4 1
A getCreateTableColumnTypeCommentsSQL() 0 5 1
A testGeneratesTableAlterationWithRemovedColumnCommentSql() 0 16 1
A testHasCorrectDateTimeTzFormatString() 0 3 1
A getGenerateTableWithMultiColumnUniqueIndexSql() 0 5 1
A getQuotesReservedKeywordInUniqueConstraintDeclarationSQL() 0 3 1
A getQuotedAlterTableRenameIndexSQL() 0 5 1
A testHasCorrectDefaultTransactionIsolationLevel() 0 5 1
A testHasCorrectPlatformName() 0 3 1
A testSupportsForeignKeyConstraints() 0 3 1
A testCannotGenerateForeignKeyConstraintSQLWithEmptyLocalColumns() 0 4 1
A testReturnsGuidTypeDeclarationSQL() 0 3 1
A testSupportsTransactions() 0 3 1
A getAlterTableRenameIndexSQL() 0 3 1
A testThrowsExceptionOnInvalidWithNullsNotDistinctIndexOptions() 0 13 1
A supportsInlineIndexDeclaration() 0 3 1
A testDoesNotSupportSequences() 0 3 1
A testDoesNotPreferSequences() 0 3 1
A testDoesNotSupportIndexDeclarationInCreateAlterTableStatements() 0 5 1
A getGenerateIndexSql() 0 3 1
A testCannotGenerateInvalidForeignKeyMatchClauseSQL() 0 5 1
A testCannotGenerateCommonIndexWithCreateConstraintSQL() 0 5 1
A testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignTableName() 0 4 1
A getQuotedColumnInPrimaryKeySQL() 0 3 1
A getQuotedColumnInForeignKeySQL() 0 3 1
A testCannotGenerateUniqueConstraintDeclarationSQLWithEmptyColumns() 0 5 1
A testCannotGeneratePrimaryKeyDeclarationSQLWithEmptyColumns() 0 5 1
A testDoesNotSupportInlineColumnComments() 0 3 1
A getQuotedAlterTableRenameIndexInSchemaSQL() 0 5 1
A testSupportsForeignKeyOnUpdate() 0 3 1
A testGeneratesSequenceSqlCommands() 0 22 1
A getCreateTableColumnCommentsSQL() 0 5 1
A getAlterTableRenameColumnSQL() 0 3 1
A testQuotesSchemaNameInListTableForeignKeysSQL() 0 5 1
A testSupportsIdentityColumns() 0 3 1
A getGenerateForeignKeySql() 0 3 1
A getLockHints() 0 8 1
A getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() 0 3 1
A getQuotesTableIdentifiersInAlterTableSQL() 0 10 1
A getAlterTableColumnCommentsSQL() 0 7 1
A testGeneratesUniqueConstraintDeclarationSQL() 0 12 1
A testGeneratesCreateTableSQLWithCheckConstraints() 0 11 1
A getGenerateAlterTableSql() 0 5 1
A testPrefersIdentityColumns() 0 3 1
A testInitializesDateTimeTzTypeMapping() 0 4 1
A testModifiesLimitQuery() 0 5 1
A testModifiesLimitQueryWithoutLimit() 0 5 1
A getQuotedNameInIndexSQL() 0 5 1
A testSupportsPrimaryConstraints() 0 3 1
A testGeneratesDDLSnippets() 0 20 1
A testSupportsSequences() 0 3 1
A testQuotesSchemaNameInListTableIndexesSQL() 0 5 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
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Tests\Platforms;
6
7
use Doctrine\DBAL\DBALException;
8
use Doctrine\DBAL\Exception\ColumnLengthRequired;
9
use Doctrine\DBAL\LockMode;
10
use Doctrine\DBAL\Platforms\AbstractPlatform;
11
use Doctrine\DBAL\Platforms\SQLAnywhere16Platform;
12
use Doctrine\DBAL\Platforms\TrimMode;
13
use Doctrine\DBAL\Schema\Column;
14
use Doctrine\DBAL\Schema\ColumnDiff;
15
use Doctrine\DBAL\Schema\Comparator;
16
use Doctrine\DBAL\Schema\Constraint;
17
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
18
use Doctrine\DBAL\Schema\Index;
19
use Doctrine\DBAL\Schema\Sequence;
20
use Doctrine\DBAL\Schema\Table;
21
use Doctrine\DBAL\Schema\TableDiff;
22
use Doctrine\DBAL\Schema\UniqueConstraint;
23
use Doctrine\DBAL\TransactionIsolationLevel;
24
use Doctrine\DBAL\Types\Type;
25
use InvalidArgumentException;
26
use function mt_rand;
27
use function strlen;
28
use function substr;
29
30
class SQLAnywhere16PlatformTest extends AbstractPlatformTestCase
31
{
32
    /** @var SQLAnywhere16Platform */
33
    protected $platform;
34
35
    public function createPlatform() : AbstractPlatform
36
    {
37
        return new SQLAnywhere16Platform();
38
    }
39
40
    /**
41
     * {@inheritDoc}
42
     */
43
    public function getGenerateAlterTableSql() : array
44
    {
45
        return [
46
            "ALTER TABLE mytable ADD quota INT DEFAULT NULL, DROP foo, ALTER baz VARCHAR(255) DEFAULT 'def' NOT NULL, ALTER bloo BIT DEFAULT '0' NOT NULL",
47
            'ALTER TABLE mytable RENAME userlist',
48
        ];
49
    }
50
51
    public function getGenerateForeignKeySql() : string
52
    {
53
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
54
    }
55
56
    public function getGenerateIndexSql() : string
57
    {
58
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
59
    }
60
61
    public function getGenerateTableSql() : string
62
    {
63
        return 'CREATE TABLE test (id INT IDENTITY NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id))';
64
    }
65
66
    /**
67
     * {@inheritDoc}
68
     */
69
    public function getGenerateTableWithMultiColumnUniqueIndexSql() : array
70
    {
71
        return [
72
            'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)',
73
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)',
74
        ];
75
    }
76
77
    public function getGenerateUniqueIndexSql() : string
78
    {
79
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     */
85
    protected function getQuotedColumnInForeignKeySQL() : array
86
    {
87
        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"))'];
88
    }
89
90
    /**
91
     * {@inheritDoc}
92
     */
93
    protected function getQuotedColumnInIndexSQL() : array
94
    {
95
        return [
96
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)',
97
            'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")',
98
        ];
99
    }
100
101
    /**
102
     * {@inheritDoc}
103
     */
104
    protected function getQuotedNameInIndexSQL() : array
105
    {
106
        return [
107
            'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)',
108
            'CREATE INDEX "key" ON test (column1)',
109
        ];
110
    }
111
112
    /**
113
     * {@inheritDoc}
114
     */
115
    protected function getQuotedColumnInPrimaryKeySQL() : array
116
    {
117
        return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, PRIMARY KEY ("create"))'];
118
    }
119
120
    /**
121
     * {@inheritDoc}
122
     */
123
    public function getCreateTableColumnCommentsSQL() : array
124
    {
125
        return [
126
            'CREATE TABLE test (id INT NOT NULL, PRIMARY KEY (id))',
127
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
128
        ];
129
    }
130
131
    /**
132
     * {@inheritDoc}
133
     */
134
    public function getAlterTableColumnCommentsSQL() : array
135
    {
136
        return [
137
            'ALTER TABLE mytable ADD quota INT NOT NULL',
138
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
139
            "COMMENT ON COLUMN mytable.foo IS ''",
140
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
141
        ];
142
    }
143
144
    /**
145
     * {@inheritDoc}
146
     */
147
    public function getCreateTableColumnTypeCommentsSQL() : array
148
    {
149
        return [
150
            'CREATE TABLE test (id INT NOT NULL, data TEXT NOT NULL, PRIMARY KEY (id))',
151
            "COMMENT ON COLUMN test.data IS '(DC2Type:array)'",
152
        ];
153
    }
154
155
    public function testHasCorrectPlatformName() : void
156
    {
157
        self::assertEquals('sqlanywhere', $this->platform->getName());
158
    }
159
160
    public function testGeneratesCreateTableSQLWithCommonIndexes() : void
161
    {
162
        $table = new Table('test');
163
        $table->addColumn('id', 'integer');
164
        $table->addColumn('name', 'string', ['length' => 50]);
165
        $table->setPrimaryKey(['id']);
166
        $table->addIndex(['name']);
167
        $table->addIndex(['id', 'name'], 'composite_idx');
168
169
        self::assertEquals(
170
            [
171
                'CREATE TABLE test (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id))',
172
                'CREATE INDEX IDX_D87F7E0C5E237E06 ON test (name)',
173
                'CREATE INDEX composite_idx ON test (id, name)',
174
            ],
175
            $this->platform->getCreateTableSQL($table)
176
        );
177
    }
178
179
    public function testGeneratesCreateTableSQLWithForeignKeyConstraints() : void
180
    {
181
        $table = new Table('test');
182
        $table->addColumn('id', 'integer');
183
        $table->addColumn('fk_1', 'integer');
184
        $table->addColumn('fk_2', 'integer');
185
        $table->setPrimaryKey(['id']);
186
        $table->addForeignKeyConstraint('foreign_table', ['fk_1', 'fk_2'], ['pk_1', 'pk_2']);
187
        $table->addForeignKeyConstraint(
188
            'foreign_table2',
189
            ['fk_1', 'fk_2'],
190
            ['pk_1', 'pk_2'],
191
            [],
192
            'named_fk'
193
        );
194
195
        self::assertEquals(
196
            ['CREATE TABLE test (id INT NOT NULL, fk_1 INT NOT NULL, fk_2 INT NOT NULL, ' .
197
                'CONSTRAINT FK_D87F7E0C177612A38E7F4319 FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table (pk_1, pk_2), ' .
198
                'CONSTRAINT named_fk FOREIGN KEY (fk_1, fk_2) REFERENCES foreign_table2 (pk_1, pk_2))',
199
            ],
200
            $this->platform->getCreateTableSQL($table, AbstractPlatform::CREATE_FOREIGNKEYS)
201
        );
202
    }
203
204
    public function testGeneratesCreateTableSQLWithCheckConstraints() : void
205
    {
206
        $table = new Table('test');
207
        $table->addColumn('id', 'integer');
208
        $table->addColumn('check_max', 'integer', ['platformOptions' => ['max' => 10]]);
209
        $table->addColumn('check_min', 'integer', ['platformOptions' => ['min' => 10]]);
210
        $table->setPrimaryKey(['id']);
211
212
        self::assertEquals(
213
            ['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))'],
214
            $this->platform->getCreateTableSQL($table)
215
        );
216
    }
217
218
    public function testGeneratesTableAlterationWithRemovedColumnCommentSql() : void
219
    {
220
        $table = new Table('mytable');
221
        $table->addColumn('foo', 'string', ['comment' => 'foo comment']);
222
223
        $tableDiff                        = new TableDiff('mytable');
224
        $tableDiff->fromTable             = $table;
225
        $tableDiff->changedColumns['foo'] = new ColumnDiff(
226
            'foo',
227
            new Column('foo', Type::getType('string')),
228
            ['comment']
229
        );
230
231
        self::assertEquals(
232
            ["COMMENT ON COLUMN mytable.foo IS ''"],
233
            $this->platform->getAlterTableSQL($tableDiff)
234
        );
235
    }
236
237
    /**
238
     * @dataProvider getLockHints
239
     */
240
    public function testAppendsLockHint(?int $lockMode, string $lockHint) : void
241
    {
242
        $fromClause     = 'FROM users';
243
        $expectedResult = $fromClause . $lockHint;
244
245
        self::assertSame($expectedResult, $this->platform->appendLockHint($fromClause, $lockMode));
246
    }
247
248
    /**
249
     * @return mixed[][]
250
     */
251
    public static function getLockHints() : iterable
252
    {
253
        return [
254
            [null, ''],
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
316
    public function testHasNativeGuidType() : void
317
    {
318
        self::assertTrue($this->platform->hasNativeGuidType());
319
    }
320
321
    public function testGeneratesDDLSnippets() : void
322
    {
323
        self::assertEquals("CREATE DATABASE 'foobar'", $this->platform->getCreateDatabaseSQL('foobar'));
324
        self::assertEquals("CREATE DATABASE 'foobar'", $this->platform->getCreateDatabaseSQL('"foobar"'));
325
        self::assertEquals("CREATE DATABASE 'create'", $this->platform->getCreateDatabaseSQL('create'));
326
        self::assertEquals("DROP DATABASE 'foobar'", $this->platform->getDropDatabaseSQL('foobar'));
327
        self::assertEquals("DROP DATABASE 'foobar'", $this->platform->getDropDatabaseSQL('"foobar"'));
328
        self::assertEquals("DROP DATABASE 'create'", $this->platform->getDropDatabaseSQL('create'));
329
        self::assertEquals('CREATE GLOBAL TEMPORARY TABLE', $this->platform->getCreateTemporaryTableSnippetSQL());
330
        self::assertEquals("START DATABASE 'foobar' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('foobar'));
331
        self::assertEquals("START DATABASE 'foobar' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('"foobar"'));
332
        self::assertEquals("START DATABASE 'create' AUTOSTOP OFF", $this->platform->getStartDatabaseSQL('create'));
333
        self::assertEquals('STOP DATABASE "foobar" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('foobar'));
334
        self::assertEquals('STOP DATABASE "foobar" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('"foobar"'));
335
        self::assertEquals('STOP DATABASE "create" UNCONDITIONALLY', $this->platform->getStopDatabaseSQL('create'));
336
        self::assertEquals('TRUNCATE TABLE foobar', $this->platform->getTruncateTableSQL('foobar'));
337
338
        $viewSql = 'SELECT * FROM footable';
339
        self::assertEquals('CREATE VIEW fooview AS ' . $viewSql, $this->platform->getCreateViewSQL('fooview', $viewSql));
340
        self::assertEquals('DROP VIEW fooview', $this->platform->getDropViewSQL('fooview'));
341
    }
342
343
    public function testGeneratesPrimaryKeyDeclarationSQL() : void
344
    {
345
        self::assertEquals(
346
            'CONSTRAINT pk PRIMARY KEY CLUSTERED (a, b)',
347
            $this->platform->getPrimaryKeyDeclarationSQL(
348
                new Index(null, ['a', 'b'], true, true, ['clustered']),
349
                'pk'
350
            )
351
        );
352
        self::assertEquals(
353
            'PRIMARY KEY (a, b)',
354
            $this->platform->getPrimaryKeyDeclarationSQL(
355
                new Index(null, ['a', 'b'], true, true)
356
            )
357
        );
358
    }
359
360
    public function testCannotGeneratePrimaryKeyDeclarationSQLWithEmptyColumns() : void
361
    {
362
        $this->expectException(InvalidArgumentException::class);
363
364
        $this->platform->getPrimaryKeyDeclarationSQL(new Index('pk', [], true, true));
365
    }
366
367
    public function testGeneratesCreateUnnamedPrimaryKeySQL() : void
368
    {
369
        self::assertEquals(
370
            'ALTER TABLE foo ADD PRIMARY KEY CLUSTERED (a, b)',
371
            $this->platform->getCreatePrimaryKeySQL(
372
                new Index('pk', ['a', 'b'], true, true, ['clustered']),
373
                'foo'
374
            )
375
        );
376
        self::assertEquals(
377
            'ALTER TABLE foo ADD PRIMARY KEY (a, b)',
378
            $this->platform->getCreatePrimaryKeySQL(
379
                new Index('any_pk_name', ['a', 'b'], true, true),
380
                new Table('foo')
381
            )
382
        );
383
    }
384
385
    public function testGeneratesUniqueConstraintDeclarationSQL() : void
386
    {
387
        self::assertEquals(
388
            'CONSTRAINT unique_constraint UNIQUE CLUSTERED (a, b)',
389
            $this->platform->getUniqueConstraintDeclarationSQL(
390
                'unique_constraint',
391
                new UniqueConstraint('', ['a', 'b'], ['clustered'])
392
            )
393
        );
394
        self::assertEquals(
395
            'CONSTRAINT UNIQUE (a, b)',
396
            $this->platform->getUniqueConstraintDeclarationSQL('', new UniqueConstraint('', ['a', 'b']))
397
        );
398
    }
399
400
    public function testCannotGenerateUniqueConstraintDeclarationSQLWithEmptyColumns() : void
401
    {
402
        $this->expectException(InvalidArgumentException::class);
403
404
        $this->platform->getUniqueConstraintDeclarationSQL('constr', new UniqueConstraint('constr', []));
405
    }
406
407
    public function testGeneratesForeignKeyConstraintsWithAdvancedPlatformOptionsSQL() : void
408
    {
409
        self::assertEquals(
410
            'CONSTRAINT fk ' .
411
                'NOT NULL FOREIGN KEY (a, b) ' .
412
                'REFERENCES foreign_table (c, d) ' .
413
                'MATCH UNIQUE SIMPLE ON UPDATE CASCADE ON DELETE SET NULL CHECK ON COMMIT CLUSTERED FOR OLAP WORKLOAD',
414
            $this->platform->getForeignKeyDeclarationSQL(
415
                new ForeignKeyConstraint(['a', 'b'], 'foreign_table', ['c', 'd'], 'fk', [
416
                    'notnull' => true,
417
                    'match' => SQLAnywhere16Platform::FOREIGN_KEY_MATCH_SIMPLE_UNIQUE,
418
                    'onUpdate' => 'CASCADE',
419
                    'onDelete' => 'SET NULL',
420
                    'check_on_commit' => true,
421
                    'clustered' => true,
422
                    'for_olap_workload' => true,
423
                ])
424
            )
425
        );
426
        self::assertEquals(
427
            'FOREIGN KEY (a, b) REFERENCES foreign_table (c, d)',
428
            $this->platform->getForeignKeyDeclarationSQL(
429
                new ForeignKeyConstraint(['a', 'b'], 'foreign_table', ['c', 'd'])
430
            )
431
        );
432
    }
433
434
    public function testGeneratesForeignKeyMatchClausesSQL() : void
435
    {
436
        self::assertEquals('SIMPLE', $this->platform->getForeignKeyMatchClauseSQL(1));
437
        self::assertEquals('FULL', $this->platform->getForeignKeyMatchClauseSQL(2));
438
        self::assertEquals('UNIQUE SIMPLE', $this->platform->getForeignKeyMatchClauseSQL(129));
439
        self::assertEquals('UNIQUE FULL', $this->platform->getForeignKeyMatchClauseSQL(130));
440
    }
441
442
    public function testCannotGenerateInvalidForeignKeyMatchClauseSQL() : void
443
    {
444
        $this->expectException(InvalidArgumentException::class);
445
446
        $this->platform->getForeignKeyMatchClauseSQL(3);
447
    }
448
449
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyLocalColumns() : void
450
    {
451
        $this->expectException(InvalidArgumentException::class);
452
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint([], 'foreign_tbl', ['c', 'd']));
453
    }
454
455
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignColumns() : void
456
    {
457
        $this->expectException(InvalidArgumentException::class);
458
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint(['a', 'b'], 'foreign_tbl', []));
459
    }
460
461
    public function testCannotGenerateForeignKeyConstraintSQLWithEmptyForeignTableName() : void
462
    {
463
        $this->expectException(InvalidArgumentException::class);
464
        $this->platform->getForeignKeyDeclarationSQL(new ForeignKeyConstraint(['a', 'b'], '', ['c', 'd']));
465
    }
466
467
    public function testCannotGenerateCommonIndexWithCreateConstraintSQL() : void
468
    {
469
        $this->expectException(InvalidArgumentException::class);
470
471
        $this->platform->getCreateConstraintSQL(new Index('fooindex', []), new Table('footable'));
472
    }
473
474
    public function testCannotGenerateCustomConstraintWithCreateConstraintSQL() : void
475
    {
476
        $this->expectException(InvalidArgumentException::class);
477
478
        $this->platform->getCreateConstraintSQL($this->createMock(Constraint::class), 'footable');
479
    }
480
481
    public function testGeneratesCreateIndexWithAdvancedPlatformOptionsSQL() : void
482
    {
483
        self::assertEquals(
484
            'CREATE UNIQUE INDEX fooindex ON footable (a, b) WITH NULLS DISTINCT',
485
            $this->platform->getCreateIndexSQL(
486
                new Index(
487
                    'fooindex',
488
                    ['a', 'b'],
489
                    true,
490
                    false,
491
                    ['with_nulls_distinct']
492
                ),
493
                'footable'
494
            )
495
        );
496
497
        // WITH NULLS DISTINCT clause not available on primary indexes.
498
        self::assertEquals(
499
            'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
500
            $this->platform->getCreateIndexSQL(
501
                new Index(
502
                    'fooindex',
503
                    ['a', 'b'],
504
                    false,
505
                    true,
506
                    ['with_nulls_distinct']
507
                ),
508
                'footable'
509
            )
510
        );
511
512
        // WITH NULLS DISTINCT clause not available on non-unique indexes.
513
        self::assertEquals(
514
            'CREATE INDEX fooindex ON footable (a, b)',
515
            $this->platform->getCreateIndexSQL(
516
                new Index(
517
                    'fooindex',
518
                    ['a', 'b'],
519
                    false,
520
                    false,
521
                    ['with_nulls_distinct']
522
                ),
523
                'footable'
524
            )
525
        );
526
527
        self::assertEquals(
528
            'CREATE VIRTUAL UNIQUE CLUSTERED INDEX fooindex ON footable (a, b) WITH NULLS NOT DISTINCT FOR OLAP WORKLOAD',
529
            $this->platform->getCreateIndexSQL(
530
                new Index(
531
                    'fooindex',
532
                    ['a', 'b'],
533
                    true,
534
                    false,
535
                    ['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
536
                ),
537
                'footable'
538
            )
539
        );
540
        self::assertEquals(
541
            'CREATE VIRTUAL CLUSTERED INDEX fooindex ON footable (a, b) FOR OLAP WORKLOAD',
542
            $this->platform->getCreateIndexSQL(
543
                new Index(
544
                    'fooindex',
545
                    ['a', 'b'],
546
                    false,
547
                    false,
548
                    ['virtual', 'clustered', 'with_nulls_not_distinct', 'for_olap_workload']
549
                ),
550
                'footable'
551
            )
552
        );
553
554
        // WITH NULLS NOT DISTINCT clause not available on primary indexes.
555
        self::assertEquals(
556
            'ALTER TABLE footable ADD PRIMARY KEY (a, b)',
557
            $this->platform->getCreateIndexSQL(
558
                new Index(
559
                    'fooindex',
560
                    ['a', 'b'],
561
                    false,
562
                    true,
563
                    ['with_nulls_not_distinct']
564
                ),
565
                'footable'
566
            )
567
        );
568
569
        // WITH NULLS NOT DISTINCT clause not available on non-unique indexes.
570
        self::assertEquals(
571
            'CREATE INDEX fooindex ON footable (a, b)',
572
            $this->platform->getCreateIndexSQL(
573
                new Index(
574
                    'fooindex',
575
                    ['a', 'b'],
576
                    false,
577
                    false,
578
                    ['with_nulls_not_distinct']
579
                ),
580
                'footable'
581
            )
582
        );
583
    }
584
585
    public function testThrowsExceptionOnInvalidWithNullsNotDistinctIndexOptions() : void
586
    {
587
        $this->expectException('UnexpectedValueException');
588
589
        $this->platform->getCreateIndexSQL(
590
            new Index(
591
                'fooindex',
592
                ['a', 'b'],
593
                false,
594
                false,
595
                ['with_nulls_distinct', 'with_nulls_not_distinct']
596
            ),
597
            'footable'
598
        );
599
    }
600
601
    public function testDoesNotSupportIndexDeclarationInCreateAlterTableStatements() : void
602
    {
603
        $this->expectException(DBALException::class);
604
605
        $this->platform->getIndexDeclarationSQL('index', new Index('index', []));
606
    }
607
608
    public function testGeneratesDropIndexSQL() : void
609
    {
610
        $index = new Index('fooindex', []);
611
612
        self::assertEquals('DROP INDEX fooindex', $this->platform->getDropIndexSQL($index));
613
        self::assertEquals('DROP INDEX footable.fooindex', $this->platform->getDropIndexSQL($index, 'footable'));
614
        self::assertEquals('DROP INDEX footable.fooindex', $this->platform->getDropIndexSQL(
615
            $index,
616
            new Table('footable')
617
        ));
618
    }
619
620
    public function testGeneratesSQLSnippets() : void
621
    {
622
        self::assertEquals('STRING(column1, "string1", column2, "string2")', $this->platform->getConcatExpression(
623
            'column1',
624
            '"string1"',
625
            'column2',
626
            '"string2"'
627
        ));
628
        self::assertEquals('CURRENT DATE', $this->platform->getCurrentDateSQL());
629
        self::assertEquals('CURRENT TIME', $this->platform->getCurrentTimeSQL());
630
        self::assertEquals('CURRENT TIMESTAMP', $this->platform->getCurrentTimestampSQL());
631
        self::assertEquals("DATEADD(DAY, 4, '1987/05/02')", $this->platform->getDateAddDaysExpression("'1987/05/02'", '4'));
632
        self::assertEquals("DATEADD(HOUR, 12, '1987/05/02')", $this->platform->getDateAddHourExpression("'1987/05/02'", '12'));
633
        self::assertEquals("DATEADD(MINUTE, 2, '1987/05/02')", $this->platform->getDateAddMinutesExpression("'1987/05/02'", '2'));
634
        self::assertEquals("DATEADD(MONTH, 102, '1987/05/02')", $this->platform->getDateAddMonthExpression("'1987/05/02'", '102'));
635
        self::assertEquals("DATEADD(QUARTER, 5, '1987/05/02')", $this->platform->getDateAddQuartersExpression("'1987/05/02'", '5'));
636
        self::assertEquals("DATEADD(SECOND, 1, '1987/05/02')", $this->platform->getDateAddSecondsExpression("'1987/05/02'", '1'));
637
        self::assertEquals("DATEADD(WEEK, 3, '1987/05/02')", $this->platform->getDateAddWeeksExpression("'1987/05/02'", '3'));
638
        self::assertEquals("DATEADD(YEAR, 10, '1987/05/02')", $this->platform->getDateAddYearsExpression("'1987/05/02'", '10'));
639
        self::assertEquals("DATEDIFF(day, '1987/04/01', '1987/05/02')", $this->platform->getDateDiffExpression("'1987/05/02'", "'1987/04/01'"));
640
        self::assertEquals("DATEADD(DAY, -1 * 4, '1987/05/02')", $this->platform->getDateSubDaysExpression("'1987/05/02'", '4'));
641
        self::assertEquals("DATEADD(HOUR, -1 * 12, '1987/05/02')", $this->platform->getDateSubHourExpression("'1987/05/02'", '12'));
642
        self::assertEquals("DATEADD(MINUTE, -1 * 2, '1987/05/02')", $this->platform->getDateSubMinutesExpression("'1987/05/02'", '2'));
643
        self::assertEquals("DATEADD(MONTH, -1 * 102, '1987/05/02')", $this->platform->getDateSubMonthExpression("'1987/05/02'", '102'));
644
        self::assertEquals("DATEADD(QUARTER, -1 * 5, '1987/05/02')", $this->platform->getDateSubQuartersExpression("'1987/05/02'", '5'));
645
        self::assertEquals("DATEADD(SECOND, -1 * 1, '1987/05/02')", $this->platform->getDateSubSecondsExpression("'1987/05/02'", '1'));
646
        self::assertEquals("DATEADD(WEEK, -1 * 3, '1987/05/02')", $this->platform->getDateSubWeeksExpression("'1987/05/02'", '3'));
647
        self::assertEquals("DATEADD(YEAR, -1 * 10, '1987/05/02')", $this->platform->getDateSubYearsExpression("'1987/05/02'", '10'));
648
        self::assertEquals('Y-m-d H:i:s.u', $this->platform->getDateTimeFormatString());
649
        self::assertEquals('H:i:s.u', $this->platform->getTimeFormatString());
650
        self::assertEquals('', $this->platform->getForUpdateSQL());
651
        self::assertEquals('LOCATE(string_column, substring_column)', $this->platform->getLocateExpression('string_column', 'substring_column'));
652
        self::assertEquals('LOCATE(string_column, substring_column, 1)', $this->platform->getLocateExpression('string_column', 'substring_column', '1'));
653
        self::assertEquals("HASH(column, 'MD5')", $this->platform->getMd5Expression('column'));
654
        self::assertEquals('SUBSTRING(column, 5)', $this->platform->getSubstringExpression('column', '5'));
655
        self::assertEquals('SUBSTRING(column, 5, 2)', $this->platform->getSubstringExpression('column', '5', '2'));
656
        self::assertEquals('GLOBAL TEMPORARY', $this->platform->getTemporaryTableSQL());
657
        self::assertEquals(
658
            'LTRIM(column)',
659
            $this->platform->getTrimExpression('column', TrimMode::LEADING)
660
        );
661
        self::assertEquals(
662
            'RTRIM(column)',
663
            $this->platform->getTrimExpression('column', TrimMode::TRAILING)
664
        );
665
        self::assertEquals(
666
            'TRIM(column)',
667
            $this->platform->getTrimExpression('column')
668
        );
669
        self::assertEquals(
670
            'TRIM(column)',
671
            $this->platform->getTrimExpression('column', TrimMode::UNSPECIFIED)
672
        );
673
        self::assertEquals(
674
            "SUBSTR(column, PATINDEX('%[^' + c + ']%', column))",
675
            $this->platform->getTrimExpression('column', TrimMode::LEADING, 'c')
676
        );
677
        self::assertEquals(
678
            "REVERSE(SUBSTR(REVERSE(column), PATINDEX('%[^' + c + ']%', REVERSE(column))))",
679
            $this->platform->getTrimExpression('column', TrimMode::TRAILING, 'c')
680
        );
681
        self::assertEquals(
682
            "REVERSE(SUBSTR(REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))), PATINDEX('%[^' + c + ']%', " .
683
            "REVERSE(SUBSTR(column, PATINDEX('%[^' + c + ']%', column))))))",
684
            $this->platform->getTrimExpression('column', TrimMode::UNSPECIFIED, 'c')
685
        );
686
    }
687
688
    public function testHasCorrectDateTimeTzFormatString() : void
689
    {
690
        self::assertEquals('Y-m-d H:i:s.uP', $this->platform->getDateTimeTzFormatString());
691
    }
692
693
    public function testGeneratesDateTimeTzColumnTypeDeclarationSQL() : void
694
    {
695
        self::assertEquals(
696
            'TIMESTAMP WITH TIME ZONE',
697
            $this->platform->getDateTimeTzTypeDeclarationSQL([
698
                'length' => 10,
699
                'fixed' => true,
700
                'unsigned' => true,
701
                'autoincrement' => true,
702
            ])
703
        );
704
    }
705
706
    public function testInitializesDateTimeTzTypeMapping() : void
707
    {
708
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('timestamp with time zone'));
709
        self::assertEquals('datetime', $this->platform->getDoctrineTypeMapping('timestamp with time zone'));
710
    }
711
712
    public function testHasCorrectDefaultTransactionIsolationLevel() : void
713
    {
714
        self::assertEquals(
715
            TransactionIsolationLevel::READ_UNCOMMITTED,
716
            $this->platform->getDefaultTransactionIsolationLevel()
717
        );
718
    }
719
720
    public function testGeneratesTransactionsCommands() : void
721
    {
722
        self::assertEquals(
723
            'SET TEMPORARY OPTION isolation_level = 0',
724
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_UNCOMMITTED)
725
        );
726
        self::assertEquals(
727
            'SET TEMPORARY OPTION isolation_level = 1',
728
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_COMMITTED)
729
        );
730
        self::assertEquals(
731
            'SET TEMPORARY OPTION isolation_level = 2',
732
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::REPEATABLE_READ)
733
        );
734
        self::assertEquals(
735
            'SET TEMPORARY OPTION isolation_level = 3',
736
            $this->platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::SERIALIZABLE)
737
        );
738
    }
739
740
    public function testModifiesLimitQuery() : void
741
    {
742
        self::assertEquals(
743
            'SELECT TOP 10 * FROM user',
744
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 0)
745
        );
746
    }
747
748
    public function testModifiesLimitQueryWithEmptyOffset() : void
749
    {
750
        self::assertEquals(
751
            'SELECT TOP 10 * FROM user',
752
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10)
753
        );
754
    }
755
756
    public function testModifiesLimitQueryWithOffset() : void
757
    {
758
        self::assertEquals(
759
            'SELECT TOP 10 START AT 6 * FROM user',
760
            $this->platform->modifyLimitQuery('SELECT * FROM user', 10, 5)
761
        );
762
        self::assertEquals(
763
            'SELECT TOP 0 START AT 6 * FROM user',
764
            $this->platform->modifyLimitQuery('SELECT * FROM user', 0, 5)
765
        );
766
    }
767
768
    public function testModifiesLimitQueryWithSubSelect() : void
769
    {
770
        self::assertEquals(
771
            'SELECT TOP 10 * FROM (SELECT u.id as uid, u.name as uname FROM user) AS doctrine_tbl',
772
            $this->platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname FROM user) AS doctrine_tbl', 10)
773
        );
774
    }
775
776
    public function testModifiesLimitQueryWithoutLimit() : void
777
    {
778
        self::assertEquals(
779
            'SELECT TOP ALL START AT 11 n FROM Foo',
780
            $this->platform->modifyLimitQuery('SELECT n FROM Foo', null, 10)
781
        );
782
    }
783
784
    public function testPrefersIdentityColumns() : void
785
    {
786
        self::assertTrue($this->platform->prefersIdentityColumns());
787
    }
788
789
    public function testDoesNotPreferSequences() : void
790
    {
791
        self::assertFalse($this->platform->prefersSequences());
792
    }
793
794
    public function testSupportsIdentityColumns() : void
795
    {
796
        self::assertTrue($this->platform->supportsIdentityColumns());
797
    }
798
799
    public function testSupportsPrimaryConstraints() : void
800
    {
801
        self::assertTrue($this->platform->supportsPrimaryConstraints());
802
    }
803
804
    public function testSupportsForeignKeyConstraints() : void
805
    {
806
        self::assertTrue($this->platform->supportsForeignKeyConstraints());
807
    }
808
809
    public function testSupportsForeignKeyOnUpdate() : void
810
    {
811
        self::assertTrue($this->platform->supportsForeignKeyOnUpdate());
812
    }
813
814
    public function testSupportsAlterTable() : void
815
    {
816
        self::assertTrue($this->platform->supportsAlterTable());
817
    }
818
819
    public function testSupportsTransactions() : void
820
    {
821
        self::assertTrue($this->platform->supportsTransactions());
822
    }
823
824
    public function testSupportsSchemas() : void
825
    {
826
        self::assertFalse($this->platform->supportsSchemas());
827
    }
828
829
    public function testSupportsIndexes() : void
830
    {
831
        self::assertTrue($this->platform->supportsIndexes());
832
    }
833
834
    public function testSupportsCommentOnStatement() : void
835
    {
836
        self::assertTrue($this->platform->supportsCommentOnStatement());
837
    }
838
839
    public function testSupportsSavePoints() : void
840
    {
841
        self::assertTrue($this->platform->supportsSavepoints());
842
    }
843
844
    public function testSupportsReleasePoints() : void
845
    {
846
        self::assertTrue($this->platform->supportsReleaseSavepoints());
847
    }
848
849
    public function testSupportsCreateDropDatabase() : void
850
    {
851
        self::assertTrue($this->platform->supportsCreateDropDatabase());
852
    }
853
854
    public function testSupportsGettingAffectedRows() : void
855
    {
856
        self::assertTrue($this->platform->supportsGettingAffectedRows());
857
    }
858
859
    public function testDoesNotSupportSequences() : void
860
    {
861
        self::markTestSkipped('This version of the platform now supports sequences.');
862
    }
863
864
    public function testSupportsSequences() : void
865
    {
866
        self::assertTrue($this->platform->supportsSequences());
867
    }
868
869
    public function testGeneratesSequenceSqlCommands() : void
870
    {
871
        $sequence = new Sequence('myseq', 20, 1);
872
        self::assertEquals(
873
            'CREATE SEQUENCE myseq INCREMENT BY 20 START WITH 1 MINVALUE 1',
874
            $this->platform->getCreateSequenceSQL($sequence)
875
        );
876
        self::assertEquals(
877
            'ALTER SEQUENCE myseq INCREMENT BY 20',
878
            $this->platform->getAlterSequenceSQL($sequence)
879
        );
880
        self::assertEquals(
881
            'DROP SEQUENCE myseq',
882
            $this->platform->getDropSequenceSQL('myseq')
883
        );
884
        self::assertEquals(
885
            'DROP SEQUENCE myseq',
886
            $this->platform->getDropSequenceSQL($sequence)
887
        );
888
        self::assertEquals(
889
            'SELECT myseq.NEXTVAL',
890
            $this->platform->getSequenceNextValSQL('myseq')
891
        );
892
    }
893
894
    public function testDoesNotSupportInlineColumnComments() : void
895
    {
896
        self::assertFalse($this->platform->supportsInlineColumnComments());
897
    }
898
899
    public function testCannotEmulateSchemas() : void
900
    {
901
        self::assertFalse($this->platform->canEmulateSchemas());
902
    }
903
904
    public function testInitializesDoctrineTypeMappings() : void
905
    {
906
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('integer'));
907
        self::assertSame('integer', $this->platform->getDoctrineTypeMapping('integer'));
908
909
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('binary'));
910
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('binary'));
911
912
        self::assertTrue($this->platform->hasDoctrineTypeMappingFor('varbinary'));
913
        self::assertSame('binary', $this->platform->getDoctrineTypeMapping('varbinary'));
914
    }
915
916
    public function testGetVariableLengthStringTypeDeclarationSQLNoLength() : void
917
    {
918
        $this->expectException(ColumnLengthRequired::class);
919
920
        parent::testGetVariableLengthStringTypeDeclarationSQLNoLength();
921
    }
922
923
    public function testGetVariableLengthBinaryTypeDeclarationSQLNoLength() : void
924
    {
925
        $this->expectException(ColumnLengthRequired::class);
926
927
        parent::testGetVariableLengthBinaryTypeDeclarationSQLNoLength();
928
    }
929
930
    /**
931
     * {@inheritDoc}
932
     *
933
     * @group DBAL-234
934
     */
935
    protected function getAlterTableRenameIndexSQL() : array
936
    {
937
        return ['ALTER INDEX idx_foo ON mytable RENAME TO idx_bar'];
938
    }
939
940
    /**
941
     * {@inheritDoc}
942
     *
943
     * @group DBAL-234
944
     */
945
    protected function getQuotedAlterTableRenameIndexSQL() : array
946
    {
947
        return [
948
            'ALTER INDEX "create" ON "table" RENAME TO "select"',
949
            'ALTER INDEX "foo" ON "table" RENAME TO "bar"',
950
        ];
951
    }
952
953
    /**
954
     * {@inheritdoc}
955
     */
956
    protected function getQuotedAlterTableRenameColumnSQL() : array
957
    {
958
        return [
959
            'ALTER TABLE mytable RENAME unquoted1 TO unquoted',
960
            'ALTER TABLE mytable RENAME unquoted2 TO "where"',
961
            'ALTER TABLE mytable RENAME unquoted3 TO "foo"',
962
            'ALTER TABLE mytable RENAME "create" TO reserved_keyword',
963
            'ALTER TABLE mytable RENAME "table" TO "from"',
964
            'ALTER TABLE mytable RENAME "select" TO "bar"',
965
            'ALTER TABLE mytable RENAME quoted1 TO quoted',
966
            'ALTER TABLE mytable RENAME quoted2 TO "and"',
967
            'ALTER TABLE mytable RENAME quoted3 TO "baz"',
968
        ];
969
    }
970
971
    /**
972
     * {@inheritdoc}
973
     */
974
    protected function getQuotedAlterTableChangeColumnLengthSQL() : array
975
    {
976
        self::markTestIncomplete('Not implemented yet');
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

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

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

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
977
    }
978
979
    /**
980
     * {@inheritDoc}
981
     *
982
     * @group DBAL-807
983
     */
984
    protected function getAlterTableRenameIndexInSchemaSQL() : array
985
    {
986
        return ['ALTER INDEX idx_foo ON myschema.mytable RENAME TO idx_bar'];
987
    }
988
989
    /**
990
     * {@inheritDoc}
991
     *
992
     * @group DBAL-807
993
     */
994
    protected function getQuotedAlterTableRenameIndexInSchemaSQL() : array
995
    {
996
        return [
997
            'ALTER INDEX "create" ON "schema"."table" RENAME TO "select"',
998
            'ALTER INDEX "foo" ON "schema"."table" RENAME TO "bar"',
999
        ];
1000
    }
1001
1002
    /**
1003
     * @group DBAL-423
1004
     */
1005
    public function testReturnsGuidTypeDeclarationSQL() : void
1006
    {
1007
        self::assertSame('UNIQUEIDENTIFIER', $this->platform->getGuidTypeDeclarationSQL([]));
1008
    }
1009
1010
    /**
1011
     * {@inheritdoc}
1012
     */
1013
    public function getAlterTableRenameColumnSQL() : array
1014
    {
1015
        return ['ALTER TABLE foo RENAME bar TO baz'];
1016
    }
1017
1018
    /**
1019
     * {@inheritdoc}
1020
     */
1021
    protected function getQuotesTableIdentifiersInAlterTableSQL() : array
1022
    {
1023
        return [
1024
            'ALTER TABLE "foo" DROP FOREIGN KEY fk1',
1025
            'ALTER TABLE "foo" DROP FOREIGN KEY fk2',
1026
            'ALTER TABLE "foo" RENAME id TO war',
1027
            'ALTER TABLE "foo" ADD bloo INT NOT NULL, DROP baz, ALTER bar INT DEFAULT NULL',
1028
            'ALTER TABLE "foo" RENAME "table"',
1029
            'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
1030
            'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
1031
        ];
1032
    }
1033
1034
    /**
1035
     * {@inheritdoc}
1036
     */
1037
    protected function getCommentOnColumnSQL() : array
1038
    {
1039
        return [
1040
            'COMMENT ON COLUMN foo.bar IS \'comment\'',
1041
            'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
1042
            'COMMENT ON COLUMN "select"."from" IS \'comment\'',
1043
        ];
1044
    }
1045
1046
    /**
1047
     * @group DBAL-1004
1048
     */
1049
    public function testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers() : void
1050
    {
1051
        $table1 = new Table('"foo"', [new Column('"bar"', Type::getType('integer'))]);
1052
        $table2 = new Table('"foo"', [new Column('"bar"', Type::getType('integer'), ['comment' => 'baz'])]);
1053
1054
        $comparator = new Comparator();
1055
1056
        $tableDiff = $comparator->diffTable($table1, $table2);
1057
1058
        self::assertInstanceOf(TableDiff::class, $tableDiff);
1059
        self::assertSame(
1060
            ['COMMENT ON COLUMN "foo"."bar" IS \'baz\''],
1061
            $this->platform->getAlterTableSQL($tableDiff)
1062
        );
1063
    }
1064
1065
    /**
1066
     * {@inheritdoc}
1067
     */
1068
    public static function getReturnsForeignKeyReferentialActionSQL() : iterable
1069
    {
1070
        return [
1071
            ['CASCADE', 'CASCADE'],
1072
            ['SET NULL', 'SET NULL'],
1073
            ['NO ACTION', 'RESTRICT'],
1074
            ['RESTRICT', 'RESTRICT'],
1075
            ['SET DEFAULT', 'SET DEFAULT'],
1076
            ['CaScAdE', 'CASCADE'],
1077
        ];
1078
    }
1079
1080
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL() : string
1081
    {
1082
        return 'CONSTRAINT "select" UNIQUE (foo)';
1083
    }
1084
1085
    protected function getQuotesReservedKeywordInIndexDeclarationSQL() : string
1086
    {
1087
        return ''; // not supported by this platform
1088
    }
1089
1090
    protected function getQuotesReservedKeywordInTruncateTableSQL() : string
1091
    {
1092
        return 'TRUNCATE TABLE "select"';
1093
    }
1094
1095
    protected function supportsInlineIndexDeclaration() : bool
1096
    {
1097
        return false;
1098
    }
1099
1100
    /**
1101
     * {@inheritdoc}
1102
     */
1103
    protected function getAlterStringToFixedStringSQL() : array
1104
    {
1105
        return ['ALTER TABLE mytable ALTER name CHAR(2) NOT NULL'];
1106
    }
1107
1108
    /**
1109
     * {@inheritdoc}
1110
     */
1111
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() : array
1112
    {
1113
        return ['ALTER INDEX idx_foo ON mytable RENAME TO idx_foo_renamed'];
1114
    }
1115
1116
    /**
1117
     * @group DBAL-2436
1118
     */
1119
    public function testQuotesSchemaNameInListTableColumnsSQL() : void
1120
    {
1121
        self::assertStringContainsStringIgnoringCase(
1122
            "'Foo''Bar\\'",
1123
            $this->platform->getListTableColumnsSQL("Foo'Bar\\.baz_table")
1124
        );
1125
    }
1126
1127
    /**
1128
     * @group DBAL-2436
1129
     */
1130
    public function testQuotesTableNameInListTableConstraintsSQL() : void
1131
    {
1132
        self::assertStringContainsStringIgnoringCase("'Foo''Bar\\'", $this->platform->getListTableConstraintsSQL("Foo'Bar\\"), '');
1133
    }
1134
1135
    /**
1136
     * @group DBAL-2436
1137
     */
1138
    public function testQuotesSchemaNameInListTableConstraintsSQL() : void
1139
    {
1140
        self::assertStringContainsStringIgnoringCase(
1141
            "'Foo''Bar\\'",
1142
            $this->platform->getListTableConstraintsSQL("Foo'Bar\\.baz_table")
1143
        );
1144
    }
1145
1146
    /**
1147
     * @group DBAL-2436
1148
     */
1149
    public function testQuotesTableNameInListTableForeignKeysSQL() : void
1150
    {
1151
        self::assertStringContainsStringIgnoringCase(
1152
            "'Foo''Bar\\'",
1153
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\")
1154
        );
1155
    }
1156
1157
    /**
1158
     * @group DBAL-2436
1159
     */
1160
    public function testQuotesSchemaNameInListTableForeignKeysSQL() : void
1161
    {
1162
        self::assertStringContainsStringIgnoringCase(
1163
            "'Foo''Bar\\'",
1164
            $this->platform->getListTableForeignKeysSQL("Foo'Bar\\.baz_table")
1165
        );
1166
    }
1167
1168
    /**
1169
     * @group DBAL-2436
1170
     */
1171
    public function testQuotesTableNameInListTableIndexesSQL() : void
1172
    {
1173
        self::assertStringContainsStringIgnoringCase(
1174
            "'Foo''Bar\\'",
1175
            $this->platform->getListTableIndexesSQL("Foo'Bar\\")
1176
        );
1177
    }
1178
1179
    /**
1180
     * @group DBAL-2436
1181
     */
1182
    public function testQuotesSchemaNameInListTableIndexesSQL() : void
1183
    {
1184
        self::assertStringContainsStringIgnoringCase(
1185
            "'Foo''Bar\\'",
1186
            $this->platform->getListTableIndexesSQL("Foo'Bar\\.baz_table")
1187
        );
1188
    }
1189
}
1190