Skip to content
This repository has been archived by the owner on Jan 2, 2025. It is now read-only.

Fix SchemaTest for Oracle #313

Merged
merged 6 commits into from
Nov 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 36 additions & 19 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,47 @@ jobs:

#################################

mariadb-pdo:
name: "MariaDb"
runs-on: ubuntu-latest
oracle-oci8:
name: "Oracle on Oci8"
runs-on: ubuntu-20.04
env:
DRUDBAL_ENV: "dbal/mariadb"
DBAL_URL: "mysql://root:@0.0.0.0:3306/drudbal"
SIMPLETEST_DB: "dbal://root:@0.0.0.0:3306/drudbal?module=drudbal&dbal_driver=pdo_mysql"
DRUDBAL_ENV: "dbal/oci8"
DBAL_URL: "oci8://DRUDBAL:[email protected]:1521/XE"
SIMPLETEST_DB: "dbal://DRUDBAL:[email protected]:1521/XE?module=drudbal&dbal_driver=oci8#dru"

services:
oracle:
image: gvenzl/oracle-xe:21
env:
ORACLE_PASSWORD: oracle
ports:
- "1521:1521"
options: >-
--health-cmd healthcheck.sh
--health-interval 20s
--health-timeout 10s
--health-retries 10

strategy:
fail-fast: false
matrix:
php-version:
- "8.1"
# - "8.2"
test-args:
- "--group Database"

services:
mariadb:
image: "mariadb:10.5"
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: "drudbal"
ports:
- "3306:3306"
# - "--group Entity"
# - "--group Cache,Config"
# - "--group field,Field"
# - "--group file"
# - "--group views"

steps:
- name: Install PHP
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "none"
extensions: "pdo_mysql"
extensions: "oci8"
ini-values: "zend.assertions=1"

- name: Checkout Drupal
Expand All @@ -73,14 +81,23 @@ jobs:
composer config repositories.test-run '{"type": "path", "url": "drudbal_staging", "options": {"symlink": false}}'
composer require "mondrake/drudbal:dev-test-run-branch" --no-progress --ansi

- name: Install Drupal
- name: Patch doctrine/dbal
run: |
curl https://patch-diff.githubusercontent.com/raw/mondrake/dbal/pull/6.diff | patch -d vendor/doctrine/dbal -p1

- name: Create Oracle schema
run: |
cp modules/contrib/drudbal/tests/github/install_* .
php install_oracle.php

- name: Install Drupal
run: |
vendor/bin/drush site-install standard --db-url=$SIMPLETEST_DB -y
vendor/bin/drush runserver localhost:8080 --default-server=localhost:8080 &
sleep 1s
sleep 5s

- name: Report installation
continue-on-error: true
run: |
php install_report.php
vendor/bin/drush core:status
Expand Down
7 changes: 3 additions & 4 deletions src/Driver/Database/dbal/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Drupal\Core\Database\Schema as DatabaseSchema;
use Drupal\Core\Database\SchemaObjectDoesNotExistException;
use Drupal\Core\Database\SchemaObjectExistsException;
use Drupal\drudbal\Driver\Database\dbal\DbalExtension\DbalExtensionInterface;

/**
* DruDbal implementation of \Drupal\Core\Database\Schema.
Expand Down Expand Up @@ -42,10 +43,8 @@ class Schema extends DatabaseSchema {

/**
* The Dbal extension for the DBAL driver.
*
* @var \Drupal\drudbal\Driver\Database\dbal\DbalExtension\DbalExtensionInterface
*/
protected $dbalExtension;
protected DbalExtensionInterface $dbalExtension;

