From 3cdfe7b0f40a52b39f128a86f00ed5c04398693b Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 8 Jan 2021 16:25:40 +0100 Subject: [PATCH 1/2] Don't try a transaction for the migrator on MySQL As per https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html CREATE TABLE statements automatically commit always. The only reason this worked in the past was that PHPs PDO connection didn't check the actual state on commit, but only checked their internal state. But in PHP8 this was fixed: https://github.com/php/php-src/blob/PHP-8.0/UPGRADING#L446-L450 So now commit() fails because the internal PDO connection implicitly commited already. Signed-off-by: Joas Schilling --- lib/private/DB/Migrator.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/private/DB/Migrator.php b/lib/private/DB/Migrator.php index f62735ea6b..e50927f620 100644 --- a/lib/private/DB/Migrator.php +++ b/lib/private/DB/Migrator.php @@ -32,6 +32,7 @@ namespace OC\DB; use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Schema\AbstractAsset; use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Index; @@ -238,14 +239,18 @@ class Migrator { $schemaDiff = $this->getDiff($targetSchema, $connection); - $connection->beginTransaction(); + if (!$connection->getDatabasePlatform() instanceof MySQLPlatform) { + $connection->beginTransaction(); + } $sqls = $schemaDiff->toSql($connection->getDatabasePlatform()); $step = 0; foreach ($sqls as $sql) { $this->emit($sql, $step++, count($sqls)); $connection->query($sql); } - $connection->commit(); + if (!$connection->getDatabasePlatform() instanceof MySQLPlatform) { + $connection->commit(); + } } /** From 2d34ca4143f6ddeb2e0be8d6bca99469a5d08792 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 11 Jan 2021 16:10:16 +0100 Subject: [PATCH 2/2] Only rollback when not MySQL Signed-off-by: Joas Schilling --- tests/lib/DB/MigratorTest.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/lib/DB/MigratorTest.php b/tests/lib/DB/MigratorTest.php index 539eb404bb..6f3ebbb2b0 100644 --- a/tests/lib/DB/MigratorTest.php +++ b/tests/lib/DB/MigratorTest.php @@ -10,7 +10,9 @@ namespace Test\DB; use Doctrine\DBAL\Exception; +use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Platforms\OraclePlatform; +use Doctrine\DBAL\Platforms\SqlitePlatform; use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\SchemaConfig; use OC\DB\SchemaWrapper; @@ -122,7 +124,11 @@ class MigratorTest extends \Test\TestCase { } private function isSQLite() { - return $this->connection->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver; + return $this->connection->getDatabasePlatform() instanceof SqlitePlatform; + } + + private function isMySQL() { + return $this->connection->getDatabasePlatform() instanceof MySQLPlatform; } @@ -143,7 +149,9 @@ class MigratorTest extends \Test\TestCase { try { $migrator->migrate($endSchema); } catch (Exception\UniqueConstraintViolationException $e) { - $this->connection->rollBack(); + if (!$this->isMySQL()) { + $this->connection->rollBack(); + } throw $e; } }