diff --git a/src/ORM/Connect/MySQLDatabase.php b/src/ORM/Connect/MySQLDatabase.php index 0aeb6067f9b..1157debc494 100644 --- a/src/ORM/Connect/MySQLDatabase.php +++ b/src/ORM/Connect/MySQLDatabase.php @@ -566,6 +566,35 @@ public function random() */ public function clearTable($table) { - $this->query("TRUNCATE TABLE \"$table\""); + // Not simply using "TRUNCATE TABLE \"$table\"" because DELETE is a lot quicker + // than TRUNCATE which is very relevant during unit testing. Using TRUNCATE will lead to an + // approximately 50% increase it the total time of running unit tests. + $self = $this; + $fn = function () use ($self, $table) { + $this->query("DELETE FROM \"$table\""); + // Check if resetting the auto-increment is needed + // Note that ALTER TABLE is an expensive operation so only do it if necessary + $autoIncrement = $self->preparedQuery( + 'SELECT "AUTO_INCREMENT" FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?', + [ $this->getSelectedDatabase(), $table] + )->value(); + if ($autoIncrement > 1) { + $self->query("ALTER TABLE \"$table\" AUTO_INCREMENT = 1"); + } + }; + if ($this->supportsTransactions()) { + // Wrap in a transaction because MySQL will use always use `max(ID) + 1` as a + // minimum value for auto-increment + // In MySQL 8, there were issues where the auto-increment was sometimes being reset to 2, + // presumbably due to some sort of timing issue + $this->withTransaction($fn); + } else { + $fn(); + } + } + + private function clearTableInner($table) + { + } }