OraclePlatformTest.php 10.8 KB
Newer Older
1 2 3 4 5 6 7 8
<?php

namespace Doctrine\Tests\DBAL\Platforms;

use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Types\Type;

require_once __DIR__ . '/../../TestInit.php';
9

10
class OraclePlatformTest extends AbstractPlatformTestCase
11
{
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    static public function dataValidIdentifiers()
    {
        return array(
            array('a'),
            array('foo'),
            array('Foo'),
            array('Foo123'),
            array('Foo#bar_baz$'),
            array('"a"'),
            array('"1"'),
            array('"foo_bar"'),
            array('"@$%&!"'),
        );
    }

    /**
     * @dataProvider dataValidIdentifiers
     */
    public function testValidIdentifiers($identifier)
    {
        $platform = $this->createPlatform();
        $platform->assertValidIdentifier($identifier);
    }

    static public function dataInvalidIdentifiers()
    {
        return array(
            array('1'),
            array('abc&'),
            array('abc-def'),
            array('"'),
            array('"foo"bar"'),
        );
    }

    /**
     * @dataProvider dataInvalidIdentifiers
     */
    public function testInvalidIdentifiers($identifier)
    {
        $this->setExpectedException('Doctrine\DBAL\DBALException');
        $platform = $this->createPlatform();
        $platform->assertValidIdentifier($identifier);
    }

57
    public function createPlatform()
58
    {
59
        return new OraclePlatform;
60 61
    }

62
    public function getGenerateTableSql()
63
    {
64
        return 'CREATE TABLE test (id NUMBER(10) NOT NULL, test VARCHAR2(255) DEFAULT NULL, PRIMARY KEY(id))';
65 66
    }

67 68 69 70
    public function getGenerateTableWithMultiColumnUniqueIndexSql()
    {
        return array(
            'CREATE TABLE test (foo VARCHAR2(255) DEFAULT NULL, bar VARCHAR2(255) DEFAULT NULL)',
71
            'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)',
72 73 74
        );
    }

75
    public function getGenerateAlterTableSql()
76
    {
77
        return array(
78
            'ALTER TABLE mytable ADD (quota NUMBER(10) DEFAULT NULL)',
79
            "ALTER TABLE mytable MODIFY (baz  VARCHAR2(255) DEFAULT 'def' NOT NULL, bloo  NUMBER(1) DEFAULT '0' NOT NULL)",
80
            "ALTER TABLE mytable DROP (foo)",
81
            "ALTER TABLE mytable RENAME TO userlist",
82 83 84 85
        );
    }

    /**
86
     * @expectedException Doctrine\DBAL\DBALException
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
     */
    public function testRLike()
    {
        $this->assertEquals('RLIKE', $this->_platform->getRegexpExpression(), 'Regular expression operator is not correct');
    }

    public function testGeneratesSqlSnippets()
    {
        $this->assertEquals('"', $this->_platform->getIdentifierQuoteCharacter(), 'Identifier quote character is not correct');
        $this->assertEquals('column1 || column2 || column3', $this->_platform->getConcatExpression('column1', 'column2', 'column3'), 'Concatenation expression is not correct');
    }

    public function testGeneratesTransactionsCommands()
    {
        $this->assertEquals(
            'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED',
103
            $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED)
104 105 106
        );
        $this->assertEquals(
            'SET TRANSACTION ISOLATION LEVEL READ COMMITTED',
107
            $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED)
108 109 110
        );
        $this->assertEquals(
            'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE',
111
            $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ)
112 113 114
        );
        $this->assertEquals(
            'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE',
115
            $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE)
116 117 118 119
        );
    }

    /**
120
     * @expectedException Doctrine\DBAL\DBALException
121 122 123
     */
    public function testCreateDatabaseThrowsException()
    {
124
        $this->assertEquals('CREATE DATABASE foobar', $this->_platform->getCreateDatabaseSQL('foobar'));
125 126 127 128
    }

    public function testDropDatabaseThrowsException()
    {
129
        $this->assertEquals('DROP USER foobar CASCADE', $this->_platform->getDropDatabaseSQL('foobar'));
130 131 132 133
    }

    public function testDropTable()
    {
134
        $this->assertEquals('DROP TABLE foobar', $this->_platform->getDropTableSQL('foobar'));
135 136 137 138 139 140
    }

    public function testGeneratesTypeDeclarationForIntegers()
    {
        $this->assertEquals(
            'NUMBER(10)',
141
            $this->_platform->getIntegerTypeDeclarationSQL(array())
142 143 144
        );
        $this->assertEquals(
            'NUMBER(10)',
145
            $this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true)
146 147 148
        ));
        $this->assertEquals(
            'NUMBER(10)',
149
            $this->_platform->getIntegerTypeDeclarationSQL(
150 151 152 153 154 155 156 157
                array('autoincrement' => true, 'primary' => true)
        ));
    }

    public function testGeneratesTypeDeclarationsForStrings()
    {
        $this->assertEquals(
            'CHAR(10)',
158
            $this->_platform->getVarcharTypeDeclarationSQL(
159 160 161 162
                array('length' => 10, 'fixed' => true)
        ));
        $this->assertEquals(
            'VARCHAR2(50)',
163
            $this->_platform->getVarcharTypeDeclarationSQL(array('length' => 50)),
164 165 166
            'Variable string declaration is not correct'
        );
        $this->assertEquals(
167
            'VARCHAR2(255)',
168
            $this->_platform->getVarcharTypeDeclarationSQL(array()),
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
            'Long string declaration is not correct'
        );
    }

    public function testPrefersIdentityColumns()
    {
        $this->assertFalse($this->_platform->prefersIdentityColumns());
    }

    public function testSupportsIdentityColumns()
    {
        $this->assertFalse($this->_platform->supportsIdentityColumns());
    }

    public function testSupportsSavePoints()
    {
185
        $this->assertTrue($this->_platform->supportsSavepoints());
186
    }
