Skip to content

Commit

Permalink
mysqli TransactionManager (#336)
Browse files Browse the repository at this point in the history
  • Loading branch information
mondrake committed Sep 25, 2023
1 parent b1297e5 commit 76bf523
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 50 deletions.
48 changes: 28 additions & 20 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,54 @@ on:
branches: [ master ]

env:
DRUDBAL_DRUPAL_VERSION: "11.x"
DRUDBAL_DRUPAL_PROFILE: "standard"
SIMPLETEST_BASE_URL: "http://localhost:8080"
PHPUNIT_SKIP_CLASS: '[
"Drupal\\KernelTests\\Core\\Cache\\ApcuBackendTest",
"Drupal\\Tests\\file\\Functional\\FileAddPermissionsUpdateTest",
"Drupal\\Tests\\file\\Functional\\DownloadTest"
]'
DRUDBAL_DRUPAL_VERSION: "11.x"
DRUDBAL_DRUPAL_PROFILE: "standard"
SIMPLETEST_BASE_URL: "http://localhost:8080"
PHPUNIT_SKIP_CLASS: '[
"Drupal\\KernelTests\\Core\\Cache\\ApcuBackendTest",
"Drupal\\Tests\\file\\Functional\\FileAddPermissionsUpdateTest"
]'

jobs:

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

sqlite-pdo:
name: "SQLite with PDO"
runs-on: ubuntu-20.04
mysql-mysqli:
name: "MySql with mysqli"
runs-on: ubuntu-latest
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/mysqli"
DBAL_URL: "mysqli://root:@0.0.0.0:3306/drudbal"
SIMPLETEST_DB: "dbal://root:@0.0.0.0:3306/drudbal?module=drudbal&dbal_driver=mysqli"

strategy:
fail-fast: false
matrix:
php-version:
# - "8.1"
- "8.2"
test-args:
- "--group Database"
# - "--group Entity"
# - "--group Cache,Config"
# - "--group field,Field"
# - "--group file"
# - "--group views"
# - "-v --group Cache"
# - "-v --group Config"
# - "-v --group Entity"
# - "-v --group Installer"

services:
mysql:
image: "mysql:5.7"
options: >-
-e MYSQL_ALLOW_EMPTY_PASSWORD=yes
-e MYSQL_DATABASE=drudbal
ports:
- "3306:3306"

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

