Fixes db migration code
parent
08953c6272
commit
f22fa76987
|
@ -139,6 +139,10 @@ class Feedback {
|
|||
'type' => self::TYPE_ERROR,
|
||||
'dismissible' => false
|
||||
],
|
||||
'MIGRATIONS_PENDING' => [
|
||||
'type' => self::TYPE_WARNING,
|
||||
'dismissible' => true
|
||||
],
|
||||
];
|
||||
|
||||
private static $strings = null;
|
||||
|
|
|
@ -7,12 +7,28 @@ use Exception;
|
|||
|
||||
class MigrationRunner
|
||||
{
|
||||
private PDO $db;
|
||||
private PDO $pdo;
|
||||
private string $migrationsDir;
|
||||
|
||||
public function __construct(PDO $db, string $migrationsDir)
|
||||
/**
|
||||
* @param mixed $db Either a PDO instance or the application's Database wrapper
|
||||
* @param string $migrationsDir Directory containing .sql migrations
|
||||
*/
|
||||
public function __construct($db, string $migrationsDir)
|
||||
{
|
||||
$this->db = $db;
|
||||
// Normalize to PDO
|
||||
if ($db instanceof PDO) {
|
||||
$this->pdo = $db;
|
||||
} elseif (is_object($db) && method_exists($db, 'getConnection')) {
|
||||
$pdo = $db->getConnection();
|
||||
if (!$pdo instanceof PDO) {
|
||||
throw new Exception('Database wrapper did not return a PDO instance');
|
||||
}
|
||||
$this->pdo = $pdo;
|
||||
} else {
|
||||
$type = is_object($db) ? get_class($db) : gettype($db);
|
||||
throw new Exception("Unsupported database type: {$type}");
|
||||
}
|
||||
$this->migrationsDir = rtrim($migrationsDir, '/');
|
||||
if (!is_dir($this->migrationsDir)) {
|
||||
throw new Exception("Migrations directory not found: {$this->migrationsDir}");
|
||||
|
@ -22,12 +38,21 @@ class MigrationRunner
|
|||
|
||||
private function ensureMigrationsTable(): void
|
||||
{
|
||||
$driver = $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
if ($driver === 'sqlite') {
|
||||
$sql = "CREATE TABLE IF NOT EXISTS migrations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
migration TEXT NOT NULL UNIQUE,
|
||||
applied_at TEXT NOT NULL
|
||||
)";
|
||||
} else {
|
||||
$sql = "CREATE TABLE IF NOT EXISTS migrations (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
migration VARCHAR(255) NOT NULL UNIQUE,
|
||||
applied_at DATETIME NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
|
||||
$this->db->exec($sql);
|
||||
}
|
||||
$this->pdo->exec($sql);
|
||||
}
|
||||
|
||||
public function listAllMigrations(): array
|
||||
|
@ -39,7 +64,7 @@ class MigrationRunner
|
|||
|
||||
public function listAppliedMigrations(): array
|
||||
{
|
||||
$stmt = $this->db->query('SELECT migration FROM migrations ORDER BY migration ASC');
|
||||
$stmt = $this->pdo->query('SELECT migration FROM migrations ORDER BY migration ASC');
|
||||
return $stmt->fetchAll(PDO::FETCH_COLUMN) ?: [];
|
||||
}
|
||||
|
||||
|
@ -64,7 +89,7 @@ class MigrationRunner
|
|||
}
|
||||
|
||||
try {
|
||||
$this->db->beginTransaction();
|
||||
$this->pdo->beginTransaction();
|
||||
foreach ($pending as $migration) {
|
||||
$path = $this->migrationsDir . '/' . $migration;
|
||||
$sql = file_get_contents($path);
|
||||
|
@ -75,16 +100,16 @@ class MigrationRunner
|
|||
$statements = array_filter(array_map('trim', preg_split('/;\s*\n/', $sql)));
|
||||
foreach ($statements as $stmtSql) {
|
||||
if ($stmtSql === '') continue;
|
||||
$this->db->exec($stmtSql);
|
||||
$this->pdo->exec($stmtSql);
|
||||
}
|
||||
$ins = $this->db->prepare('INSERT INTO migrations (migration, applied_at) VALUES (:m, NOW())');
|
||||
$ins = $this->pdo->prepare('INSERT INTO migrations (migration, applied_at) VALUES (:m, NOW())');
|
||||
$ins->execute([':m' => $migration]);
|
||||
$appliedNow[] = $migration;
|
||||
}
|
||||
$this->db->commit();
|
||||
$this->pdo->commit();
|
||||
} catch (Exception $e) {
|
||||
if ($this->db->inTransaction()) {
|
||||
$this->db->rollBack();
|
||||
if ($this->pdo->inTransaction()) {
|
||||
$this->pdo->rollBack();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
|
|
@ -44,5 +44,6 @@ return [
|
|||
'DB_ERROR' => 'Error connecting to the database: %s',
|
||||
'DB_CONNECT_ERROR' => 'Error connecting to DB: %s',
|
||||
'DB_UNKNOWN_TYPE' => 'Error: unknown database type "%s"',
|
||||
'MIGRATIONS_PENDING' => '%s',
|
||||
],
|
||||
];
|
||||
|
|
|
@ -194,7 +194,7 @@ try {
|
|||
$msg = 'Database schema is out of date. Pending migrations: ' . implode(', ', $pending) . '. Run: php scripts/migrate.php up';
|
||||
// Log and show as a system message
|
||||
$logObject->log('warning', $msg, ['scope' => 'system']);
|
||||
Feedback::flash('DB', 'MIGRATIONS_PENDING', $msg, false, true);
|
||||
Feedback::flash('SYSTEM', 'MIGRATIONS_PENDING', $msg, false, true);
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
|
|
Loading…
Reference in New Issue