From da3da257648febf1afa259da8edba025130b7144 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Fri, 1 May 2026 18:56:15 +0000 Subject: [PATCH] update migration and installer --- installation/index.php | 64 +++++++++++++++++++++++++++--------------- migrate.php | 18 +++++++++++- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/installation/index.php b/installation/index.php index e36224e..b066075 100644 --- a/installation/index.php +++ b/installation/index.php @@ -10,6 +10,32 @@ $step = isset($_GET['step']) ? (int)$_GET['step'] : 1; $error = ''; $success = ''; +function installationMigrationSortKey(string $filePath): string { + $basename = basename($filePath); + + return match ($basename) { + '20260318_add_outlet_id_to_purchases.sql' => '20260318_10_add_outlet_id_to_purchases.sql', + '20260318_create_outlets_table.sql' => '20260318_20_create_outlets_table.sql', + '20260318_multi_outlet_schema.sql' => '20260318_30_multi_outlet_schema.sql', + '20260318_local_definitions.sql' => '20260318_40_local_definitions.sql', + '20260318_user_outlets_table.sql' => '20260318_50_user_outlets_table.sql', + default => $basename, + }; +} + +function installationMigrationFiles(): array { + $files = array_merge( + glob(__DIR__ . '/../db/migrations/*.sql') ?: [], + glob(__DIR__ . '/../db/migrations/*.php') ?: [] + ); + + usort($files, static function (string $left, string $right): int { + return strnatcasecmp(installationMigrationSortKey($left), installationMigrationSortKey($right)); + }); + + return $files; +} + // Step 1: Requirements if ($step === 1) { $requirements = [ @@ -143,36 +169,30 @@ if ($step === 3 && $_SERVER['REQUEST_METHOD'] === 'POST') { $stmt = $pdo->query("SELECT migration FROM migrations"); $executed = $stmt->fetchAll(PDO::FETCH_COLUMN); - $files = glob(__DIR__ . '/../db/migrations/*.sql'); - sort($files); - + $files = installationMigrationFiles(); foreach ($files as $file) { $migrationName = basename($file); - if (!in_array($migrationName, $executed)) { - $sql = file_get_contents($file); + if (!in_array($migrationName, $executed, true)) { try { - $pdo->exec($sql); + $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + if ($extension === 'php') { + include $file; + } else { + $sql = file_get_contents($file); + if ($sql === false) { + throw new RuntimeException('Unable to read migration file: ' . $migrationName); + } + $pdo->exec($sql); + } + $stmt = $pdo->prepare("INSERT INTO migrations (migration) VALUES (?)"); $stmt->execute([$migrationName]); - } catch (PDOException $e) { - // Ignore duplicate column errors or missing columns if schema already has them - // This is safe because complete_schema.sql might be partially updated + $executed[] = $migrationName; + } catch (Throwable $e) { + // Ignore migration errors here to keep setup resilient when schema/seed already contain parts of the change. } } } - - $php_files = glob(__DIR__ . '/../db/migrations/*.php'); - sort($php_files); - foreach ($php_files as $pfile) { - $migrationName = basename($pfile); - if (!in_array($migrationName, $executed)) { - try { - include $pfile; - $stmt = $pdo->prepare("INSERT INTO migrations (migration) VALUES (?)"); - $stmt->execute([$migrationName]); - } catch (Exception $e) {} - } - } // --- End Migrations --- // Ensure Admin Role exists (might be in schema but just in case) $stmt = $pdo->prepare("SELECT id FROM role_groups WHERE name = 'Administrator'"); diff --git a/migrate.php b/migrate.php index c1063bf..233be75 100644 --- a/migrate.php +++ b/migrate.php @@ -83,6 +83,20 @@ function getExecutedMigrations(PDO $pdo): array return array_fill_keys($rows, true); } +function migrationSortKey(string $filePath): string +{ + $basename = basename($filePath); + + return match ($basename) { + '20260318_add_outlet_id_to_purchases.sql' => '20260318_10_add_outlet_id_to_purchases.sql', + '20260318_create_outlets_table.sql' => '20260318_20_create_outlets_table.sql', + '20260318_multi_outlet_schema.sql' => '20260318_30_multi_outlet_schema.sql', + '20260318_local_definitions.sql' => '20260318_40_local_definitions.sql', + '20260318_user_outlets_table.sql' => '20260318_50_user_outlets_table.sql', + default => $basename, + }; +} + function getMigrationFiles(): array { $sqlFiles = glob(__DIR__ . '/db/migrations/*.sql') ?: []; @@ -90,7 +104,7 @@ function getMigrationFiles(): array $files = array_merge($sqlFiles, $phpFiles); usort($files, static function (string $left, string $right): int { - return strnatcasecmp(basename($left), basename($right)); + return strnatcasecmp(migrationSortKey($left), migrationSortKey($right)); }); return $files; @@ -160,6 +174,8 @@ function isIgnorableMigrationError(PDOException $exception): bool 'duplicate key name', 'duplicate entry', 'duplicate foreign key constraint name', + 'duplicate key on write or update', + 'errno: 121', 'check that column/key exists', ];