Passed
Pull Request — master (#3120)
by Sergei
12:25
created

OraclePlatformTest   F

Complexity

Total Complexity 80

Size/Duplication

Total Lines 863
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 80
dl 0
loc 863
rs 1.263
c 0
b 0
f 0

How to fix   Complexity   

Complex Class

Complex classes like OraclePlatformTest 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 OraclePlatformTest, 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\Platforms\OraclePlatform;
7
use Doctrine\DBAL\Schema\Column;
8
use Doctrine\DBAL\Schema\Comparator;
9
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
10
use Doctrine\DBAL\Schema\Table;
11
use Doctrine\DBAL\TransactionIsolationLevel;
12
use Doctrine\DBAL\Types\Type;
13
use function array_walk;
14
use function preg_replace;
15
use function strtoupper;
16
use function uniqid;
17
18
class OraclePlatformTest extends AbstractPlatformTestCase
19
{
20
    public static function dataValidIdentifiers()
21
    {
22
        return [
23
            ['a'],
24
            ['foo'],
25
            ['Foo'],
26
            ['Foo123'],
27
            ['Foo#bar_baz$'],
28
            ['"a"'],
29
            ['"1"'],
30
            ['"foo_bar"'],
31
            ['"@$%&!"'],
32
        ];
33
    }
34
35
    /**
36
     * @dataProvider dataValidIdentifiers
37
     */
38
    public function testValidIdentifiers($identifier)
39
    {
40
        $platform = $this->createPlatform();
41
        $platform->assertValidIdentifier($identifier);
42
43
        $this->addToAssertionCount(1);
44
    }
45
46
    public static function dataInvalidIdentifiers()
47
    {
48
        return [
49
            ['1'],
50
            ['abc&'],
51
            ['abc-def'],
52
            ['"'],
53
            ['"foo"bar"'],
54
        ];
55
    }
56
57
    /**
58
     * @dataProvider dataInvalidIdentifiers
59
     */
60
    public function testInvalidIdentifiers($identifier)
61
    {
62
        $this->expectException(DBALException::class);
63
64
        $platform = $this->createPlatform();
65
        $platform->assertValidIdentifier($identifier);
66
    }
67
68
    public function createPlatform()
69
    {
70
        return new OraclePlatform;
71
    }
72
73
    public function getGenerateTableSql()
74
    {
75
        return 'CREATE TABLE test (id NUMBER(10) NOT NULL, test VARCHAR2(255) DEFAULT NULL NULL, PRIMARY KEY(id))';
76
    }
77
78
    public function getGenerateTableWithMultiColumnUniqueIndexSql()
79
    {
80
        return array(
81
            'CREATE TABLE test (foo VARCHAR2(255) DEFAULT NULL NULL, bar VARCHAR2(255) DEFAULT NULL NULL)',
82
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)',
83
        );
84
    }
85
86
    public function getGenerateAlterTableSql()
87
    {
88
        return array(
89
            'ALTER TABLE mytable ADD (quota NUMBER(10) DEFAULT NULL NULL)',
90
            "ALTER TABLE mytable MODIFY (baz VARCHAR2(255) DEFAULT 'def' NOT NULL, bloo NUMBER(1) DEFAULT '0' NOT NULL)",
91
            "ALTER TABLE mytable DROP (foo)",
92
            "ALTER TABLE mytable RENAME TO userlist",
93
        );
94
    }
95
96
    /**
97
     * @expectedException \Doctrine\DBAL\DBALException
98
     */
99
    public function testRLike()
100
    {
101
        self::assertEquals('RLIKE', $this->_platform->getRegexpExpression(), 'Regular expression operator is not correct');
102
    }
103
104
    public function testGeneratesSqlSnippets()
105
    {
106
        self::assertEquals('"', $this->_platform->getIdentifierQuoteCharacter(), 'Identifier quote character is not correct');
107
        self::assertEquals('column1 || column2 || column3', $this->_platform->getConcatExpression('column1', 'column2', 'column3'), 'Concatenation expression is not correct');
108
    }
109
110
    public function testGeneratesTransactionsCommands()
111
    {
112
        self::assertEquals(
113
            'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED',
114
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_UNCOMMITTED)
115
        );
116
        self::assertEquals(
117
            'SET TRANSACTION ISOLATION LEVEL READ COMMITTED',
118
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_COMMITTED)
119
        );
