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

AbstractPostgreSqlPlatformTestCase   F

Complexity

Total Complexity 80

Size/Duplication

Total Lines 966
Duplicated Lines 0 %

Importance

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

How to fix   Complexity   

Complex Class

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

1
<?php
2
3
namespace Doctrine\Tests\DBAL\Platforms;
4
5
use Doctrine\DBAL\Schema\Column;
6
use Doctrine\DBAL\Schema\Comparator;
7
use Doctrine\DBAL\Schema\Table;
8
use Doctrine\DBAL\Schema\TableDiff;
9
use Doctrine\DBAL\TransactionIsolationLevel;
10
use Doctrine\DBAL\Types\Type;
11
12
abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCase
13
{
14
    public function getGenerateTableSql()
15
    {
16
        return 'CREATE TABLE test (id SERIAL NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))';
17
    }
18
19
    public function getGenerateTableWithMultiColumnUniqueIndexSql()
20
    {
21
        return array(
22
            'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)',
23
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)'
24
        );
25
    }
26
27
    public function getGenerateAlterTableSql()
28
    {
29
        return array(
30
            'ALTER TABLE mytable ADD quota INT DEFAULT NULL',
31
            'ALTER TABLE mytable DROP foo',
32
            'ALTER TABLE mytable ALTER bar TYPE VARCHAR(255)',
33
            "ALTER TABLE mytable ALTER bar SET DEFAULT 'def'",
34
            'ALTER TABLE mytable ALTER bar SET NOT NULL',
35
            'ALTER TABLE mytable ALTER bloo TYPE BOOLEAN',
36
            "ALTER TABLE mytable ALTER bloo SET DEFAULT 'false'",
37
            'ALTER TABLE mytable ALTER bloo SET NOT NULL',
38
            'ALTER TABLE mytable RENAME TO userlist',
39
        );
40
    }
41
42
    public function getGenerateIndexSql()
43
    {
44
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
45
    }
46
47
    public function getGenerateForeignKeySql()
48
    {
49
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id) NOT DEFERRABLE INITIALLY IMMEDIATE';
50
    }
51
52
    public function testGeneratesForeignKeySqlForNonStandardOptions()
53
    {
54
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
55
                array('foreign_id'), 'my_table', array('id'), 'my_fk', array('onDelete' => 'CASCADE')
56
        );
57
        self::assertEquals(
58
            "CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE",
59
            $this->_platform->getForeignKeyDeclarationSQL($foreignKey)
60
        );
61
62
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
63
            array('foreign_id'), 'my_table', array('id'), 'my_fk', array('match' => 'full')
64
        );
65
        self::assertEquals(
66
            "CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) MATCH full NOT DEFERRABLE INITIALLY IMMEDIATE",
67
            $this->_platform->getForeignKeyDeclarationSQL($foreignKey)
68
        );
69
70
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
71
            array('foreign_id'), 'my_table', array('id'), 'my_fk', array('deferrable' => true)
72
        );
73
        self::assertEquals(
74
            "CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) DEFERRABLE INITIALLY IMMEDIATE",
75
            $this->_platform->getForeignKeyDeclarationSQL($foreignKey)
76
        );
77
78
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
79
            array('foreign_id'), 'my_table', array('id'), 'my_fk', array('deferred' => true)
80
        );
81
        self::assertEquals(
82
            "CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) NOT DEFERRABLE INITIALLY DEFERRED",
83
            $this->_platform->getForeignKeyDeclarationSQL($foreignKey)
84
        );
85
86
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
87
            array('foreign_id'), 'my_table', array('id'), 'my_fk', array('feferred' => true)
88
        );
89
        self::assertEquals(
90
            "CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) NOT DEFERRABLE INITIALLY DEFERRED",
91
            $this->_platform->getForeignKeyDeclarationSQL($foreignKey)
92
        );
93
94
        $foreignKey = new \Doctrine\DBAL\Schema\ForeignKeyConstraint(
95
            array('foreign_id'), 'my_table', array('id'), 'my_fk', array('deferrable' => true, 'deferred' => true, 'match' => 'full')
96
        );
97
        self::assertEquals(
98
            "CONSTRAINT my_fk FOREIGN KEY (foreign_id) REFERENCES my_table (id) MATCH full DEFERRABLE INITIALLY DEFERRED",
99
            $this->_platform->getForeignKeyDeclarationSQL($foreignKey)
100
        );
101
    }
102
103
    public function testGeneratesSqlSnippets()
