#!/usr/bin/env php getModules(); if (count($modules) === 0) { fwrite(STDOUT, "module-migrate: no modules enabled, nothing to do.\n"); exit(0); } // Ensure tracking table exists (safe if already created by db/updates/ script) DB::execute( 'CREATE TABLE IF NOT EXISTS `module_migrations` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `module_id` VARCHAR(64) NOT NULL, `filename` VARCHAR(255) NOT NULL, `applied_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uq_module_migration` (`module_id`, `filename`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' ); foreach ($modules as $manifest) { $migrationsPath = $manifest->migrationsPath; if ($migrationsPath === null || !is_dir($migrationsPath)) { continue; } // Discover SQL files $files = glob($migrationsPath . '/*.sql'); if ($files === false || count($files) === 0) { continue; } sort($files); // alphabetical order // Get already-applied filenames $applied = []; $rows = DB::select('SELECT filename FROM module_migrations WHERE module_id = ?', [$manifest->id]); foreach ($rows as $row) { $applied[$row['filename']] = true; } foreach ($files as $file) { $filename = basename($file); if (isset($applied[$filename])) { continue; } $sql = file_get_contents($file); if ($sql === false || trim($sql) === '') { fwrite(STDERR, sprintf("module-migrate: WARNING skipping empty file %s/%s\n", $manifest->id, $filename)); continue; } fwrite(STDOUT, sprintf("module-migrate: applying %s/%s ... ", $manifest->id, $filename)); // Execute migration (may contain multiple statements) $statements = array_filter(array_map('trim', explode(';', $sql)), static fn (string $s): bool => $s !== ''); foreach ($statements as $statement) { DB::execute($statement); } // Record as applied DB::execute( 'INSERT INTO module_migrations (module_id, filename) VALUES (?, ?)', [$manifest->id, $filename] ); fwrite(STDOUT, "OK\n"); $totalApplied++; } } if ($totalApplied === 0) { fwrite(STDOUT, "module-migrate: all modules up to date, 0 new migrations.\n"); } else { fwrite(STDOUT, sprintf("module-migrate: applied %d migration(s).\n", $totalApplied)); } } catch (Throwable $exception) { fwrite(STDERR, sprintf("module-migrate: FAILED: %s\n", $exception->getMessage())); $exitCode = 1; } finally { DB::close(); } exit($exitCode);