- name: Checkout Drupal
Expand All @@ -62,6 +69,7 @@ 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: |
Expand Down
38 changes: 22 additions & 16 deletions src/Driver/Database/dbal/DbalExtension/AbstractExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,37 +257,43 @@ public function delegateHasJson(): bool {
* Transaction delegated methods.
*/

/**
* {@inheritdoc}
*/
public function delegateInTransaction(): bool {
return $this->getDbalConnection()->isTransactionActive();
}

/**
* {@inheritdoc}
*/
public function delegateBeginTransaction(): bool {
return $this->getDbalConnection()->beginTransaction();;
return $this->getDbalConnection()->beginTransaction();
}

public function delegateAddClientSavepoint($name): bool {
$this->getDbalConnection()->executeStatement('SAVEPOINT ' . $name);
return TRUE;
}

public function delegateRollbackClientSavepoint($name): bool {
$this->getDbalConnection()->executeStatement('ROLLBACK TO SAVEPOINT ' . $name);
return TRUE;
}

public function delegateReleaseClientSavepoint($name): bool {
try {
$this->getDbalConnection()->executeStatement('RELEASE SAVEPOINT ' . $name);
return TRUE;
}
catch (DbalDriverException $e) {
// Continue.
}
return FALSE;
}

/**
* {@inheritdoc}
*/
public function delegateRollBack(): bool {
return $this->getDbalConnection()->rollBack();
}

/**
* {@inheritdoc}
*/
public function delegateCommit(): bool {
return $this->getDbalConnection()->commit();
}

/**
* {@inheritdoc}
*/
public function delegateReleaseSavepointExceptionProcess(DbalDriverException $e) {
throw new \LogicException("Method " . __METHOD__ . " not implemented.");
}
Expand Down
33 changes: 33 additions & 0 deletions src/Driver/Database/dbal/DbalExtension/DbalExtensionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,39 @@ public function delegateInTransaction(): bool;
*/
public function delegateBeginTransaction(): bool;

/**
* Adds a savepoint on the client transaction.
*
* @param string $name
* The name of the savepoint.
*
* @return bool
* Returns TRUE on success or FALSE on failure.
*/
public function delegateAddClientSavepoint($name): bool;

/**
* Rolls back to a savepoint on the client transaction.
*
* @param string $name
* The name of the savepoint.
*
* @return bool
* Returns TRUE on success or FALSE on failure.
*/
public function delegateRollbackClientSavepoint($name): bool;

/**
* Releases a savepoint on the client transaction.
*
* @param string $name
* The name of the savepoint.
*
* @return bool
* Returns TRUE on success or FALSE on failure.
*/
public function delegateReleaseClientSavepoint($name): bool;

/**
* Handles rollback of the current transaction.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/Driver/Database/dbal/Statement/StatementWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset =
\PDO::FETCH_LAZY, \PDO::FETCH_OBJ => $this->assocToObj($row),
// @phpstan-ignore-next-line
\PDO::FETCH_CLASS | \PDO::FETCH_CLASSTYPE => $this->assocToClassType($row, $this->fetchOptions['constructor_args']),
\PDO::FETCH_CLASS => $this->assocToClass($row, $this->fetchOptions['class'], $this->fetchOptions['constructor_args']),
\PDO::FETCH_CLASS => $this->assocToClass($row, $this->fetchOptions['class'], $this->fetchOptions['constructor_args'] ?? []),
// @phpstan-ignore-next-line
\PDO::FETCH_INTO => $this->assocIntoObject($row, $this->fetchOptions['object']),
\PDO::FETCH_COLUMN => $this->assocToColumn($row, $columnNames, $this->fetchOptions['column']),
Expand Down Expand Up @@ -337,7 +337,7 @@ public function fetchField($index = 0) {
/**
* {@inheritdoc}
*/
public function fetchObject(string $class_name = NULL, array $constructor_arguments = NULL) {
public function fetchObject(string $class_name = NULL, array $constructor_arguments = []) {
if (isset($class_name)) {
$this->fetchStyle = \PDO::FETCH_CLASS;
$this->fetchOptions = [
Expand Down
49 changes: 37 additions & 12 deletions src/Driver/Database/dbal/TransactionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,55 @@
*/
class TransactionManager extends TransactionManagerBase {

/**
* {@inheritdoc}
*/
protected function beginClientTransaction(): bool {
return $this->connection->getDbalConnection()->beginTransaction();
/** @var \Drupal\drudbal\Driver\Database\dbal\Connection $connection */
$connection = $this->connection;
return $connection->getDbalExtension()->delegateBeginTransaction();
}

protected function addClientSavepoint(string $name): bool {
/** @var \Drupal\drudbal\Driver\Database\dbal\Connection $connection */
$connection = $this->connection;
return $connection->getDbalExtension()->delegateAddClientSavepoint($name);
}

protected function rollbackClientSavepoint(string $name): bool {
/** @var \Drupal\drudbal\Driver\Database\dbal\Connection $connection */
$connection = $this->connection;
return $connection->getDbalExtension()->delegateRollbackClientSavepoint($name);
}

protected function releaseClientSavepoint(string $name): bool {
/** @var \Drupal\drudbal\Driver\Database\dbal\Connection $connection */
$connection = $this->connection;
if ($connection->getDbalExtension()->delegateReleaseClientSavepoint($name)) {
return TRUE;
}
// If the rollback failed, most likely the savepoint was not there
// because the transaction is no longer active. In this case we rollback
// to root and cleanup.
$connection->getDbalExtension()->delegateRollBack();
$this->resetStack();
$this->setConnectionTransactionState(ClientConnectionTransactionState::Voided);
$this->processPostTransactionCallbacks();
return TRUE;
}

/**
* {@inheritdoc}
*/
protected function rollbackClientTransaction(): bool {
$clientRollback = $this->connection->getDbalConnection()->rollBack();
/** @var \Drupal\drudbal\Driver\Database\dbal\Connection $connection */
$connection = $this->connection;
$clientRollback = $connection->getDbalExtension()->delegateRollBack();
$this->setConnectionTransactionState($clientRollback ?
ClientConnectionTransactionState::RolledBack :
ClientConnectionTransactionState::RollbackFailed
);
return $clientRollback;
}

/**
* {@inheritdoc}
*/
protected function commitClientTransaction(): bool {
$clientCommit = $this->connection->getDbalConnection()->commit();
/** @var \Drupal\drudbal\Driver\Database\dbal\Connection $connection */
$connection = $this->connection;
$clientCommit = $connection->getDbalExtension()->delegateCommit();
$this->setConnectionTransactionState($clientCommit ?
ClientConnectionTransactionState::Committed :
ClientConnectionTransactionState::CommitFailed
Expand Down

0 comments on commit 76bf523

Please sign in to comment.