104
    {
105
        self::assertEquals('SIMILAR TO', $this->_platform->getRegexpExpression(), 'Regular expression operator is not correct');
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
        self::assertEquals('SUBSTRING(column FROM 5)', $this->_platform->getSubstringExpression('column', 5), 'Substring expression without length is not correct');
109
        self::assertEquals('SUBSTRING(column FROM 1 FOR 5)', $this->_platform->getSubstringExpression('column', 1, 5), 'Substring expression with length is not correct');
110
    }
111
112
    public function testGeneratesTransactionCommands()
113
    {
114
        self::assertEquals(
115
            'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ UNCOMMITTED',
116
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_UNCOMMITTED)
117
        );
118
        self::assertEquals(
119
            'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED',
120
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::READ_COMMITTED)
121
        );
122
        self::assertEquals(
123
            'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ',
124
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::REPEATABLE_READ)
125
        );
126
        self::assertEquals(
127
            'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE',
128
            $this->_platform->getSetTransactionIsolationSQL(TransactionIsolationLevel::SERIALIZABLE)
129
        );
130
    }
131
132
    public function testGeneratesDDLSnippets()
133
    {
134
        self::assertEquals('CREATE DATABASE foobar', $this->_platform->getCreateDatabaseSQL('foobar'));
135
        self::assertEquals('DROP DATABASE foobar', $this->_platform->getDropDatabaseSQL('foobar'));
136
        self::assertEquals('DROP TABLE foobar', $this->_platform->getDropTableSQL('foobar'));
137
    }
138
139
    public function testGenerateTableWithAutoincrement()
140
    {
141
        $table = new \Doctrine\DBAL\Schema\Table('autoinc_table');
142
        $column = $table->addColumn('id', 'integer');
143
        $column->setAutoincrement(true);
144
145
        self::assertEquals(array('CREATE TABLE autoinc_table (id SERIAL NOT NULL)'), $this->_platform->getCreateTableSQL($table));
146
    }
147
148
    public static function serialTypes() : array
149
    {
150
        return [
151
            ['integer', 'SERIAL'],
152
            ['bigint', 'BIGSERIAL'],
153
        ];
154
    }
155
156
    /**
157
     * @dataProvider serialTypes
158
     * @group 2906
159
     */
160
    public function testGenerateTableWithAutoincrementDoesNotSetDefault(string $type, string $definition) : void
161
    {
162
        $table  = new \Doctrine\DBAL\Schema\Table('autoinc_table_notnull');
163
        $column = $table->addColumn('id', $type);
164
        $column->setAutoIncrement(true);
165
        $column->setNotNull(false);
166
167
        $sql = $this->_platform->getCreateTableSQL($table);
168
169
        self::assertEquals(["CREATE TABLE autoinc_table_notnull (id $definition)"], $sql);
170
    }
171
172
    /**
173
     * @dataProvider serialTypes
174
     * @group 2906
175
     */
176
    public function testCreateTableWithAutoincrementAndNotNullAddsConstraint(string $type, string $definition) : void
177
    {
178
        $table  = new \Doctrine\DBAL\Schema\Table('autoinc_table_notnull_enabled');
179
        $column = $table->addColumn('id', $type);
180
        $column->setAutoIncrement(true);
181
        $column->setNotNull(true);
182
183
        $sql = $this->_platform->getCreateTableSQL($table);
184
185
        self::assertEquals(["CREATE TABLE autoinc_table_notnull_enabled (id $definition NOT NULL)"], $sql);
186
    }
187
188
    /**
189
     * @dataProvider serialTypes
190
     * @group 2906
191
     */
192
    public function testGetDefaultValueDeclarationSQLIgnoresTheDefaultKeyWhenTheFieldIsSerial(string $type) : void
193
    {
194
        $sql = $this->_platform->getDefaultValueDeclarationSQL(
195
            [
196
                'autoincrement' => true,
197
                'type'          => Type::getType($type),
198
                'default'       => 1,
199
            ]
200
        );
201
202
        self::assertSame('', $sql);
203
    }
204
205
    public function testGeneratesTypeDeclarationForIntegers()
206
    {
207
        self::assertEquals(
208
            'INT',
209
            $this->_platform->getIntegerTypeDeclarationSQL(array())
210
        );
211
        self::assertEquals(
212
            'SERIAL',
213
            $this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true)
214
        ));
215
        self::assertEquals(
216
            'SERIAL',
217
            $this->_platform->getIntegerTypeDeclarationSQL(
218
                array('autoincrement' => true, 'primary' => true)
219
        ));