120
        self::assertEquals(
121
            'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE',
122
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::REPEATABLE_READ)
123
        );
124
        self::assertEquals(
125
            'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE',
126
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::SERIALIZABLE)
127
        );
128
    }
129
130
    /**
131
     * @expectedException \Doctrine\DBAL\DBALException
132
     */
133
    public function testCreateDatabaseThrowsException()
134
    {
135
        self::assertEquals('CREATE DATABASE foobar', $this->_platform->getCreateDatabaseSQL('foobar'));
136
    }
137
138
    public function testDropDatabaseThrowsException()
139
    {
140
        self::assertEquals('DROP USER foobar CASCADE', $this->_platform->getDropDatabaseSQL('foobar'));
141
    }
142
143
    public function testDropTable()
144
    {
145
        self::assertEquals('DROP TABLE foobar', $this->_platform->getDropTableSQL('foobar'));
146
    }
147
148
    public function testGeneratesTypeDeclarationForIntegers()
149
    {
150
        self::assertEquals(
151
            'NUMBER(10)',
152
            $this->_platform->getIntegerTypeDeclarationSQL(array())
153
        );
154
        self::assertEquals(
155
            'NUMBER(10)',
156
            $this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true)
157
            ));
158
        self::assertEquals(
159
            'NUMBER(10)',
160
            $this->_platform->getIntegerTypeDeclarationSQL(
161
                array('autoincrement' => true, 'primary' => true)
162
            ));
163
    }
164
165
    public function testGeneratesTypeDeclarationsForStrings()
166
    {
167
        self::assertEquals(
168
            'CHAR(10)',
169
            $this->_platform->getVarcharTypeDeclarationSQL(
170
                array('length' => 10, 'fixed' => true)
171
            ));
172
        self::assertEquals(
173
            'VARCHAR2(50)',
174
            $this->_platform->getVarcharTypeDeclarationSQL(array('length' => 50)),
175
            'Variable string declaration is not correct'
176
        );
177
        self::assertEquals(
178
            'VARCHAR2(255)',
179
            $this->_platform->getVarcharTypeDeclarationSQL(array()),
180
            'Long string declaration is not correct'
181
        );
182
    }
183
184
    public function testPrefersIdentityColumns()
185
    {
186
        self::assertFalse($this->_platform->prefersIdentityColumns());
187
    }
188
189
    public function testSupportsIdentityColumns()
190
    {
191
        self::assertFalse($this->_platform->supportsIdentityColumns());
192
    }
193
194
    public function testSupportsSavePoints()
195
    {
196
        self::assertTrue($this->_platform->supportsSavepoints());
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202
    protected function supportsCommentOnStatement()
203
    {
204
        return true;
205
    }
206
207
    public function getGenerateIndexSql()
208
    {
209
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
210
    }
211
212
    public function getGenerateUniqueIndexSql()
213
    {
214
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
215
    }
216
217
    public function getGenerateForeignKeySql()
218
    {
219
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
220
    }
221
222
    /**
223
     * @group DBAL-1097
224
     *
225
     * @dataProvider getGeneratesAdvancedForeignKeyOptionsSQLData
226
     */
227
    public function testGeneratesAdvancedForeignKeyOptionsSQL(array $options, $expectedSql)
228
    {
229
        $foreignKey = new ForeignKeyConstraint(array('foo'), 'foreign_table', array('bar'), null, $options);
230
231
        self::assertSame($expectedSql, $this->_platform->getAdvancedForeignKeyOptionsSQL($foreignKey));
232
    }
233
234
    /**
235
     * @return array
236
     */
237
    public function getGeneratesAdvancedForeignKeyOptionsSQLData()
238
    {
239
        return array(
240
            array(array(), ''),
241
            array(array('onUpdate' => 'CASCADE'), ''),
242
            array(array('onDelete' => 'CASCADE'), ' ON DELETE CASCADE'),
243
            array(array('onDelete' => 'NO ACTION'), ''),
244
            array(array('onDelete' => 'RESTRICT'), ''),
245
            array(array('onUpdate' => 'SET NULL', 'onDelete' => 'SET NULL'), ' ON DELETE SET NULL'),
246
        );
247
    }
248
249
    /**
250
     * {@inheritdoc}
251
     */
252
    public function getReturnsForeignKeyReferentialActionSQL()
253
    {
254
        return array(
255
            array('CASCADE', 'CASCADE'),
256
            array('SET NULL', 'SET NULL'),
257
            array('NO ACTION', ''),
258
            array('RESTRICT', ''),
259
            array('CaScAdE', 'CASCADE'),
260
        );
261
    }
262
263
    public function testModifyLimitQuery()
264
    {
265
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 0);
266
        self::assertEquals('SELECT a.* FROM (SELECT * FROM user) a WHERE ROWNUM <= 10', $sql);
267
    }
