diff --git a/Dbal/MutableAclProvider.php b/Dbal/MutableAclProvider.php index 0d69ca6..a7e8c88 100644 --- a/Dbal/MutableAclProvider.php +++ b/Dbal/MutableAclProvider.php @@ -36,6 +36,7 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterface, PropertyChangedListener { private $propertyChanges; + private $transactionStarted = false; /** * {@inheritdoc} @@ -80,7 +81,12 @@ public function createAcl(ObjectIdentityInterface $oid) */ public function deleteAcl(ObjectIdentityInterface $oid) { - $this->connection->beginTransaction(); + // DBAL 4.0 does not support nested transactions, so we need to keep track of the transaction state + // @see https://github.com/doctrine/dbal/pull/5383 and https://github.com/doctrine/dbal/pull/5401 + if (!$this->transactionStarted) { + $this->connection->beginTransaction(); + $this->transactionStarted = true; + } try { foreach ($this->findChildren($oid, true) as $childOid) { $this->deleteAcl($childOid); @@ -92,9 +98,15 @@ public function deleteAcl(ObjectIdentityInterface $oid) $this->deleteObjectIdentityRelations($oidPK); $this->deleteObjectIdentity($oidPK); - $this->connection->commit(); + if ($this->transactionStarted) { + $this->connection->commit(); + $this->transactionStarted = false; + } } catch (\Exception $e) { - $this->connection->rollBack(); + if ($this->transactionStarted) { + $this->connection->rollBack(); + $this->transactionStarted = false; + } throw $e; } diff --git a/Dbal/Schema.php b/Dbal/Schema.php index 56ea9dc..ff9ee01 100644 --- a/Dbal/Schema.php +++ b/Dbal/Schema.php @@ -94,9 +94,9 @@ protected function addEntryTable() $table->addUniqueIndex(['class_id', 'object_identity_id', 'field_name', 'ace_order']); $table->addIndex(['class_id', 'object_identity_id', 'security_identity_id']); - $table->addForeignKeyConstraint($this->getTable($this->options['class_table_name']), ['class_id'], ['id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']); - $table->addForeignKeyConstraint($this->getTable($this->options['oid_table_name']), ['object_identity_id'], ['id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']); - $table->addForeignKeyConstraint($this->getTable($this->options['sid_table_name']), ['security_identity_id'], ['id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']); + $table->addForeignKeyConstraint($this->getTable($this->options['class_table_name'])->getName(), ['class_id'], ['id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']); + $table->addForeignKeyConstraint($this->getTable($this->options['oid_table_name'])->getName(), ['object_identity_id'], ['id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']); + $table->addForeignKeyConstraint($this->getTable($this->options['sid_table_name'])->getName(), ['security_identity_id'], ['id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']); } /** @@ -116,7 +116,7 @@ protected function addObjectIdentitiesTable() $table->addUniqueIndex(['object_identifier', 'class_id']); $table->addIndex(['parent_object_identity_id']); - $table->addForeignKeyConstraint($table, ['parent_object_identity_id'], ['id']); + $table->addForeignKeyConstraint($table->getName(), ['parent_object_identity_id'], ['id']); } /** @@ -137,8 +137,8 @@ protected function addObjectIdentityAncestorsTable() // MS SQL Server does not support recursive cascading $action = 'NO ACTION'; } - $table->addForeignKeyConstraint($oidTable, ['object_identity_id'], ['id'], ['onDelete' => $action, 'onUpdate' => $action]); - $table->addForeignKeyConstraint($oidTable, ['ancestor_id'], ['id'], ['onDelete' => $action, 'onUpdate' => $action]); + $table->addForeignKeyConstraint($oidTable->getName(), ['object_identity_id'], ['id'], ['onDelete' => $action, 'onUpdate' => $action]); + $table->addForeignKeyConstraint($oidTable->getName(), ['ancestor_id'], ['id'], ['onDelete' => $action, 'onUpdate' => $action]); } /** diff --git a/Tests/Dbal/MutableAclProviderTest.php b/Tests/Dbal/MutableAclProviderTest.php index d29a0d9..91e95f9 100644 --- a/Tests/Dbal/MutableAclProviderTest.php +++ b/Tests/Dbal/MutableAclProviderTest.php @@ -263,7 +263,7 @@ public function testUpdateDoesNothingWhenThereAreNoChanges() ; $con ->expects($this->never()) - ->method('executeUpdate') + ->method('executeStatement') ; $provider = new MutableAclProvider($con, new PermissionGrantingStrategy(), []); @@ -536,7 +536,6 @@ protected function setUp(): void ], $configuration ); - $this->connection->setNestTransactionsWithSavepoints(true); // import the schema $schema = new Schema($this->getOptions()); @@ -547,6 +546,7 @@ protected function setUp(): void protected function tearDown(): void { + $this->connection->close(); $this->connection = null; } diff --git a/composer.json b/composer.json index 22eaea5..4504789 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "doctrine/cache": "^1.11|^2.0", "doctrine/common": "^2.2|^3", "doctrine/persistence": "^1.3.3|^2|^3", - "doctrine/dbal": "^2.13.1|^3.1", + "doctrine/dbal": "^2.13.1|^3.1|^4", "psr/log": "^1|^2|^3" }, "autoload": {