220
    }
221
222
    public function testGeneratesTypeDeclarationForStrings()
223
    {
224
        self::assertEquals(
225
            'CHAR(10)',
226
            $this->_platform->getVarcharTypeDeclarationSQL(
227
                array('length' => 10, 'fixed' => true))
228
        );
229
        self::assertEquals(
230
            'VARCHAR(50)',
231
            $this->_platform->getVarcharTypeDeclarationSQL(array('length' => 50)),
232
            'Variable string declaration is not correct'
233
        );
234
        self::assertEquals(
235
            'VARCHAR(255)',
236
            $this->_platform->getVarcharTypeDeclarationSQL(array()),
237
            'Long string declaration is not correct'
238
        );
239
    }
240
241
    public function getGenerateUniqueIndexSql()
242
    {
243
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
244
    }
245
246
    public function testGeneratesSequenceSqlCommands()
247
    {
248
        $sequence = new \Doctrine\DBAL\Schema\Sequence('myseq', 20, 1);
249
        self::assertEquals(
250
            'CREATE SEQUENCE myseq INCREMENT BY 20 MINVALUE 1 START 1',
251
            $this->_platform->getCreateSequenceSQL($sequence)
252
        );
253
        self::assertEquals(
254
            'DROP SEQUENCE myseq CASCADE',
255
            $this->_platform->getDropSequenceSQL('myseq')
256
        );
257
        self::assertEquals(
258
            "SELECT NEXTVAL('myseq')",
259
            $this->_platform->getSequenceNextValSQL('myseq')
260
        );
261
    }
262
263
    public function testDoesNotPreferIdentityColumns()
264
    {
265
        self::assertFalse($this->_platform->prefersIdentityColumns());
266
    }
267
268
    public function testPrefersSequences()
269
    {
270
        self::assertTrue($this->_platform->prefersSequences());
271
    }
272
273
    public function testSupportsIdentityColumns()
274
    {
275
        self::assertTrue($this->_platform->supportsIdentityColumns());
276
    }
277
278
    public function testSupportsSavePoints()
279
    {
280
        self::assertTrue($this->_platform->supportsSavepoints());
281
    }
282
283
    public function testSupportsSequences()
284
    {
285
        self::assertTrue($this->_platform->supportsSequences());
286
    }
287
288
    /**
289
     * {@inheritdoc}
290
     */
291
    protected function supportsCommentOnStatement()
292
    {
293
        return true;
294
    }
295
296
    public function testModifyLimitQuery()
297
    {
298
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 0);
299
        self::assertEquals('SELECT * FROM user LIMIT 10 OFFSET 0', $sql);
300
    }
301
302
    public function testModifyLimitQueryWithEmptyOffset()
303
    {
304
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10);
305
        self::assertEquals('SELECT * FROM user LIMIT 10', $sql);
306
    }
307
308
    public function getCreateTableColumnCommentsSQL()
309
    {
310
        return array(
311
            "CREATE TABLE test (id INT NOT NULL, PRIMARY KEY(id))",
312
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
313
        );
314
    }
315
316
    public function getAlterTableColumnCommentsSQL()
317
    {
318
        return array(
319
            "ALTER TABLE mytable ADD quota INT NOT NULL",
320
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
321
            "COMMENT ON COLUMN mytable.foo IS NULL",
322
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
323
        );
324
    }
325
326
    public function getCreateTableColumnTypeCommentsSQL()
327
    {
328
        return array(
329
            "CREATE TABLE test (id INT NOT NULL, data TEXT NOT NULL, PRIMARY KEY(id))",
330
            "COMMENT ON COLUMN test.data IS '(DC2Type:array)'"
331
        );
332
    }
333
334
    protected function getQuotedColumnInPrimaryKeySQL()
335
    {
336
        return array(
337
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, PRIMARY KEY("create"))',
338
        );
339
    }
340
341
    protected function getQuotedColumnInIndexSQL()
342
    {
343
        return array(
344
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)',
345
            'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")',
346
        );
347
    }
348
349
    protected function getQuotedNameInIndexSQL()
350
    {
351
        return array(
352
            'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)',
353
            'CREATE INDEX "key" ON test (column1)',
354
        );
355
    }
356
357
    protected function getQuotedColumnInForeignKeySQL()
358
    {
359
        return array(
360
            'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL)',
361
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES "foreign" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE',
362
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") REFERENCES foo ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE',
363
            'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") REFERENCES "foo-bar" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE',
364
        );
365
    }