268
269
    public function testModifyLimitQueryWithEmptyOffset()
270
    {
271
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10);
272
        self::assertEquals('SELECT a.* FROM (SELECT * FROM user) a WHERE ROWNUM <= 10', $sql);
273
    }
274
275
    public function testModifyLimitQueryWithNonEmptyOffset()
276
    {
277
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 10);
278
        self::assertEquals('SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT * FROM user) a WHERE ROWNUM <= 20) WHERE doctrine_rownum >= 11', $sql);
279
    }
280
281
    public function testModifyLimitQueryWithEmptyLimit()
282
    {
283
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', null, 10);
284
        self::assertEquals('SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT * FROM user) a) WHERE doctrine_rownum >= 11', $sql);
285
    }
286
287
    public function testModifyLimitQueryWithAscOrderBy()
288
    {
289
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username ASC', 10);
290
        self::assertEquals('SELECT a.* FROM (SELECT * FROM user ORDER BY username ASC) a WHERE ROWNUM <= 10', $sql);
291
    }
292
293
    public function testModifyLimitQueryWithDescOrderBy()
294
    {
295
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username DESC', 10);
296
        self::assertEquals('SELECT a.* FROM (SELECT * FROM user ORDER BY username DESC) a WHERE ROWNUM <= 10', $sql);
297
    }
298
299
    public function testGenerateTableWithAutoincrement()
300
    {
301
        $columnName = strtoupper('id' . uniqid());
302
        $tableName = strtoupper('table' . uniqid());
303
        $table = new \Doctrine\DBAL\Schema\Table($tableName);
304
        $column = $table->addColumn($columnName, 'integer');
305
        $column->setAutoincrement(true);
306
        $targets = array(
307
            "CREATE TABLE {$tableName} ({$columnName} NUMBER(10) NOT NULL)",
308
            "DECLARE constraints_Count NUMBER; BEGIN SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = '{$tableName}' AND CONSTRAINT_TYPE = 'P'; IF constraints_Count = 0 OR constraints_Count = '' THEN EXECUTE IMMEDIATE 'ALTER TABLE {$tableName} ADD CONSTRAINT {$tableName}_AI_PK PRIMARY KEY ({$columnName})'; END IF; END;",
309
            "CREATE SEQUENCE {$tableName}_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1",
310
            "CREATE TRIGGER {$tableName}_AI_PK BEFORE INSERT ON {$tableName} FOR EACH ROW DECLARE last_Sequence NUMBER; last_InsertID NUMBER; BEGIN SELECT {$tableName}_SEQ.NEXTVAL INTO :NEW.{$columnName} FROM DUAL; IF (:NEW.{$columnName} IS NULL OR :NEW.{$columnName} = 0) THEN SELECT {$tableName}_SEQ.NEXTVAL INTO :NEW.{$columnName} FROM DUAL; ELSE SELECT NVL(Last_Number, 0) INTO last_Sequence FROM User_Sequences WHERE Sequence_Name = '{$tableName}_SEQ'; SELECT :NEW.{$columnName} INTO last_InsertID FROM DUAL; WHILE (last_InsertID > last_Sequence) LOOP SELECT {$tableName}_SEQ.NEXTVAL INTO last_Sequence FROM DUAL; END LOOP; END IF; END;"
311
        );
312
        $statements = $this->_platform->getCreateTableSQL($table);
313
        //strip all the whitespace from the statements
314
        array_walk($statements, function(&$value){
315
            $value = preg_replace('/\s+/', ' ',$value);
316
        });
317
        foreach($targets as $key => $sql){
318
            self::assertArrayHasKey($key,$statements);
319
            self::assertEquals($sql, $statements[$key]);
320
        }
321
    }
