OracleSchemaManagerTest.php 12 KB
Newer Older
1 2 3 4 5
<?php

namespace Doctrine\Tests\DBAL\Functional\Schema;

use Doctrine\DBAL\Schema;
6
use Doctrine\DBAL\Schema\Table;
Sergei Morozov's avatar
Sergei Morozov committed
7
use Doctrine\DBAL\Types\BinaryType;
8
use Doctrine\DBAL\Types\Types;
9
use Doctrine\Tests\TestUtil;
10
use function array_map;
11

romanb's avatar
romanb committed
12
class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
13
{
14 15 16
    /** @var bool */
    private static $privilegesGranted = false;

17
    protected function setUp() : void
18
    {
19 20
        parent::setUp();

21 22
        if (self::$privilegesGranted) {
            return;
23 24
        }

25 26 27
        if (! isset($GLOBALS['db_username'])) {
            self::markTestSkipped('Username must be explicitly specified in connection parameters for this test');
        }
28

29 30
        TestUtil::getTempConnection()
            ->exec('GRANT ALL PRIVILEGES TO ' . $GLOBALS['db_username']);
31

32
        self::$privilegesGranted = true;
33 34
    }

35
    public function testRenameTable() : void
36
    {
Sergei Morozov's avatar
Sergei Morozov committed
37 38
        $this->schemaManager->tryMethod('DropTable', 'list_tables_test');
        $this->schemaManager->tryMethod('DropTable', 'list_tables_test_new_name');
39 40

        $this->createTestTable('list_tables_test');
Sergei Morozov's avatar
Sergei Morozov committed
41
        $this->schemaManager->renameTable('list_tables_test', 'list_tables_test_new_name');
42

Sergei Morozov's avatar
Sergei Morozov committed
43
        $tables = $this->schemaManager->listTables();
44

45
        self::assertHasTable($tables, 'list_tables_test_new_name');
46
    }
Steve Müller's avatar
Steve Müller committed
47

48
    public function testListTableWithBinary() : void
Steve Müller's avatar
Steve Müller committed
49 50 51
    {
        $tableName = 'test_binary_table';

Sergei Morozov's avatar
Sergei Morozov committed
52
        $table = new Table($tableName);
Steve Müller's avatar
Steve Müller committed
53
        $table->addColumn('id', 'integer');
Sergei Morozov's avatar
Sergei Morozov committed
54 55 56
        $table->addColumn('column_varbinary', 'binary', []);
        $table->addColumn('column_binary', 'binary', ['fixed' => true]);
        $table->setPrimaryKey(['id']);
Steve Müller's avatar
Steve Müller committed
57

Sergei Morozov's avatar
Sergei Morozov committed
58
        $this->schemaManager->createTable($table);
Steve Müller's avatar
Steve Müller committed
59

Sergei Morozov's avatar
Sergei Morozov committed
60
        $table = $this->schemaManager->listTableDetails($tableName);
Steve Müller's avatar
Steve Müller committed
61

Sergei Morozov's avatar
Sergei Morozov committed
62
        self::assertInstanceOf(BinaryType::class, $table->getColumn('column_varbinary')->getType());
63
        self::assertFalse($table->getColumn('column_varbinary')->getFixed());
Steve Müller's avatar
Steve Müller committed
64

Sergei Morozov's avatar
Sergei Morozov committed
65
        self::assertInstanceOf(BinaryType::class, $table->getColumn('column_binary')->getType());
66
        self::assertFalse($table->getColumn('column_binary')->getFixed());
Steve Müller's avatar
Steve Müller committed
67
    }
68 69 70

    /**
     * @group DBAL-472
71
     * @group DBAL-1001
72
     */
73
    public function testAlterTableColumnNotNull() : void
74 75 76 77 78 79 80
    {
        $comparator = new Schema\Comparator();
        $tableName  = 'list_table_column_notnull';
        $table      = new Schema\Table($tableName);

        $table->addColumn('id', 'integer');
        $table->addColumn('foo', 'integer');
81
        $table->addColumn('bar', 'string');
Sergei Morozov's avatar
Sergei Morozov committed
82
        $table->setPrimaryKey(['id']);
83

Sergei Morozov's avatar
Sergei Morozov committed
84
        $this->schemaManager->dropAndCreateTable($table);
85

Sergei Morozov's avatar
Sergei Morozov committed
86
        $columns = $this->schemaManager->listTableColumns($tableName);
87

88 89 90
        self::assertTrue($columns['id']->getNotnull());
        self::assertTrue($columns['foo']->getNotnull());
        self::assertTrue($columns['bar']->getNotnull());
91 92

        $diffTable = clone $table;
Sergei Morozov's avatar
Sergei Morozov committed
93 94
        $diffTable->changeColumn('foo', ['notnull' => false]);
        $diffTable->changeColumn('bar', ['length' => 1024]);
95

Sergei Morozov's avatar
Sergei Morozov committed
96
        $this->schemaManager->alterTable($comparator->diffTable($table, $diffTable));
97

Sergei Morozov's avatar
Sergei Morozov committed
98
        $columns = $this->schemaManager->listTableColumns($tableName);
99

100 101 102
        self::assertTrue($columns['id']->getNotnull());
        self::assertFalse($columns['foo']->getNotnull());
        self::assertTrue($columns['bar']->getNotnull());
103
    }
104

105
    public function testListDatabases() : void
106 107 108 109 110 111
    {
        // We need the temp connection that has privileges to create a database.
        $sm = TestUtil::getTempConnection()->getSchemaManager();

        $sm->dropAndCreateDatabase('c##test_create_database');

Sergei Morozov's avatar
Sergei Morozov committed
112
        $databases = $this->schemaManager->listDatabases();
113
        $databases = array_map('strtolower', $databases);
114

115
        self::assertContains('c##test_create_database', $databases);
116
    }
117 118 119 120

    /**
     * @group DBAL-831
     */
121
    public function testListTableDetailsWithDifferentIdentifierQuotingRequirements() : void
122
    {
Sergei Morozov's avatar
Sergei Morozov committed
123
        $primaryTableName    = '"Primary_Table"';
124 125 126 127
        $offlinePrimaryTable = new Schema\Table($primaryTableName);
        $offlinePrimaryTable->addColumn(
            '"Id"',
            'integer',
Sergei Morozov's avatar
Sergei Morozov committed
128
            ['autoincrement' => true, 'comment' => 'Explicit casing.']
129
        );
Sergei Morozov's avatar
Sergei Morozov committed
130 131
        $offlinePrimaryTable->addColumn('select', 'integer', ['comment' => 'Reserved keyword.']);
        $offlinePrimaryTable->addColumn('foo', 'integer', ['comment' => 'Implicit uppercasing.']);
132 133
        $offlinePrimaryTable->addColumn('BAR', 'integer');
        $offlinePrimaryTable->addColumn('"BAZ"', 'integer');
Sergei Morozov's avatar
Sergei Morozov committed
134 135 136 137 138
        $offlinePrimaryTable->addIndex(['select'], 'from');
        $offlinePrimaryTable->addIndex(['foo'], 'foo_index');
        $offlinePrimaryTable->addIndex(['BAR'], 'BAR_INDEX');
        $offlinePrimaryTable->addIndex(['"BAZ"'], 'BAZ_INDEX');
        $offlinePrimaryTable->setPrimaryKey(['"Id"']);
139

Sergei Morozov's avatar
Sergei Morozov committed
140
        $foreignTableName    = 'foreign';
141
        $offlineForeignTable = new Schema\Table($foreignTableName);
Sergei Morozov's avatar
Sergei Morozov committed
142
        $offlineForeignTable->addColumn('id', 'integer', ['autoincrement' => true]);
143
        $offlineForeignTable->addColumn('"Fk"', 'integer');
Sergei Morozov's avatar
Sergei Morozov committed
144
        $offlineForeignTable->addIndex(['"Fk"'], '"Fk_index"');
145 146
        $offlineForeignTable->addForeignKeyConstraint(
            $primaryTableName,
Sergei Morozov's avatar
Sergei Morozov committed
147 148 149
            ['"Fk"'],
            ['"Id"'],
            [],
150 151
            '"Primary_Table_Fk"'
        );
Sergei Morozov's avatar
Sergei Morozov committed
152
        $offlineForeignTable->setPrimaryKey(['id']);
153

Sergei Morozov's avatar
Sergei Morozov committed
154 155
        $this->schemaManager->tryMethod('dropTable', $foreignTableName);
        $this->schemaManager->tryMethod('dropTable', $primaryTableName);
156

Sergei Morozov's avatar
Sergei Morozov committed
157 158
        $this->schemaManager->createTable($offlinePrimaryTable);
        $this->schemaManager->createTable($offlineForeignTable);
159

Sergei Morozov's avatar
Sergei Morozov committed
160 161
        $onlinePrimaryTable = $this->schemaManager->listTableDetails($primaryTableName);
        $onlineForeignTable = $this->schemaManager->listTableDetails($foreignTableName);
162

Sergei Morozov's avatar
Sergei Morozov committed
163
        $platform = $this->schemaManager->getDatabasePlatform();
164 165

        // Primary table assertions
166
        self::assertSame($primaryTableName, $onlinePrimaryTable->getQuotedName($platform));
167

168 169 170
        self::assertTrue($onlinePrimaryTable->hasColumn('"Id"'));
        self::assertSame('"Id"', $onlinePrimaryTable->getColumn('"Id"')->getQuotedName($platform));
        self::assertTrue($onlinePrimaryTable->hasPrimaryKey());
Sergei Morozov's avatar
Sergei Morozov committed
171
        self::assertSame(['"Id"'], $onlinePrimaryTable->getPrimaryKey()->getQuotedColumns($platform));
172

173 174
        self::assertTrue($onlinePrimaryTable->hasColumn('select'));
        self::assertSame('"select"', $onlinePrimaryTable->getColumn('select')->getQuotedName($platform));
175

176 177
        self::assertTrue($onlinePrimaryTable->hasColumn('foo'));
        self::assertSame('FOO', $onlinePrimaryTable->getColumn('foo')->getQuotedName($platform));
178

179 180
        self::assertTrue($onlinePrimaryTable->hasColumn('BAR'));
        self::assertSame('BAR', $onlinePrimaryTable->getColumn('BAR')->getQuotedName($platform));
181

182 183
        self::assertTrue($onlinePrimaryTable->hasColumn('"BAZ"'));
        self::assertSame('BAZ', $onlinePrimaryTable->getColumn('"BAZ"')->getQuotedName($platform));
184

185 186
        self::assertTrue($onlinePrimaryTable->hasIndex('from'));
        self::assertTrue($onlinePrimaryTable->getIndex('from')->hasColumnAtPosition('"select"'));
Sergei Morozov's avatar
Sergei Morozov committed
187
        self::assertSame(['"select"'], $onlinePrimaryTable->getIndex('from')->getQuotedColumns($platform));
188

189 190
        self::assertTrue($onlinePrimaryTable->hasIndex('foo_index'));
        self::assertTrue($onlinePrimaryTable->getIndex('foo_index')->hasColumnAtPosition('foo'));
Sergei Morozov's avatar
Sergei Morozov committed
191
        self::assertSame(['FOO'], $onlinePrimaryTable->getIndex('foo_index')->getQuotedColumns($platform));
192

193 194
        self::assertTrue($onlinePrimaryTable->hasIndex('BAR_INDEX'));
        self::assertTrue($onlinePrimaryTable->getIndex('BAR_INDEX')->hasColumnAtPosition('BAR'));
Sergei Morozov's avatar
Sergei Morozov committed
195
        self::assertSame(['BAR'], $onlinePrimaryTable->getIndex('BAR_INDEX')->getQuotedColumns($platform));
196

197 198
        self::assertTrue($onlinePrimaryTable->hasIndex('BAZ_INDEX'));
        self::assertTrue($onlinePrimaryTable->getIndex('BAZ_INDEX')->hasColumnAtPosition('"BAZ"'));
Sergei Morozov's avatar
Sergei Morozov committed
199
        self::assertSame(['BAZ'], $onlinePrimaryTable->getIndex('BAZ_INDEX')->getQuotedColumns($platform));
200 201

        // Foreign table assertions
202 203 204
        self::assertTrue($onlineForeignTable->hasColumn('id'));
        self::assertSame('ID', $onlineForeignTable->getColumn('id')->getQuotedName($platform));
        self::assertTrue($onlineForeignTable->hasPrimaryKey());
Sergei Morozov's avatar
Sergei Morozov committed
205
        self::assertSame(['ID'], $onlineForeignTable->getPrimaryKey()->getQuotedColumns($platform));
206

207 208
        self::assertTrue($onlineForeignTable->hasColumn('"Fk"'));
        self::assertSame('"Fk"', $onlineForeignTable->getColumn('"Fk"')->getQuotedName($platform));
209

210 211
        self::assertTrue($onlineForeignTable->hasIndex('"Fk_index"'));
        self::assertTrue($onlineForeignTable->getIndex('"Fk_index"')->hasColumnAtPosition('"Fk"'));
Sergei Morozov's avatar
Sergei Morozov committed
212
        self::assertSame(['"Fk"'], $onlineForeignTable->getIndex('"Fk_index"')->getQuotedColumns($platform));
213

214 215
        self::assertTrue($onlineForeignTable->hasForeignKey('"Primary_Table_Fk"'));
        self::assertSame(
216 217 218
            $primaryTableName,
            $onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedForeignTableName($platform)
        );
219
        self::assertSame(
Sergei Morozov's avatar
Sergei Morozov committed
220
            ['"Fk"'],
221 222
            $onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedLocalColumns($platform)
        );
223
        self::assertSame(
Sergei Morozov's avatar
Sergei Morozov committed
224
            ['"Id"'],
225 226 227
            $onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedForeignColumns($platform)
        );
    }
228

229
    public function testListTableColumnsSameTableNamesInDifferentSchemas() : void
230 231
    {
        $table = $this->createListTableColumns();
Sergei Morozov's avatar
Sergei Morozov committed
232
        $this->schemaManager->dropAndCreateTable($table);
233 234

        $otherTable = new Table($table->getName());
235
        $otherTable->addColumn('id', Types::STRING);
236 237
        TestUtil::getTempConnection()->getSchemaManager()->dropAndCreateTable($otherTable);

Sergei Morozov's avatar
Sergei Morozov committed
238
        $columns = $this->schemaManager->listTableColumns($table->getName(), $this->connection->getUsername());
239
        self::assertCount(7, $columns);
240
    }
241

242 243 244
    /**
     * @group DBAL-1234
     */
245
    public function testListTableIndexesPrimaryKeyConstraintNameDiffersFromIndexName() : void
246 247
    {
        $table = new Table('list_table_indexes_pk_id_test');
Sergei Morozov's avatar
Sergei Morozov committed
248
        $table->setSchemaConfig($this->schemaManager->createSchemaConfig());
Sergei Morozov's avatar
Sergei Morozov committed
249 250
        $table->addColumn('id', 'integer', ['notnull' => true]);
        $table->addUniqueIndex(['id'], 'id_unique_index');
Sergei Morozov's avatar
Sergei Morozov committed
251
        $this->schemaManager->dropAndCreateTable($table);
252 253 254

        // Adding a primary key on already indexed columns
        // Oracle will reuse the unique index, which cause a constraint name differing from the index name
Sergei Morozov's avatar
Sergei Morozov committed
255
        $this->schemaManager->createConstraint(new Schema\Index('id_pk_id_index', ['id'], true, true), 'list_table_indexes_pk_id_test');
256

Sergei Morozov's avatar
Sergei Morozov committed
257
        $tableIndexes = $this->schemaManager->listTableIndexes('list_table_indexes_pk_id_test');
258

259
        self::assertArrayHasKey('primary', $tableIndexes, 'listTableIndexes() has to return a "primary" array key.');
Sergei Morozov's avatar
Sergei Morozov committed
260
        self::assertEquals(['id'], array_map('strtolower', $tableIndexes['primary']->getColumns()));
261 262
        self::assertTrue($tableIndexes['primary']->isUnique());
        self::assertTrue($tableIndexes['primary']->isPrimary());
263 264
    }

265 266 267
    /**
     * @group DBAL-2555
     */
268
    public function testListTableDateTypeColumns() : void
269 270 271 272
    {
        $table = new Table('tbl_date');
        $table->addColumn('col_date', 'date');
        $table->addColumn('col_datetime', 'datetime');
273
        $table->addColumn('col_datetimetz', 'datetimetz');
274

Sergei Morozov's avatar
Sergei Morozov committed
275
        $this->schemaManager->dropAndCreateTable($table);
276

Sergei Morozov's avatar
Sergei Morozov committed
277
        $columns = $this->schemaManager->listTableColumns('tbl_date');
278

279 280 281
        self::assertSame('date', $columns['col_date']->getType()->getName());
        self::assertSame('datetime', $columns['col_datetime']->getType()->getName());
        self::assertSame('datetimetz', $columns['col_datetimetz']->getType()->getName());
282
    }
283 284 285 286 287

    public function testCreateAndListSequences() : void
    {
        self::markTestSkipped("Skipped for uppercase letters are contained in sequences' names. Fix the schema manager in 3.0.");
    }
Steve Müller's avatar
Steve Müller committed
288
}