366
367
    /**
368
     * @group DBAL-457
369
     * @dataProvider pgBooleanProvider
370
     *
371
     * @param string $databaseValue
372
     * @param string $preparedStatementValue
373
     * @param int    $integerValue
374
     * @param bool   $booleanValue
375
     */
376
    public function testConvertBooleanAsLiteralStrings(
377
        $databaseValue,
378
        $preparedStatementValue,
379
        $integerValue,
380
        $booleanValue
381
    ) {
382
        $platform = $this->createPlatform();
383
384
        self::assertEquals($preparedStatementValue, $platform->convertBooleans($databaseValue));
385
    }
386
387
    /**
388
     * @group DBAL-457
389
     */
390
    public function testConvertBooleanAsLiteralIntegers()
391
    {
392
        $platform = $this->createPlatform();
393
        $platform->setUseBooleanTrueFalseStrings(false);
394
395
        self::assertEquals(1, $platform->convertBooleans(true));
396
        self::assertEquals(1, $platform->convertBooleans('1'));
397
398
        self::assertEquals(0, $platform->convertBooleans(false));
399
        self::assertEquals(0, $platform->convertBooleans('0'));
400
    }
401
402
    /**
403
     * @group DBAL-630
404
     * @dataProvider pgBooleanProvider
405
     *
406
     * @param string $databaseValue
407
     * @param string $preparedStatementValue
408
     * @param int    $integerValue
409
     * @param bool   $booleanValue
410
     */
411
    public function testConvertBooleanAsDatabaseValueStrings(
412
        $databaseValue,
413
        $preparedStatementValue,
414
        $integerValue,
415
        $booleanValue
416
    )
417
    {
418
        $platform = $this->createPlatform();
419
420
        self::assertSame($integerValue, $platform->convertBooleansToDatabaseValue($booleanValue));
421
    }
422
423
    /**
424
     * @group DBAL-630
425
     */
426
    public function testConvertBooleanAsDatabaseValueIntegers()
427
    {
428
        $platform = $this->createPlatform();
429
        $platform->setUseBooleanTrueFalseStrings(false);
430
431
        self::assertSame(1, $platform->convertBooleansToDatabaseValue(true));
432
        self::assertSame(0, $platform->convertBooleansToDatabaseValue(false));
433
    }
434
435
    /**
436
     * @dataProvider pgBooleanProvider
437
     *
438
     * @param string $databaseValue
439
     * @param string $prepareStatementValue
440
     * @param int    $integerValue
441
     * @param bool   $booleanValue
442
     */
443
    public function testConvertFromBoolean($databaseValue, $prepareStatementValue, $integerValue, $booleanValue)
444
    {
445
        $platform = $this->createPlatform();
446
447
        self::assertSame($booleanValue, $platform->convertFromBoolean($databaseValue));
448
    }
449
450
    /**
451
     * @expectedException        UnexpectedValueException
452
     * @expectedExceptionMessage Unrecognized boolean literal 'my-bool'
453
     */
454
    public function testThrowsExceptionWithInvalidBooleanLiteral()
455
    {
456
        $platform = $this->createPlatform()->convertBooleansToDatabaseValue("my-bool");
457
    }
458
459
    public function testGetCreateSchemaSQL()
460
    {
461
        $schemaName = 'schema';
462
        $sql = $this->_platform->getCreateSchemaSQL($schemaName);
463
        self::assertEquals('CREATE SCHEMA ' . $schemaName, $sql);
464
    }
465
466
    public function testAlterDecimalPrecisionScale()