322
323
    public function getCreateTableColumnCommentsSQL()
324
    {
325
        return array(
326
            "CREATE TABLE test (id NUMBER(10) NOT NULL, PRIMARY KEY(id))",
327
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
328
        );
329
    }
330
331
    public function getCreateTableColumnTypeCommentsSQL()
332
    {
333
        return array(
334
            "CREATE TABLE test (id NUMBER(10) NOT NULL, data CLOB NOT NULL, PRIMARY KEY(id))",
335
            "COMMENT ON COLUMN test.data IS '(DC2Type:array)'"
336
        );
337
    }
338
339
    public function getAlterTableColumnCommentsSQL()
340
    {
341
        return array(
342
            "ALTER TABLE mytable ADD (quota NUMBER(10) NOT NULL)",
343
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
344
            "COMMENT ON COLUMN mytable.foo IS ''",
345
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
346
        );
347
    }
348
349
    public function getBitAndComparisonExpressionSql($value1, $value2)
350
    {
351
        return 'BITAND('.$value1 . ', ' . $value2 . ')';
352
    }
353
354
    public function getBitOrComparisonExpressionSql($value1, $value2)
355
    {
356
        return '(' . $value1 . '-' .
357
        $this->getBitAndComparisonExpressionSql($value1, $value2)
358
        . '+' . $value2 . ')';
359
    }
360
361
    protected function getQuotedColumnInPrimaryKeySQL()
362
    {
363
        return array('CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL, PRIMARY KEY("create"))');
364
    }
365
366
    protected function getQuotedColumnInIndexSQL()
367
    {
368
        return array(
369
            'CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL)',
370
            'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")',
371
        );
372
    }
373
374
    protected function getQuotedNameInIndexSQL()
375
    {
376
        return array(
377
            'CREATE TABLE test (column1 VARCHAR2(255) NOT NULL)',
378
            'CREATE INDEX "key" ON test (column1)',
379
        );
380
    }
381
382
    protected function getQuotedColumnInForeignKeySQL()
383
    {
384
        return array(
385
            'CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL, foo VARCHAR2(255) NOT NULL, "bar" VARCHAR2(255) NOT NULL)',
386
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foreign ("create", bar, "foo-bar")',
387
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foo ("create", bar, "foo-bar")',
388
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar")',
389
        );
390
    }
391
392
    /**
393
     * @group DBAL-472
394
     * @group DBAL-1001
395
     */
396
    public function testAlterTableNotNULL()
397
    {
398
        $tableDiff = new \Doctrine\DBAL\Schema\TableDiff('mytable');
399
        $tableDiff->changedColumns['foo'] = new \Doctrine\DBAL\Schema\ColumnDiff(
400
            'foo', new \Doctrine\DBAL\Schema\Column(
401
                'foo', \Doctrine\DBAL\Types\Type::getType('string'), array('default' => 'bla', 'notnull' => true)
402
            ),
403
            array('type')
404
        );
405
        $tableDiff->changedColumns['bar'] = new \Doctrine\DBAL\Schema\ColumnDiff(
406
            'bar', new \Doctrine\DBAL\Schema\Column(
407
                'baz', \Doctrine\DBAL\Types\Type::getType('string'), array('default' => 'bla', 'notnull' => true)
408
            ),
409
            array('type', 'notnull')
410
        );
411
        $tableDiff->changedColumns['metar'] = new \Doctrine\DBAL\Schema\ColumnDiff(
412
            'metar', new \Doctrine\DBAL\Schema\Column(
413
                'metar', \Doctrine\DBAL\Types\Type::getType('string'), array('length' => 2000, 'notnull' => false)
414
            ),
415
            array('notnull')
416
        );
417
418
        $expectedSql = array(
419
            "ALTER TABLE mytable MODIFY (foo VARCHAR2(255) DEFAULT 'bla', baz VARCHAR2(255) DEFAULT 'bla' NOT NULL, metar VARCHAR2(2000) DEFAULT NULL NULL)",
420
        );
421
        self::assertEquals($expectedSql, $this->_platform->getAlterTableSQL($tableDiff));
422
    }
