Completed
Push — master ( c7757e...39cb21 )
by Luís
16s
created

Tests/DBAL/Platforms/OraclePlatformTest.php (3 issues)

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\Types\Type;
12
13
class OraclePlatformTest extends AbstractPlatformTestCase
14
{
15
    public static function dataValidIdentifiers()
16
    {
17
        return [
18
            ['a'],
19
            ['foo'],
20
            ['Foo'],
21
            ['Foo123'],
22
            ['Foo#bar_baz$'],
23
            ['"a"'],
24
            ['"1"'],
25
            ['"foo_bar"'],
26
            ['"@$%&!"'],
27
        ];
28
    }
29
30
    /**
31
     * @dataProvider dataValidIdentifiers
32
     */
33
    public function testValidIdentifiers($identifier)
34
    {
35
        $platform = $this->createPlatform();
36
        $platform->assertValidIdentifier($identifier);
37
38
        $this->addToAssertionCount(1);
39
    }
40
41
    public static function dataInvalidIdentifiers()
42
    {
43
        return [
44
            ['1'],
45
            ['abc&'],
46
            ['abc-def'],
47
            ['"'],
48
            ['"foo"bar"'],
49
        ];
50
    }
51
52
    /**
53
     * @dataProvider dataInvalidIdentifiers
54
     */
55
    public function testInvalidIdentifiers($identifier)
56
    {
57
        $this->expectException(DBALException::class);
58
59
        $platform = $this->createPlatform();
60
        $platform->assertValidIdentifier($identifier);
61
    }
62
63
    public function createPlatform()
64
    {
65
        return new OraclePlatform;
66
    }
67
68
    public function getGenerateTableSql()
69
    {
70
        return 'CREATE TABLE test (id NUMBER(10) NOT NULL, test VARCHAR2(255) DEFAULT NULL NULL, PRIMARY KEY(id))';
71
    }
72
73
    public function getGenerateTableWithMultiColumnUniqueIndexSql()
74
    {
75
        return array(
76
            'CREATE TABLE test (foo VARCHAR2(255) DEFAULT NULL NULL, bar VARCHAR2(255) DEFAULT NULL NULL)',
77
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)',
78
        );
79
    }
80
81
    public function getGenerateAlterTableSql()
82
    {
83
        return array(
84
            'ALTER TABLE mytable ADD (quota NUMBER(10) DEFAULT NULL NULL)',
85
            "ALTER TABLE mytable MODIFY (baz VARCHAR2(255) DEFAULT 'def' NOT NULL, bloo NUMBER(1) DEFAULT '0' NOT NULL)",
86
            "ALTER TABLE mytable DROP (foo)",
87
            "ALTER TABLE mytable RENAME TO userlist",
88
        );
89
    }
90
91
    /**
92
     * @expectedException \Doctrine\DBAL\DBALException
93
     */
94
    public function testRLike()
95
    {
96
        self::assertEquals('RLIKE', $this->_platform->getRegexpExpression(), 'Regular expression operator is not correct');
97
    }
98
99
    public function testGeneratesSqlSnippets()
100
    {
101
        self::assertEquals('"', $this->_platform->getIdentifierQuoteCharacter(), 'Identifier quote character is not correct');
102
        self::assertEquals('column1 || column2 || column3', $this->_platform->getConcatExpression('column1', 'column2', 'column3'), 'Concatenation expression is not correct');
103
    }
104
105 View Code Duplication
    public function testGeneratesTransactionsCommands()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
106
    {
107
        self::assertEquals(
108
            'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED',
109
            $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED)
110
        );
111
        self::assertEquals(
112
            'SET TRANSACTION ISOLATION LEVEL READ COMMITTED',
113
            $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED)
114
        );
115
        self::assertEquals(
116
            'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE',
117
            $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ)
118
        );
119
        self::assertEquals(
120
            'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE',
121
            $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE)
122
        );
123
    }
124
125
    /**
126
     * @expectedException \Doctrine\DBAL\DBALException
127
     */
128
    public function testCreateDatabaseThrowsException()
129
    {
130
        self::assertEquals('CREATE DATABASE foobar', $this->_platform->getCreateDatabaseSQL('foobar'));
131
    }
132
133
    public function testDropDatabaseThrowsException()
134
    {
135
        self::assertEquals('DROP USER foobar CASCADE', $this->_platform->getDropDatabaseSQL('foobar'));
136
    }
137
138
    public function testDropTable()
139
    {
140
        self::assertEquals('DROP TABLE foobar', $this->_platform->getDropTableSQL('foobar'));
141
    }
142
143 View Code Duplication
    public function testGeneratesTypeDeclarationForIntegers()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
144
    {
145
        self::assertEquals(
146
            'NUMBER(10)',
147
            $this->_platform->getIntegerTypeDeclarationSQL(array())
148
        );
149
        self::assertEquals(
150
            'NUMBER(10)',
151
            $this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true)
152
            ));
153
        self::assertEquals(
154
            'NUMBER(10)',
155
            $this->_platform->getIntegerTypeDeclarationSQL(
156
                array('autoincrement' => true, 'primary' => true)
157
            ));
158
    }
159
160 View Code Duplication
    public function testGeneratesTypeDeclarationsForStrings()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

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