467
    {
468
469
        $table = new Table('mytable');
470
        $table->addColumn('dfoo1', 'decimal');
471
        $table->addColumn('dfoo2', 'decimal', array('precision' => 10, 'scale' => 6));
472
        $table->addColumn('dfoo3', 'decimal', array('precision' => 10, 'scale' => 6));
473
        $table->addColumn('dfoo4', 'decimal', array('precision' => 10, 'scale' => 6));
474
475
        $tableDiff = new TableDiff('mytable');
476
        $tableDiff->fromTable = $table;
477
478
        $tableDiff->changedColumns['dloo1'] = new \Doctrine\DBAL\Schema\ColumnDiff(
479
            'dloo1', new \Doctrine\DBAL\Schema\Column(
480
                'dloo1', \Doctrine\DBAL\Types\Type::getType('decimal'), array('precision' => 16, 'scale' => 6)
481
            ),
482
            array('precision')
483
        );
484
        $tableDiff->changedColumns['dloo2'] = new \Doctrine\DBAL\Schema\ColumnDiff(
485
            'dloo2', new \Doctrine\DBAL\Schema\Column(
486
                'dloo2', \Doctrine\DBAL\Types\Type::getType('decimal'), array('precision' => 10, 'scale' => 4)
487
            ),
488
            array('scale')
489
        );
490
        $tableDiff->changedColumns['dloo3'] = new \Doctrine\DBAL\Schema\ColumnDiff(
491
            'dloo3', new \Doctrine\DBAL\Schema\Column(
492
                'dloo3', \Doctrine\DBAL\Types\Type::getType('decimal'), array('precision' => 10, 'scale' => 6)
493
            ),
494
            array()
495
        );
496
        $tableDiff->changedColumns['dloo4'] = new \Doctrine\DBAL\Schema\ColumnDiff(
497
            'dloo4', new \Doctrine\DBAL\Schema\Column(
498
                'dloo4', \Doctrine\DBAL\Types\Type::getType('decimal'), array('precision' => 16, 'scale' => 8)
499
            ),
500
            array('precision', 'scale')
501
        );
502
503
        $sql = $this->_platform->getAlterTableSQL($tableDiff);
504
505
        $expectedSql = array(
506
            'ALTER TABLE mytable ALTER dloo1 TYPE NUMERIC(16, 6)',
507
            'ALTER TABLE mytable ALTER dloo2 TYPE NUMERIC(10, 4)',
508
            'ALTER TABLE mytable ALTER dloo4 TYPE NUMERIC(16, 8)',
509
        );
510
511
        self::assertEquals($expectedSql, $sql);
512
    }
513
514
    /**
515
     * @group DBAL-365
516
     */
517
    public function testDroppingConstraintsBeforeColumns()
518
    {
519
        $newTable = new Table('mytable');
520
        $newTable->addColumn('id', 'integer');
521
        $newTable->setPrimaryKey(array('id'));
522
523
        $oldTable = clone $newTable;
524
        $oldTable->addColumn('parent_id', 'integer');
525
        $oldTable->addUnnamedForeignKeyConstraint('mytable', array('parent_id'), array('id'));
526
527
        $comparator = new \Doctrine\DBAL\Schema\Comparator();
528
        $tableDiff = $comparator->diffTable($oldTable, $newTable);
529
530
        $sql = $this->_platform->getAlterTableSQL($tableDiff);
531
532
        $expectedSql = array(
533
            'ALTER TABLE mytable DROP CONSTRAINT FK_6B2BD609727ACA70',
534
            'DROP INDEX IDX_6B2BD609727ACA70',
535
            'ALTER TABLE mytable DROP parent_id',
536
        );
537
538
        self::assertEquals($expectedSql, $sql);
539
    }
540
541
    /**
542
     * @group DBAL-563
543
     */
544
    public function testUsesSequenceEmulatedIdentityColumns()
545
    {
546
        self::assertTrue($this->_platform->usesSequenceEmulatedIdentityColumns());
547
    }
548
549
    /**
550
     * @group DBAL-563
551
     */
552
    public function testReturnsIdentitySequenceName()
553
    {
554
        self::assertSame('mytable_mycolumn_seq', $this->_platform->getIdentitySequenceName('mytable', 'mycolumn'));
555
    }
556
557
    /**
558
     * @dataProvider dataCreateSequenceWithCache
559
     * @group DBAL-139
560
     */
561
    public function testCreateSequenceWithCache($cacheSize, $expectedSql)
562
    {
563
        $sequence = new \Doctrine\DBAL\Schema\Sequence('foo', 1, 1, $cacheSize);
564
        self::assertContains($expectedSql, $this->_platform->getCreateSequenceSQL($sequence));
565
    }
566
567
    public function dataCreateSequenceWithCache()
568
    {
569
        return array(
570
            array(3, 'CACHE 3')
571
        );
572
    }
573
574
    protected function getBinaryDefaultLength()
575
    {
576
        return 0;
577
    }
578
579
    protected function getBinaryMaxLength()
580
    {
581
        return 0;
582
    }
583
584
    public function testReturnsBinaryTypeDeclarationSQL()
585
    {
586
        self::assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array()));
587
        self::assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 0)));
588
        self::assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('length' => 9999999)));
589
590
        self::assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true)));