423
424
    /**
425
     * @group DBAL-2555
426
     */
427
    public function testInitializesDoctrineTypeMappings()
428
    {
429
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('long raw'));
430
        self::assertSame('blob', $this->_platform->getDoctrineTypeMapping('long raw'));
431
432
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('raw'));
433
        self::assertSame('binary', $this->_platform->getDoctrineTypeMapping('raw'));
434
435
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('date'));
436
        self::assertSame('date', $this->_platform->getDoctrineTypeMapping('date'));
437
    }
438
439
    protected function getBinaryMaxLength()
440
    {
441
        return 2000;
442
    }
443
444
    public function testReturnsBinaryTypeDeclarationSQL()
445
    {
446
        self::assertSame('RAW(255)', $this->_platform->getBinaryTypeDeclarationSQL(array()));
447
        self::assertSame('RAW(2000)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
448
        self::assertSame('RAW(2000)', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 2000)));
449
        self::assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 2001)));
450
451
        self::assertSame('RAW(255)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
452
        self::assertSame('RAW(2000)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
453
        self::assertSame('RAW(2000)', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 2000)));
454
        self::assertSame('BLOB', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 2001)));
455
    }
456
457
    public function testDoesNotPropagateUnnecessaryTableAlterationOnBinaryType()
458
    {
459
        $table1 = new Table('mytable');
460
        $table1->addColumn('column_varbinary', 'binary');
461
        $table1->addColumn('column_binary', 'binary', array('fixed' => true));
462
463
        $table2 = new Table('mytable');
464
        $table2->addColumn('column_varbinary', 'binary', array('fixed' => true));
465
        $table2->addColumn('column_binary', 'binary');
466
467
        $comparator = new Comparator();
468
469
        // VARBINARY -> BINARY
470
        // BINARY    -> VARBINARY
471
        self::assertEmpty($this->_platform->getAlterTableSQL($comparator->diffTable($table1, $table2)));
472
    }
473
474
    /**
475
     * @group DBAL-563
476
     */
477
    public function testUsesSequenceEmulatedIdentityColumns()
478
    {
479
        self::assertTrue($this->_platform->usesSequenceEmulatedIdentityColumns());
480
    }
481
482
    /**
483
     * @group DBAL-563
484
     * @group DBAL-831
485
     */
486
    public function testReturnsIdentitySequenceName()
487
    {
488
        self::assertSame('MYTABLE_SEQ', $this->_platform->getIdentitySequenceName('mytable', 'mycolumn'));
489
        self::assertSame('"mytable_SEQ"', $this->_platform->getIdentitySequenceName('"mytable"', 'mycolumn'));
490
        self::assertSame('MYTABLE_SEQ', $this->_platform->getIdentitySequenceName('mytable', '"mycolumn"'));
491
        self::assertSame('"mytable_SEQ"', $this->_platform->getIdentitySequenceName('"mytable"', '"mycolumn"'));
492
    }
493
494
    /**
495
     * @dataProvider dataCreateSequenceWithCache
496
     * @group DBAL-139
497
     */
498
    public function testCreateSequenceWithCache($cacheSize, $expectedSql)
499
    {
500
        $sequence = new \Doctrine\DBAL\Schema\Sequence('foo', 1, 1, $cacheSize);
501
        self::assertContains($expectedSql, $this->_platform->getCreateSequenceSQL($sequence));
502
    }
503
504
    public function dataCreateSequenceWithCache()
505
    {
506
        return array(
507
            array(1, 'NOCACHE'),
508
            array(0, 'NOCACHE'),
509
            array(3, 'CACHE 3')
510
        );
511
    }
512
513
    /**
514
     * @group DBAL-234
515
     */
516
    protected function getAlterTableRenameIndexSQL()
517
    {
518
        return array(
519
            'ALTER INDEX idx_foo RENAME TO idx_bar',
520
        );
521
    }
522
523
    /**
524
     * @group DBAL-234
525
     */
