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

Fix SchemaTest::testChangeSerialFieldLength for Oracle #322

Merged
merged 57 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
19ecc5b
I
mondrake Apr 19, 2023
37500a7
II
mondrake Apr 22, 2023
d9a3178
IV
mondrake Apr 22, 2023
1c5009e
V
mondrake Apr 22, 2023
920e5fd
Update Oci8Extension.php
mondrake Apr 22, 2023
01689c7
Update Oci8Extension.php
mondrake Apr 22, 2023
122dfdc
Update Oci8Extension.php
mondrake Apr 22, 2023
0c2b444
Update Oci8Extension.php
mondrake Apr 22, 2023
9c65905
VI
mondrake Apr 22, 2023
de3602e
VII
mondrake Apr 22, 2023
98abb38
VIII
mondrake Apr 22, 2023
a9b7594
iX
mondrake Apr 22, 2023
42dc0e6
X
mondrake Apr 22, 2023
404d001
XI
mondrake Apr 22, 2023
6f2c574
XII
mondrake Apr 22, 2023
cb96fb6
XIII
mondrake Apr 22, 2023
c44ed74
Revert "XIII"
mondrake Apr 22, 2023
6b33e12
Revert "XII"
mondrake Apr 22, 2023
e4ad2ad
Revert "XI"
mondrake Apr 22, 2023
d3b6d6c
XIV
mondrake Apr 23, 2023
cdafb6f
XVI
mondrake Apr 23, 2023
355b0e0
XVII
mondrake Apr 23, 2023
34e7535
XVIII
mondrake Apr 23, 2023
4d1d152
xix
mondrake Apr 23, 2023
529d4b4
XX
mondrake Apr 23, 2023
8015d6c
XXI
mondrake Apr 23, 2023
600216f
XXII
mondrake Apr 23, 2023
128a739
XXII
mondrake Apr 23, 2023
3369a63
XXIII
mondrake Apr 23, 2023
fae967c
xxiv
mondrake Apr 23, 2023
37f1039
xxv
mondrake Apr 23, 2023
82710bb
xxvi
mondrake Apr 23, 2023
8a40cb2
XXVII
mondrake Apr 24, 2023
2cb3977
XXX
mondrake Apr 24, 2023
853bbd8
XXXI
mondrake Apr 24, 2023
fca4649
XXXII
mondrake Apr 24, 2023
20c7cab
xxxiii
mondrake Apr 24, 2023
c7a5f55
xxxiv
mondrake Apr 24, 2023
f3efe55
xxxv
mondrake Apr 24, 2023
7963b78
xxxv
mondrake Apr 24, 2023
b233a6f
xxxvii
mondrake Apr 24, 2023
28b6338
xxxviii
mondrake Apr 24, 2023
50e0c9e
xxxix
mondrake Apr 24, 2023
caec6a4
xl
mondrake Apr 24, 2023
038c954
XLI
mondrake Apr 24, 2023
a9cfe6c
XLII
mondrake Apr 24, 2023
07246e0
XLIII
mondrake Apr 24, 2023
4b65627
XLV
mondrake Apr 24, 2023
dc1b96d
XLVII
mondrake Apr 24, 2023
0e07327
XLVII
mondrake Apr 24, 2023
5dc840f
XLIX
mondrake Apr 24, 2023
af8af94
L
mondrake Apr 25, 2023
297a82b
LI
mondrake Apr 25, 2023
1e8ecad
LII
mondrake Apr 25, 2023
2cde7be
LIII
mondrake Apr 25, 2023
1616d1a
LIII
mondrake Apr 25, 2023
e3539e6
lv
mondrake Apr 25, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/oracle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:

services:
oracle:
image: gvenzl/oracle-xe:21
image: gvenzl/oracle-xe:slim-faststart
env:
ORACLE_PASSWORD: oracle
ports:
Expand Down
44 changes: 34 additions & 10 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,43 @@ env:
PHPUNIT_SKIP_CLASS: '[
"Drupal\\KernelTests\\Core\\Cache\\ApcuBackendTest",
"Drupal\\Tests\\file\\Functional\\FileAddPermissionsUpdateTest",
"Drupal\\Tests\\file\\Functional\\DownloadTest",
"Drupal\\KernelTests\\Core\\Database\\SchemaUniquePrefixedKeysIndexTest"
]'

jobs:

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

