65 lines
1.8 KiB
PHP
65 lines
1.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace andrewkydev\Database\Migration;
|
|
|
|
use andrewkydev\Database\Config\DatabaseConfig;
|
|
use andrewkydev\Database\Query\QueryRunner;
|
|
use andrewkydev\Database\Schema\SchemaManager;
|
|
|
|
final class MigrationManager {
|
|
/** @var array<int, Migration> */
|
|
private array $migrations = [];
|
|
|
|
public function __construct(
|
|
private SchemaManager $schema,
|
|
private QueryRunner $query,
|
|
private DatabaseConfig $config
|
|
) {
|
|
}
|
|
|
|
public function register(Migration $migration): void {
|
|
$this->migrations[$migration->version()] = $migration;
|
|
}
|
|
|
|
public function runPending(): void {
|
|
if (!$this->config->migrationsEnabled) {
|
|
return;
|
|
}
|
|
$this->ensureTable();
|
|
$applied = $this->appliedVersions();
|
|
ksort($this->migrations);
|
|
foreach ($this->migrations as $version => $migration) {
|
|
if (in_array($version, $applied, true)) {
|
|
continue;
|
|
}
|
|
$migration->up($this->schema, $this->query);
|
|
$this->query->execute(
|
|
'INSERT INTO ' . $this->config->migrationsTable . ' (version, applied_at) VALUES (?, ?)',
|
|
[$version, date('Y-m-d H:i:s')]
|
|
);
|
|
}
|
|
}
|
|
|
|
private function ensureTable(): void {
|
|
$sql = 'CREATE TABLE IF NOT EXISTS ' . $this->config->migrationsTable . ' ('
|
|
. 'version INT PRIMARY KEY, '
|
|
. 'applied_at VARCHAR(32) NOT NULL'
|
|
. ')';
|
|
$this->query->execute($sql);
|
|
}
|
|
|
|
/**
|
|
* @return int[]
|
|
*/
|
|
private function appliedVersions(): array {
|
|
$rows = $this->query->query('SELECT version FROM ' . $this->config->migrationsTable);
|
|
$versions = [];
|
|
foreach ($rows as $row) {
|
|
$versions[] = (int) $row['version'];
|
|
}
|
|
return $versions;
|
|
}
|
|
}
|