From 46c853146b05b23057800a1cf42e03f96ae0c45b Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 27 Aug 2024 12:33:20 +0200 Subject: [PATCH] fix(migration): Correctly sort migrations by version number Signed-off-by: Joas Schilling --- lib/private/DB/MigrationService.php | 34 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/lib/private/DB/MigrationService.php b/lib/private/DB/MigrationService.php index 68f31fff3fcac..61a6d2baf1662 100644 --- a/lib/private/DB/MigrationService.php +++ b/lib/private/DB/MigrationService.php @@ -158,7 +158,7 @@ private function createMigrationTable(): bool { /** * Returns all versions which have already been applied * - * @return string[] + * @return list * @codeCoverageIgnore - no need to test this */ public function getMigratedVersions() { @@ -174,6 +174,8 @@ public function getMigratedVersions() { $rows = $result->fetchAll(\PDO::FETCH_COLUMN); $result->closeCursor(); + usort($rows, $this->sortMigrations(...)); + return $rows; } @@ -183,7 +185,23 @@ public function getMigratedVersions() { */ public function getAvailableVersions(): array { $this->ensureMigrationsAreLoaded(); - return array_map('strval', array_keys($this->migrations)); + $versions = array_map('strval', array_keys($this->migrations)); + usort($versions, $this->sortMigrations(...)); + return $versions; + } + + protected function sortMigrations(string $a, string $b): int { + preg_match('/(\d+)Date(\d+)/', basename($a), $matchA); + preg_match('/(\d+)Date(\d+)/', basename($b), $matchB); + if (!empty($matchA) && !empty($matchB)) { + $versionA = (int)$matchA[1]; + $versionB = (int)$matchB[1]; + if ($versionA !== $versionB) { + return ($versionA < $versionB) ? -1 : 1; + } + return ($matchA[2] < $matchB[2]) ? -1 : 1; + } + return (basename($a) < basename($b)) ? -1 : 1; } /** @@ -204,17 +222,7 @@ protected function findMigrations(): array { \RegexIterator::GET_MATCH); $files = array_keys(iterator_to_array($iterator)); - uasort($files, function ($a, $b) { - preg_match('/^Version(\d+)Date(\d+)\\.php$/', basename($a), $matchA); - preg_match('/^Version(\d+)Date(\d+)\\.php$/', basename($b), $matchB); - if (!empty($matchA) && !empty($matchB)) { - if ($matchA[1] !== $matchB[1]) { - return ($matchA[1] < $matchB[1]) ? -1 : 1; - } - return ($matchA[2] < $matchB[2]) ? -1 : 1; - } - return (basename($a) < basename($b)) ? -1 : 1; - }); + usort($files, $this->sortMigrations(...)); $migrations = [];