36293-vm/db/migrate.php
2025-11-26 16:15:14 +00:00

81 lines
3.3 KiB
PHP

<?php
// Simple migration script
require_once __DIR__ . '/config.php';
try {
$pdo = db();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Create migrations table if it doesn't exist
$pdo->exec("CREATE TABLE IF NOT EXISTS migrations (
id INT AUTO_INCREMENT PRIMARY KEY,
migration_name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)");
// Get all migration files
$migrationFiles = glob(__DIR__ . '/migrations/*.sql');
// Get already run migrations
$stmt = $pdo->query("SELECT migration_name FROM migrations");
$runMigrations = $stmt->fetchAll(PDO::FETCH_COLUMN);
echo '<html><head><title>Database Migrations</title>';
echo '<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">';
echo '<style>body { padding: 2rem; } .log { font-family: monospace; white-space: pre; } </style>';
echo '</head><body><div class="container">';
echo '<h1>Database Migrations</h1>';
$migrationsApplied = false;
foreach ($migrationFiles as $file) {
$migrationName = basename($file);
if (!in_array($migrationName, $runMigrations)) {
echo '<div class="alert alert-info log">Applying migration: ' . htmlspecialchars($migrationName) . '...</div>';
$sql = file_get_contents($file);
$statements = array_filter(array_map('trim', explode(';', $sql)));
$fileHasError = false;
foreach ($statements as $statement) {
if (empty($statement)) continue;
try {
$pdo->exec($statement);
} catch (PDOException $e) {
// 1060 is the specific error code for "Duplicate column name"
if (strpos($e->getMessage(), '1060') !== false) {
// It's a duplicate column error, we can ignore it.
echo '<div class="alert alert-warning log">Ignoring existing column in ' . htmlspecialchars($migrationName) . '.</div>';
} else {
// It's another error, so we should stop.
echo '<div class="alert alert-danger log">Error applying migration ' . htmlspecialchars($migrationName) . ': ' . htmlspecialchars($e->getMessage()) . '</div>';
$fileHasError = true;
break; // break from statements loop
}
}
}
if (!$fileHasError) {
// Record migration
$stmt = $pdo->prepare("INSERT INTO migrations (migration_name) VALUES (?)");
$stmt->execute([$migrationName]);
echo '<div class="alert alert-success log">Successfully applied ' . htmlspecialchars($migrationName) . '</div>';
$migrationsApplied = true;
} else {
// Stop on error
break; // break from files loop
}
}
}
if (!$migrationsApplied) {
echo '<div class="alert alert-success log">Database is already up to date.</div>';
}
echo '<a href="/" class="btn btn-primary mt-3">Back to Home</a>';
echo '</div></body></html>';
} catch (PDOException $e) {
http_response_code(500);
die("Database connection failed: " . $e->getMessage());
}