sqlite-pdo:
name: "SQLite with PDO"
oracle-oci8:
name: "Oracle on Oci8"
runs-on: ubuntu-20.04
env:
DRUDBAL_ENV: "dbal/sqlite/file"
DBAL_URL: "sqlite://localhost/sites/drudbal.sqlite"
SIMPLETEST_DB: "dbal://localhost/sites/drudbal.sqlite?module=drudbal&dbal_driver=pdo_sqlite"
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:slim-faststart
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"
- "-v modules/contrib/drudbal/tests/src/Kernel/dbal/SchemaBisTest.php"
- "-v modules/contrib/drudbal/tests/src/Kernel/dbal/SchemaTest.php"
# - "--group Database"
# - "--group Entity"
# - "--group Cache,Config"
# - "--group field,Field"
Expand All @@ -47,6 +60,7 @@ jobs:
with:
php-version: "${{ matrix.php-version }}"
coverage: "none"
extensions: "oci8"
ini-values: "zend.assertions=1"

- name: Checkout Drupal
Expand All @@ -63,21 +77,31 @@ jobs:
- name: Install Composer dependencies
run: |
composer install --no-progress --ansi
composer config --no-plugins allow-plugins.composer/package-versions-deprecated true

- name: Composer require DruDbal from local staging
run: |
git -C drudbal_staging checkout -b test-run-branch
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,4 @@ tbd | UpdateTestBase
[#2992274](https://www.drupal.org/project/drupal/issues/2992274) | Installer tests fail if contrib driver hides database credentials form fields |
[#3256642](https://www.drupal.org/project/drupal/issues/3256642) | Autoload classes of database drivers modules' dependencies |
[#3347497](https://www.drupal.org/project/drupal/issues/3347497) | Introduce a FetchModeTrait to allow emulating PDO fetch modes |
[#3355841](https://www.drupal.org/project/drupal/issues/3355841) | Allow DriverSpecificSchemaTestBase::testChangePrimaryKeyToSerial to execute for non-core drivers |
85 changes: 57 additions & 28 deletions src/Driver/Database/dbal/DbalExtension/Oci8Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -821,13 +821,8 @@ public function delegateAddField(&$primary_key_processed_by_extension, DbalSchem
$sql[] = "ALTER TABLE $db_table ADD $db_field $column_definition";

if ($drupal_field_specs['type'] === 'serial') {
/** @var OraclePlatform $platform */
$platform = $this->connection->getDbalPlatform();
$autoincrement_sql = $platform->getCreateAutoincrementSql($db_field, $db_table);
// Remove the auto primary key generation, which is the first element in
// the array.
array_shift($autoincrement_sql);
$sql = array_merge($sql, $autoincrement_sql);
$sql[] = $this->getAutoincrementSequenceSql($unquoted_db_table);
$sql[] = $this->getAutoincrementTriggerSql($unquoted_db_table, $unquoted_db_field);
}

if (!$has_primary_key && $db_primary_key_columns) {
Expand Down Expand Up @@ -907,20 +902,35 @@ public function delegateChangeField(&$primary_key_processed_by_extension, DbalSc
$db_primary_key_columns[$key] = $new_db_field;
}

// Drop primary key if needed.
if ($drop_primary_key) {
$db_pk_constraint = '';
$this->delegateDropPrimaryKey($primary_key_processed_by_extension, $db_pk_constraint, $dbal_schema, $drupal_table_name);
$has_primary_key = FALSE;
}

$sql = [];

// Drop autoincrement setup if new field is serial and setup exists
// already.
if ($new_db_field_is_serial) {
$sequenceName = "\"" . $unquoted_db_table . "_SEQ\"";
$autoincrementIdentifierName = "\"" . $unquoted_db_table ."_AI_PK\"";

$currentSchema = $this->getDbalConnection()->createSchemaManager()->introspectSchema();
if ($currentSchema->hasSequence($sequenceName)) {
$sql[] = 'DROP TRIGGER ' . $autoincrementIdentifierName;
$sql[] = 'DROP SEQUENCE ' . $sequenceName;
}
}

$temp_column = $this->getLimitedIdentifier(str_replace('-', '', 'tmp' . (new Uuid())->generate()));
$not_null = $drupal_field_new_specs['not null'] ?? FALSE;
$column_definition = str_replace($db_field, "\"$temp_column\"", $dbal_column_options['columnDefinition']);
if ($not_null) {
$column_definition = str_replace("NOT NULL", "NULL", $column_definition);
}

$sql = [];
$sql[] = "ALTER TABLE $db_table ADD \"$temp_column\" $column_definition";
$sql[] = "UPDATE $db_table SET \"$temp_column\" = $db_field";
$sql[] = "ALTER TABLE $db_table DROP COLUMN $db_field";
Expand All @@ -929,31 +939,19 @@ public function delegateChangeField(&$primary_key_processed_by_extension, DbalSc
$sql[] = "ALTER TABLE $db_table MODIFY $new_db_field NOT NULL";
}

if ($new_db_field_is_serial) {
$prev_max_sequence = (int) $this->connection->query("SELECT MAX({$db_field}) FROM {$db_table}")->fetchField();
/** @var OraclePlatform $platform */
$platform = $this->connection->getDbalPlatform();
$autoincrement_sql = $platform->getCreateAutoincrementSql($new_db_field, $db_table);
// Remove the auto primary key generation, which is the first element in
// the array.
array_shift($autoincrement_sql);
// Get the the sequence generation, which is the second element in the
// array.
$sequence_sql = array_shift($autoincrement_sql);
if ($prev_max_sequence) {
$sql[] = str_replace('START WITH 1', 'START WITH ' . $prev_max_sequence, $sequence_sql);
}
else {
$sql[] = $sequence_sql;
}
$sql = array_merge($sql, $autoincrement_sql);
}

// Add primary key if needed.
if (!$has_primary_key && $db_primary_key_columns) {
$db_pk_constraint = $db_pk_constraint ?? $unquoted_db_table . '_PK';
$sql[] = "ALTER TABLE $db_table ADD CONSTRAINT $db_pk_constraint PRIMARY KEY (" . implode(', ', $db_primary_key_columns) . ")";
}

// Add autoincrement if needed.
if ($new_db_field_is_serial) {
$prev_max_sequence = (int) $this->connection->query("SELECT MAX({$db_field}) FROM {$db_table}")->fetchField();
$sql[] = $this->getAutoincrementSequenceSql($unquoted_db_table, $prev_max_sequence + 1);
$sql[] = $this->getAutoincrementTriggerSql($unquoted_db_table, $unquoted_new_db_field);
}

if (isset($drupal_field_new_specs['description'])) {
$column_description = $this->connection->getDbalPlatform()->quoteStringLiteral($drupal_field_new_specs['description']);
$sql[] = "COMMENT ON COLUMN $db_table.$new_db_field IS " . $column_description;
Expand Down Expand Up @@ -993,9 +991,40 @@ public function delegateDropPrimaryKey(bool &$primary_key_dropped_by_extension,
assert(is_object($db_constraint));
$primary_key_asset_name = $db_constraint->name;
$exec = "ALTER TABLE $db_table DROP CONSTRAINT \"$primary_key_asset_name\"";
if ($this->getDebugging()) dump($exec);
$this->getDbalConnection()->executeStatement($exec);
$primary_key_dropped_by_extension = TRUE;
return TRUE;
}

private function getAutoincrementSequenceSql(string $unquotedTableName, int $start = 1): string {
return "CREATE SEQUENCE \"{$unquotedTableName}_SEQ\" START WITH {$start} MINVALUE {$start} INCREMENT BY 1";
}

private function getAutoincrementTriggerSql(string $unquotedTableName, string $unquotedColumnName): string {
$unquotedSequenceName = $unquotedTableName . '_SEQ';
return "
CREATE OR REPLACE TRIGGER \"{$unquotedTableName}_AI_PK\"
BEFORE INSERT
ON \"{$unquotedTableName}\"
FOR EACH ROW
DECLARE
pragma autonomous_transaction;
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
IF (:NEW.\"{$unquotedColumnName}\" IS NULL) THEN
SELECT \"{$unquotedSequenceName}\".NEXTVAL INTO :NEW.\"{$unquotedColumnName}\" FROM DUAL;
ELSE
SELECT :NEW.\"{$unquotedColumnName}\" INTO last_InsertID FROM DUAL;
SELECT (\"{$unquotedSequenceName}\".NEXTVAL - 1) INTO last_Sequence FROM DUAL;
IF (last_InsertID > last_Sequence) THEN
EXECUTE IMMEDIATE 'alter sequence \"{$unquotedSequenceName}\" INCREMENT BY ' || TO_CHAR(last_InsertID - last_Sequence -1);
SELECT \"{$unquotedSequenceName}\".NEXTVAL INTO last_Sequence FROM DUAL;
EXECUTE IMMEDIATE 'alter sequence \"{$unquotedSequenceName}\" INCREMENT BY 1';
END IF;
END IF;
END;";
}

}
3 changes: 3 additions & 0 deletions tests/github/drupal_patch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ git apply -v ./drudbal_staging/tests/github/2992274-local.patch

#3347497 Introduce a FetchModeTrait to allow emulating PDO fetch modes
curl https://git.drupalcode.org/project/drupal/-/merge_requests/3676.diff | git apply -v

#3355841 Allow DriverSpecificSchemaTestBase::testChangePrimaryKeyToSerial to execute for non-core drivers
curl https://www.drupal.org/files/issues/2023-04-23/3355841-2.patch | git apply -v
Loading