591
        self::assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 0)));
592
        self::assertSame('BYTEA', $this->_platform->getBinaryTypeDeclarationSQL(array('fixed' => true, 'length' => 9999999)));
593
    }
594
595
    public function testDoesNotPropagateUnnecessaryTableAlterationOnBinaryType()
596
    {
597
        $table1 = new Table('mytable');
598
        $table1->addColumn('column_varbinary', 'binary');
599
        $table1->addColumn('column_binary', 'binary', array('fixed' => true));
600
        $table1->addColumn('column_blob', 'blob');
601
602
        $table2 = new Table('mytable');
603
        $table2->addColumn('column_varbinary', 'binary', array('fixed' => true));
604
        $table2->addColumn('column_binary', 'binary');
605
        $table2->addColumn('column_blob', 'binary');
606
607
        $comparator = new Comparator();
608
609
        // VARBINARY -> BINARY
610
        // BINARY    -> VARBINARY
611
        // BLOB      -> VARBINARY
612
        self::assertEmpty($this->_platform->getAlterTableSQL($comparator->diffTable($table1, $table2)));
613
614
        $table2 = new Table('mytable');
615
        $table2->addColumn('column_varbinary', 'binary', array('length' => 42));
616
        $table2->addColumn('column_binary', 'blob');
617
        $table2->addColumn('column_blob', 'binary', array('length' => 11, 'fixed' => true));
618
619
        // VARBINARY -> VARBINARY with changed length
620
        // BINARY    -> BLOB
621
        // BLOB      -> BINARY
622
        self::assertEmpty($this->_platform->getAlterTableSQL($comparator->diffTable($table1, $table2)));
623
624
        $table2 = new Table('mytable');
625
        $table2->addColumn('column_varbinary', 'blob');
626
        $table2->addColumn('column_binary', 'binary', array('length' => 42, 'fixed' => true));
627
        $table2->addColumn('column_blob', 'blob');
628
629
        // VARBINARY -> BLOB
630
        // BINARY    -> BINARY with changed length
631
        // BLOB      -> BLOB
632
        self::assertEmpty($this->_platform->getAlterTableSQL($comparator->diffTable($table1, $table2)));
633
    }
634
635
    /**
636
     * @group DBAL-234
637
     */
638
    protected function getAlterTableRenameIndexSQL()
639
    {
640
        return array(
641
            'ALTER INDEX idx_foo RENAME TO idx_bar',
642
        );
643
    }
644
645
    /**
646
     * @group DBAL-234
647
     */
648
    protected function getQuotedAlterTableRenameIndexSQL()
649
    {
650
        return array(
651
            'ALTER INDEX "create" RENAME TO "select"',
652
            'ALTER INDEX "foo" RENAME TO "bar"',
653
        );
654
    }
655
656
    /**
657
     * PostgreSQL boolean strings provider
658
     * @return array
659
     */
660
    public function pgBooleanProvider()
661
    {
662
        return array(
663
            // Database value, prepared statement value, boolean integer value, boolean value.
664
            array(true, 'true', 1, true),
665
            array('t', 'true', 1, true),
666
            array('true', 'true', 1, true),
667
            array('y', 'true', 1, true),
668
            array('yes', 'true', 1, true),
669
            array('on', 'true', 1, true),
670
            array('1', 'true', 1, true),
671
672
            array(false, 'false', 0, false),
673
            array('f', 'false', 0, false),
674
            array('false', 'false', 0, false),
675
            array( 'n', 'false', 0, false),
676
            array('no', 'false', 0, false),
677
            array('off', 'false', 0, false),
678
            array('0', 'false', 0, false),
679
680
            array(null, 'NULL', null, null)
681
        );
682
    }
683
684
    /**
685
     * {@inheritdoc}
686
     */
687
    protected function getQuotedAlterTableRenameColumnSQL()
688
    {
689
        return array(
690
            'ALTER TABLE mytable RENAME COLUMN unquoted1 TO unquoted',
691
            'ALTER TABLE mytable RENAME COLUMN unquoted2 TO "where"',
692
            'ALTER TABLE mytable RENAME COLUMN unquoted3 TO "foo"',
693
            'ALTER TABLE mytable RENAME COLUMN "create" TO reserved_keyword',
694
            'ALTER TABLE mytable RENAME COLUMN "table" TO "from"',
695
            'ALTER TABLE mytable RENAME COLUMN "select" TO "bar"',
696
            'ALTER TABLE mytable RENAME COLUMN quoted1 TO quoted',
697
            'ALTER TABLE mytable RENAME COLUMN quoted2 TO "and"',
698
            'ALTER TABLE mytable RENAME COLUMN quoted3 TO "baz"',
699
        );
700
    }
