registry->getModules(); if (count($modules) === 0) { fwrite(STDOUT, "module-migrate: no modules enabled, nothing to do.\n"); return ['ok' => true, 'applied' => 0]; } $this->repository->ensureTrackingTable(); $totalApplied = 0; foreach ($modules as $manifest) { $migrationsPath = $manifest->migrationsPath; if ($migrationsPath === null || !is_dir($migrationsPath)) { continue; } $files = glob($migrationsPath . '/*.sql'); if ($files === false || count($files) === 0) { continue; } sort($files); $applied = $this->repository->getAppliedFilenames((string) $manifest->id); 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)); $this->repository->beginTransaction(); try { $statements = SqlStatementParser::splitStatements($sql); foreach ($statements as $statement) { $this->repository->executeStatement($statement); } $this->repository->recordApplied((string) $manifest->id, $filename); $this->repository->commit(); } catch (\Throwable $migrationError) { $this->repository->rollback(); throw new RuntimeException( sprintf("Migration %s/%s failed: %s", $manifest->id, $filename, $migrationError->getMessage()), 0, $migrationError ); } 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)); } return ['ok' => true, 'applied' => $totalApplied]; } }