/**
* Constructs a Schema object.
Expand Down Expand Up @@ -844,7 +843,7 @@ public function fieldExists($table, $column) {
* @return \Doctrine\DBAL\Schema\Schema
* The DBAL schema of the database.
*/
private function dbalSchema() {
public function dbalSchema() {
if (!isset($this->dbalCurrentSchema)) {
$this->dbalSetCurrentSchema($this->dbalSchemaManager->introspectSchema());
}
Expand Down
112 changes: 112 additions & 0 deletions tests/src/Kernel/dbal/SchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -507,4 +507,116 @@ public function testUnsignedColumns(): void {
}
}

/**
* Tests handling with reserved keywords for naming tables, fields and more.
*/
public function testReservedKeywordsForNaming(): void {
$table_specification = [
'description' => 'A test table with an ANSI reserved keywords for naming.',
'fields' => [
'primary' => [
'description' => 'Simple unique ID.',
'type' => 'int',
'not null' => TRUE,
],
'update' => [
'description' => 'A column with reserved name.',
'type' => 'varchar',
'length' => 255,
],
'insert' => [
'description' => 'Another column with reserved name.',
'type' => 'varchar',
'length' => 255,
],
],
'primary key' => ['primary'],
'unique keys' => [
'having' => ['update'],
],
'indexes' => [
'in' => ['primary', 'update'],
],
];

// Creating a table.
$table_name = 'select';
$this->schema->createTable($table_name, $table_specification);
$this->assertTrue($this->schema->tableExists($table_name));

// Finding all tables.
$tables = $this->schema->findTables('%');
sort($tables);
$this->assertEquals(['config', 'select'], $tables);

// Renaming a table.
$table_name_new = 'from';
$this->schema->renameTable($table_name, $table_name_new);
$this->assertFalse($this->schema->tableExists($table_name));
$this->assertTrue($this->schema->tableExists($table_name_new));

// Adding a field.
$field_name = 'delete';
$this->schema->addField($table_name_new, $field_name, ['type' => 'int', 'not null' => TRUE]);
$this->assertTrue($this->schema->fieldExists($table_name_new, $field_name));

// Dropping a primary key.
$this->schema->dropPrimaryKey($table_name_new);

// Adding a primary key.
$this->schema->addPrimaryKey($table_name_new, [$field_name]);

// Check the primary key columns.
$find_primary_key_columns = new \ReflectionMethod(get_class($this->schema), 'findPrimaryKeyColumns');
$this->assertEquals([$field_name], $find_primary_key_columns->invoke($this->schema, $table_name_new));

// Dropping a primary key.
$this->schema->dropPrimaryKey($table_name_new);

// Changing a field.
$field_name_new = 'where';
$this->schema->changeField($table_name_new, $field_name, $field_name_new, ['type' => 'int', 'not null' => FALSE]);
$this->assertFalse($this->schema->fieldExists($table_name_new, $field_name));
$this->assertTrue($this->schema->fieldExists($table_name_new, $field_name_new));

// Adding an unique key
$unique_key_name = $unique_key_introspect_name = 'unique';
$this->schema->addUniqueKey($table_name_new, $unique_key_name, [$field_name_new]);

// Check the unique key columns.
// @todo this differs from core in the sense that the index name must be
// recalculated via ::getDbIndexName().
$introspect_index_schema = new \ReflectionMethod(get_class($this->schema), 'introspectIndexSchema');
$dbUniqueIndexName = $this->connection()->getDbalExtension()->getDbIndexName('indexExists', $this->schema()->dbalSchema(), $table_name_new, $unique_key_name);
$this->assertEquals([$field_name_new], $introspect_index_schema->invoke($this->schema, $table_name_new)['unique keys'][$dbUniqueIndexName]);

// Dropping an unique key
$this->schema->dropUniqueKey($table_name_new, $unique_key_name);

// Dropping a field.
$this->schema->dropField($table_name_new, $field_name_new);
$this->assertFalse($this->schema->fieldExists($table_name_new, $field_name_new));

// Adding an index.
// @todo this differs from core in the sense that we use a different column
// than 'update' - that would lead to duplicated index on Oracle.
$index_name = $index_introspect_name = 'index';
$this->schema->addIndex($table_name_new, $index_name, ['insert'], $table_specification);
$this->assertTrue($this->schema->indexExists($table_name_new, $index_name));

// Check the index columns.
// @todo this differs from core in the sense that the index name must be
// recalculated via ::getDbIndexName().
$dbIndexName = $this->connection()->getDbalExtension()->getDbIndexName('indexExists', $this->schema()->dbalSchema(), $table_name_new, $index_name);
$this->assertEquals(['insert'], $introspect_index_schema->invoke($this->schema, $table_name_new)['indexes'][$dbIndexName]);

// Dropping an index.
$this->schema->dropIndex($table_name_new, $index_name);
$this->assertFalse($this->schema->indexExists($table_name_new, $index_name));

// Dropping a table.
$this->schema->dropTable($table_name_new);
$this->assertFalse($this->schema->tableExists($table_name_new));
}

}