701
702
    /**
703
     * {@inheritdoc}
704
     */
705
    protected function getQuotedAlterTableChangeColumnLengthSQL()
706
    {
707
        return array(
708
            'ALTER TABLE mytable ALTER unquoted1 TYPE VARCHAR(255)',
709
            'ALTER TABLE mytable ALTER unquoted2 TYPE VARCHAR(255)',
710
            'ALTER TABLE mytable ALTER unquoted3 TYPE VARCHAR(255)',
711
            'ALTER TABLE mytable ALTER "create" TYPE VARCHAR(255)',
712
            'ALTER TABLE mytable ALTER "table" TYPE VARCHAR(255)',
713
            'ALTER TABLE mytable ALTER "select" TYPE VARCHAR(255)',
714
        );
715
    }
716
717
    /**
718
     * @group DBAL-807
719
     */
720
    protected function getAlterTableRenameIndexInSchemaSQL()
721
    {
722
        return array(
723
            'ALTER INDEX myschema.idx_foo RENAME TO idx_bar',
724
        );
725
    }
726
727
    /**
728
     * @group DBAL-807
729
     */
730
    protected function getQuotedAlterTableRenameIndexInSchemaSQL()
731
    {
732
        return array(
733
            'ALTER INDEX "schema"."create" RENAME TO "select"',
734
            'ALTER INDEX "schema"."foo" RENAME TO "bar"',
735
        );
736
    }
737
738
    protected function getQuotesDropForeignKeySQL()
739
    {
740
        return 'ALTER TABLE "table" DROP CONSTRAINT "select"';
741
    }
742
743
    public function testGetNullCommentOnColumnSQL()
744
    {
745
        self::assertEquals(
746
            "COMMENT ON COLUMN mytable.id IS NULL",
747
            $this->_platform->getCommentOnColumnSQL('mytable', 'id', null)
748
        );
749
    }
750
751
    /**
752
     * @group DBAL-423
753
     */
754
    public function testReturnsGuidTypeDeclarationSQL()
755
    {
756
        self::assertSame('UUID', $this->_platform->getGuidTypeDeclarationSQL(array()));
757
    }
758
759
    /**
760
     * {@inheritdoc}
761
     */
762
    public function getAlterTableRenameColumnSQL()
763
    {
764
        return array(
765
            'ALTER TABLE foo RENAME COLUMN bar TO baz',
766
        );
767
    }
768
769
    /**
770
     * {@inheritdoc}
771
     */
772
    protected function getQuotesTableIdentifiersInAlterTableSQL()
773
    {
774
        return array(
775
            'ALTER TABLE "foo" DROP CONSTRAINT fk1',
776
            'ALTER TABLE "foo" DROP CONSTRAINT fk2',
777
            'ALTER TABLE "foo" ADD bloo INT NOT NULL',
778
            'ALTER TABLE "foo" DROP baz',
779
            'ALTER TABLE "foo" ALTER bar DROP NOT NULL',
780
            'ALTER TABLE "foo" RENAME COLUMN id TO war',
781
            'ALTER TABLE "foo" RENAME TO "table"',
782
            'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id) NOT DEFERRABLE ' .
783
            'INITIALLY IMMEDIATE',
784
            'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id) NOT DEFERRABLE ' .
785
            'INITIALLY IMMEDIATE',
786
        );
787
    }
788
789
    /**
790
     * {@inheritdoc}
791
     */
792
    protected function getCommentOnColumnSQL()
793
    {
794
        return array(
795
            'COMMENT ON COLUMN foo.bar IS \'comment\'',
796
            'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
797
            'COMMENT ON COLUMN "select"."from" IS \'comment\'',
798
        );
799
    }
800
801
    /**
802
     * @group DBAL-1004
803
     */
804
    public function testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers()
805
    {
806
        $table1 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'))));
807
        $table2 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'), array('comment' => 'baz'))));
808
809
        $comparator = new Comparator();
810
811
        $tableDiff = $comparator->diffTable($table1, $table2);
812
813
        self::assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
814
        self::assertSame(
815
            array(
816
                'COMMENT ON COLUMN "foo"."bar" IS \'baz\'',
817
            ),
818
            $this->_platform->getAlterTableSQL($tableDiff)
819
        );
820
    }