526
    protected function getQuotedAlterTableRenameIndexSQL()
527
    {
528
        return array(
529
            'ALTER INDEX "create" RENAME TO "select"',
530
            'ALTER INDEX "foo" RENAME TO "bar"',
531
        );
532
    }
533
534
    /**
535
     * {@inheritdoc}
536
     */
537
    protected function getQuotedAlterTableRenameColumnSQL()
538
    {
539
        return array(
540
            'ALTER TABLE mytable RENAME COLUMN unquoted1 TO unquoted',
541
            'ALTER TABLE mytable RENAME COLUMN unquoted2 TO "where"',
542
            'ALTER TABLE mytable RENAME COLUMN unquoted3 TO "foo"',
543
            'ALTER TABLE mytable RENAME COLUMN "create" TO reserved_keyword',
544
            'ALTER TABLE mytable RENAME COLUMN "table" TO "from"',
545
            'ALTER TABLE mytable RENAME COLUMN "select" TO "bar"',
546
            'ALTER TABLE mytable RENAME COLUMN quoted1 TO quoted',
547
            'ALTER TABLE mytable RENAME COLUMN quoted2 TO "and"',
548
            'ALTER TABLE mytable RENAME COLUMN quoted3 TO "baz"',
549
        );
550
    }
551
552
    /**
553
     * {@inheritdoc}
554
     */
555
    protected function getQuotedAlterTableChangeColumnLengthSQL()
556
    {
557
        $this->markTestIncomplete('Not implemented yet');
558
    }
559
560
    /**
561
     * @group DBAL-807
562
     */
563
    protected function getAlterTableRenameIndexInSchemaSQL()
564
    {
565
        return array(
566
            'ALTER INDEX myschema.idx_foo RENAME TO idx_bar',
567
        );
568
    }
569
570
    /**
571
     * @group DBAL-807
572
     */
573
    protected function getQuotedAlterTableRenameIndexInSchemaSQL()
574
    {
575
        return array(
576
            'ALTER INDEX "schema"."create" RENAME TO "select"',
577
            'ALTER INDEX "schema"."foo" RENAME TO "bar"',
578
        );
579
    }
580
581
    protected function getQuotesDropForeignKeySQL()
582
    {
583
        return 'ALTER TABLE "table" DROP CONSTRAINT "select"';
584
    }
585
586
    /**
587
     * @group DBAL-423
588
     */
589
    public function testReturnsGuidTypeDeclarationSQL()
590
    {
591
        self::assertSame('CHAR(36)', $this->_platform->getGuidTypeDeclarationSQL(array()));
592
    }
593
594
    /**
595
     * {@inheritdoc}
596
     */
597
    public function getAlterTableRenameColumnSQL()
598
    {
599
        return array(
600
            'ALTER TABLE foo RENAME COLUMN bar TO baz',
601
        );
602
    }
603
604
    /**
605
     * @dataProvider getReturnsDropAutoincrementSQL
606
     * @group DBAL-831
607
     */
608
    public function testReturnsDropAutoincrementSQL($table, $expectedSql)
609
    {
610
        self::assertSame($expectedSql, $this->_platform->getDropAutoincrementSql($table));
611
    }
612
613
    public function getReturnsDropAutoincrementSQL()
614
    {
615
        return array(
616
            array(
617
                'myTable',
618
                array(
619
                    'DROP TRIGGER MYTABLE_AI_PK',
620
                    'DROP SEQUENCE MYTABLE_SEQ',
621
                    'ALTER TABLE MYTABLE DROP CONSTRAINT MYTABLE_AI_PK',
622
                )
623
            ),
624
            array(
625
                '"myTable"',
626
                array(
627
                    'DROP TRIGGER "myTable_AI_PK"',
628
                    'DROP SEQUENCE "myTable_SEQ"',
629
                    'ALTER TABLE "myTable" DROP CONSTRAINT "myTable_AI_PK"',
630
                )
631
            ),
632
            array(
633
                'table',
634
                array(
635
                    'DROP TRIGGER TABLE_AI_PK',
636
                    'DROP SEQUENCE TABLE_SEQ',
637
                    'ALTER TABLE "TABLE" DROP CONSTRAINT TABLE_AI_PK',
638
                )
639
            ),
640
        );
641
    }