187

188
    public function getGenerateIndexSql()
189
    {
190
        return 'CREATE INDEX my_idx ON mytable (user_name, last_login)';
191 192
    }

193
    public function getGenerateUniqueIndexSql()
194
    {
195
        return 'CREATE UNIQUE INDEX index_name ON test (test, test2)';
196 197
    }

198
    public function getGenerateForeignKeySql()
199
    {
200
        return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)';
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
    }

    public function testModifyLimitQuery()
    {
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 0);
        $this->assertEquals('SELECT a.* FROM (SELECT * FROM user) a WHERE ROWNUM <= 10', $sql);
    }

    public function testModifyLimitQueryWithEmptyOffset()
    {
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10);
        $this->assertEquals('SELECT a.* FROM (SELECT * FROM user) a WHERE ROWNUM <= 10', $sql);
    }

    public function testModifyLimitQueryWithAscOrderBy()
    {
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username ASC', 10);
        $this->assertEquals('SELECT a.* FROM (SELECT * FROM user ORDER BY username ASC) a WHERE ROWNUM <= 10', $sql);
    }

    public function testModifyLimitQueryWithDescOrderBy()
    {
        $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username DESC', 10);
        $this->assertEquals('SELECT a.* FROM (SELECT * FROM user ORDER BY username DESC) a WHERE ROWNUM <= 10', $sql);
    }
226

227 228
    public function testGenerateTableWithAutoincrement()
    {
229 230 231
        $columnName = strtoupper('id' . uniqid());
        $tableName = strtoupper('table' . uniqid());
        $table = new \Doctrine\DBAL\Schema\Table($tableName);
232 233 234
        $column = $table->addColumn($columnName, 'integer');
        $column->setAutoincrement(true);
        $targets = array(
235 236 237 238
          "CREATE TABLE {$tableName} ({$columnName} NUMBER(10) NOT NULL)",
          "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;",
          "CREATE SEQUENCE {$tableName}_{$columnName}_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1",
          "CREATE TRIGGER {$tableName}_AI_PK BEFORE INSERT ON {$tableName} FOR EACH ROW DECLARE last_Sequence NUMBER; last_InsertID NUMBER; BEGIN SELECT {$tableName}_{$columnName}_SEQ.NEXTVAL INTO :NEW.{$columnName} FROM DUAL; IF (:NEW.{$columnName} IS NULL OR :NEW.{$columnName} = 0) THEN SELECT {$tableName}_{$columnName}_SEQ.NEXTVAL INTO :NEW.{$columnName} FROM DUAL; ELSE SELECT NVL(Last_Number, 0) INTO last_Sequence FROM User_Sequences WHERE Sequence_Name = '{$tableName}_{$columnName}_SEQ'; SELECT :NEW.{$columnName} INTO last_InsertID FROM DUAL; WHILE (last_InsertID > last_Sequence) LOOP SELECT {$tableName}_{$columnName}_SEQ.NEXTVAL INTO last_Sequence FROM DUAL; END LOOP; END IF; END;"
239 240 241 242 243 244 245 246 247 248 249 250
        );
        $statements = $this->_platform->getCreateTableSQL($table);
        //strip all the whitespace from the statements
        array_walk($statements, function(&$value){
          $value = preg_replace('/\s+/', ' ',$value);
        });
        foreach($targets as $key => $sql){
          $this->assertArrayHasKey($key,$statements);
          $this->assertEquals($sql, $statements[$key]);
        }
    }

251 252 253 254
    public function getCreateTableColumnCommentsSQL()
    {
        return array(
            "CREATE TABLE test (id NUMBER(10) NOT NULL, PRIMARY KEY(id))",
255
            "COMMENT ON COLUMN test.id IS 'This is a comment'",
256 257 258
        );
    }

259 260 261 262 263 264 265 266
    public function getCreateTableColumnTypeCommentsSQL()
    {
        return array(
            "CREATE TABLE test (id NUMBER(10) NOT NULL, data CLOB NOT NULL, PRIMARY KEY(id))",
            "COMMENT ON COLUMN test.data IS '(DC2Type:array)'"
        );
    }

267 268 269 270
    public function getAlterTableColumnCommentsSQL()
    {
        return array(
            "ALTER TABLE mytable ADD (quota NUMBER(10) NOT NULL)",
271
            "COMMENT ON COLUMN mytable.quota IS 'A comment'",
272
            "COMMENT ON COLUMN mytable.foo IS ''",
273
            "COMMENT ON COLUMN mytable.baz IS 'B comment'",
274 275
        );
    }
276 277 278 279 280 281 282 283

    public function getBitAndComparisonExpressionSql($value1, $value2)
    {
        return 'BITAND('.$value1 . ', ' . $value2 . ')';
    }

    public function getBitOrComparisonExpressionSql($value1, $value2)
    {
284 285
        return '(' . $value1 . '-' .
                $this->getBitAndComparisonExpressionSql($value1, $value2)
286 287
                . '+' . $value2 . ')';
    }
288 289 290

    protected function getQuotedColumnInPrimaryKeySQL()
    {
291
        return array('CREATE TABLE "quoted" ("key" VARCHAR2(255) NOT NULL, PRIMARY KEY("key"))');
292 293 294 295
    }

    protected function getQuotedColumnInIndexSQL()
    {
296 297 298 299
        return array(
            'CREATE TABLE "quoted" ("key" VARCHAR2(255) NOT NULL)',
            'CREATE INDEX IDX_22660D028A90ABA9 ON "quoted" ("key")',
        );
300
    }
301
}