821
822
    /**
823
     * {@inheritdoc}
824
     */
825
    protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL()
826
    {
827
        return 'CONSTRAINT "select" UNIQUE (foo)';
828
    }
829
830
    /**
831
     * {@inheritdoc}
832
     */
833
    protected function getQuotesReservedKeywordInIndexDeclarationSQL()
834
    {
835
        return 'INDEX "select" (foo)';
836
    }
837
838
    /**
839
     * {@inheritdoc}
840
     */
841
    protected function getQuotesReservedKeywordInTruncateTableSQL()
842
    {
843
        return 'TRUNCATE "select"';
844
    }
845
846
    /**
847
     * {@inheritdoc}
848
     */
849
    protected function getAlterStringToFixedStringSQL()
850
    {
851
        return array(
852
            'ALTER TABLE mytable ALTER name TYPE CHAR(2)',
853
        );
854
    }
855
856
    /**
857
     * {@inheritdoc}
858
     */
859
    protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL()
860
    {
861
        return array(
862
            'ALTER INDEX idx_foo RENAME TO idx_foo_renamed',
863
        );
864
    }
865
866
    /**
867
     * @group DBAL-1142
868
     */
869
    public function testInitializesTsvectorTypeMapping()
870
    {
871
        self::assertTrue($this->_platform->hasDoctrineTypeMappingFor('tsvector'));
872
        self::assertEquals('text', $this->_platform->getDoctrineTypeMapping('tsvector'));
873
    }
874
875
    /**
876
     * @group DBAL-1220
877
     */
878
    public function testReturnsDisallowDatabaseConnectionsSQL()
879
    {
880
        self::assertSame(
881
            "UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'foo'",
882
            $this->_platform->getDisallowDatabaseConnectionsSQL('foo')
883
        );
884
    }
885
886
    /**
887
     * @group DBAL-1220
888
     */
889
    public function testReturnsCloseActiveDatabaseConnectionsSQL()
890
    {
891
        self::assertSame(
892
            "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname = 'foo'",
893
            $this->_platform->getCloseActiveDatabaseConnectionsSQL('foo')
894
        );
895
    }
896
897
    /**
898
     * @group DBAL-2436
899
     */
900
    public function testQuotesTableNameInListTableForeignKeysSQL()
901
    {
902
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true);
903
    }
904
905
    /**
906
     * @group DBAL-2436
907
     */
908
    public function testQuotesSchemaNameInListTableForeignKeysSQL()
909
    {
910
        self::assertContains(
911
            "'Foo''Bar\\\\'",
912
            $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\.baz_table"),
913
            '',
914
            true
915
        );
916
    }
917
918
    /**
919
     * @group DBAL-2436
920
     */
921
    public function testQuotesTableNameInListTableConstraintsSQL()
922
    {
923
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true);
924
    }
925
926
    /**
927
     * @group DBAL-2436
928
     */
929
    public function testQuotesTableNameInListTableIndexesSQL()
930
    {
931
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\"), '', true);
932
    }
933
934
    /**
935
     * @group DBAL-2436
936
     */
937
    public function testQuotesSchemaNameInListTableIndexesSQL()
938
    {
939
        self::assertContains(
940
            "'Foo''Bar\\\\'",
941
            $this->_platform->getListTableIndexesSQL("Foo'Bar\\.baz_table"),
942
            '',
943
            true
944
        );
945
    }
946
947
    /**
948
     * @group DBAL-2436
949
     */
950
    public function testQuotesTableNameInListTableColumnsSQL()
951
    {
952
        self::assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableColumnsSQL("Foo'Bar\\"), '', true);
953
    }
954
955
    /**
956
     * @group DBAL-2436
957
     */
958
    public function testQuotesSchemaNameInListTableColumnsSQL()
959
    {
960
        self::assertContains(
961
            "'Foo''Bar\\\\'",
962
            $this->_platform->getListTableColumnsSQL("Foo'Bar\\.baz_table"),
963
            '',
964
            true
965
        );
966
    }
967
968
    /**
969
     * @group DBAL-2436
970
     */
971
    public function testQuotesDatabaseNameInCloseActiveDatabaseConnectionsSQL()
972
    {
973
        self::assertContains(
974
            "'Foo''Bar\\\\'",
975
            $this->_platform->getCloseActiveDatabaseConnectionsSQL("Foo'Bar\\"),
976
            '',
977
            true
978
        );
979
    }
980
}
981