642
643
    /**
644
     * {@inheritdoc}
645
     */
646
    protected function getQuotesTableIdentifiersInAlterTableSQL()
647
    {
648
        return array(
649
            'ALTER TABLE "foo" DROP CONSTRAINT fk1',
650
            'ALTER TABLE "foo" DROP CONSTRAINT fk2',
651
            'ALTER TABLE "foo" ADD (bloo NUMBER(10) NOT NULL)',
652
            'ALTER TABLE "foo" MODIFY (bar NUMBER(10) DEFAULT NULL NULL)',
653
            'ALTER TABLE "foo" RENAME COLUMN id TO war',
654
            'ALTER TABLE "foo" DROP (baz)',
655
            'ALTER TABLE "foo" RENAME TO "table"',
656
            'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
657
            'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
658
        );
659
    }
660
661
    /**
662
     * {@inheritdoc}
663
     */
664
    protected function getCommentOnColumnSQL()
665
    {
666
        return array(
667
            'COMMENT ON COLUMN foo.bar IS \'comment\'',
668
            'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
669
            'COMMENT ON COLUMN "select"."from" IS \'comment\'',
670
        );
671
    }
672
673
    /**
674
     * @group DBAL-1004
675
     */
676
    public function testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers()
677
    {
678
        $table1 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'))));
679
        $table2 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'), array('comment' => 'baz'))));
680
681
        $comparator = new Comparator();
682
683
        $tableDiff = $comparator->diffTable($table1, $table2);
684
685
        self::assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
686
        self::assertSame(
687
            array(
688
                'COMMENT ON COLUMN "foo"."bar" IS \'baz\'',
689
            ),
690
            $this->_platform->getAlterTableSQL($tableDiff)
691
        );
692
    }
693
694
    public function testQuotedTableNames()
695
    {
696
        $table = new Table('"test"');
697
        $table->addColumn('"id"', 'integer', array('autoincrement' => true));
698
699
        // assert tabel
700
        self::assertTrue($table->isQuoted());
701
        self::assertEquals('test', $table->getName());
702
        self::assertEquals('"test"', $table->getQuotedName($this->_platform));
703
704
        $sql = $this->_platform->getCreateTableSQL($table);
705
        self::assertEquals('CREATE TABLE "test" ("id" NUMBER(10) NOT NULL)', $sql[0]);
706
        self::assertEquals('CREATE SEQUENCE "test_SEQ" START WITH 1 MINVALUE 1 INCREMENT BY 1', $sql[2]);
707
        $createTriggerStatement = <<<EOD
708
CREATE TRIGGER "test_AI_PK"
709
   BEFORE INSERT
710
   ON "test"
711
   FOR EACH ROW
712
DECLARE
713
   last_Sequence NUMBER;
714
   last_InsertID NUMBER;
715
BEGIN
716
   SELECT "test_SEQ".NEXTVAL INTO :NEW."id" FROM DUAL;
717
   IF (:NEW."id" IS NULL OR :NEW."id" = 0) THEN
718
      SELECT "test_SEQ".NEXTVAL INTO :NEW."id" FROM DUAL;
719
   ELSE
720
      SELECT NVL(Last_Number, 0) INTO last_Sequence
721
        FROM User_Sequences
722
       WHERE Sequence_Name = 'test_SEQ';
723
      SELECT :NEW."id" INTO last_InsertID FROM DUAL;
724
      WHILE (last_InsertID > last_Sequence) LOOP
725
         SELECT "test_SEQ".NEXTVAL INTO last_Sequence FROM DUAL;
726
      END LOOP;
727
   END IF;
728
END;
729
EOD;
730
731
        self::assertEquals($createTriggerStatement, $sql[3]);
732
    }
733
734
    /**
735
     * @dataProvider getReturnsGetListTableColumnsSQL
736
     * @group DBAL-831
737
     */
738
    public function testReturnsGetListTableColumnsSQL($database, $expectedSql)
739
    {
740
        // note: this assertion is a bit strict, as it compares a full SQL string.
741
        // Should this break in future, then please try to reduce the matching to substring matching while reworking
742
        // the tests
743
        self::assertEquals($expectedSql, $this->_platform->getListTableColumnsSQL('"test"', $database));
744
    }
745
746
    public function getReturnsGetListTableColumnsSQL()
747
    {
748
        return array(
749
            array(
750
                null,
751
                "SELECT   c.*,
752
                         (
753
                             SELECT d.comments
754
                             FROM   user_col_comments d
755
                             WHERE  d.TABLE_NAME = c.TABLE_NAME 
756
                             AND    d.COLUMN_NAME = c.COLUMN_NAME
757
                         ) AS comments
758
                FROM     user_tab_columns c
759
                WHERE    c.table_name = 'test' 
760
                ORDER BY c.column_id"
761
            ),
762
            array(
763
                '/',
764
                "SELECT   c.*,
765
                         (
766
                             SELECT d.comments
767
                             FROM   user_col_comments d
768
                             WHERE  d.TABLE_NAME = c.TABLE_NAME 
769
                             AND    d.COLUMN_NAME = c.COLUMN_NAME
770
                         ) AS comments
771
                FROM     user_tab_columns c
772
                WHERE    c.table_name = 'test' 
773
                ORDER BY c.column_id"
774
            ),
775
            array(
776
                'scott',
777
                "SELECT   c.*,
778
                         (
779
                             SELECT d.comments
780
                             FROM   all_col_comments d
781
                             WHERE  d.TABLE_NAME = c.TABLE_NAME AND d.OWNER = c.OWNER
782
                             AND    d.COLUMN_NAME = c.COLUMN_NAME
783
                         ) AS comments
784
                FROM     all_tab_columns c
785
                WHERE    c.table_name = 'test' AND c.owner = 'SCOTT'
786
                ORDER BY c.column_id"
787
            ),
788
        );
789
    }
790
791
    /**
792
     * {@inheritdoc}
793
     */
794
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL()
795
    {
796
        return 'CONSTRAINT "select" UNIQUE (foo)';
797
    }
798
799
    /**
800
     * {@inheritdoc}
801
     */
802
    protected function getQuotesReservedKeywordInIndexDeclarationSQL()
803
    {
804
        return 'INDEX "select" (foo)';
805
    }
806
807
    /**
808
     * {@inheritdoc}
809
     */
810
    protected function getQuotesReservedKeywordInTruncateTableSQL()
811
    {
812
        return 'TRUNCATE TABLE "select"';
813
    }
814
815
    /**
816
     * {@inheritdoc}
817
     */
818
    protected function getAlterStringToFixedStringSQL()
819
    {
820
        return array(
821
            'ALTER TABLE mytable MODIFY (name CHAR(2) DEFAULT NULL)',
822
        );
823
    }
824
825
    /**
826
     * {@inheritdoc}
827
     */
828
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL()
829
    {
830
        return array(
831
            'ALTER INDEX idx_foo RENAME TO idx_foo_renamed',
832
        );
833
    }
834
835
    /**
836
     * @group DBAL-2436
837
     */
838
    public function testQuotesDatabaseNameInListSequencesSQL()
839
    {
840
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListSequencesSQL("Foo'Bar\\"), '', true);
841
    }
842
843
    /**
844
     * @group DBAL-2436
845
     */
846
    public function testQuotesTableNameInListTableIndexesSQL()
847
    {
848
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\"), '', true);
849
    }
850
851
    /**
852
     * @group DBAL-2436
853
     */
854
    public function testQuotesTableNameInListTableForeignKeysSQL()
855
    {
856
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true);
857
    }
858
859
    /**
860
     * @group DBAL-2436
861
     */
862
    public function testQuotesTableNameInListTableConstraintsSQL()
863
    {
864
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true);
865
    }
866
867
    /**
868
     * @group DBAL-2436
869
     */
870
    public function testQuotesTableNameInListTableColumnsSQL()
871
    {
872
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableColumnsSQL("Foo'Bar\\"), '', true);
873
    }
874
875
    /**
876
     * @group DBAL-2436
877
     */
878
    public function testQuotesDatabaseNameInListTableColumnsSQL()
879
    {
880
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableColumnsSQL('foo_table', "Foo'Bar\\"), '', true);
881
    }
882
}
883