feat: auto-migration dans Database et refactorisation du runner
This commit is contained in:
1 parent
8118f97b8f
commit
2069b66f9b
2 files changed
+67
-62
No files matched your search
+5
-49
@@ -2,59 +2,15 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
$root = dirname(__DIR__);
|
require dirname(__DIR__) . '/src/Database.php';
|
||||||
|
|
||||||
$pdo = new PDO('sqlite:' . $root . '/database/api_tube.sqlite');
|
$applied = Database::runMigrations();
|
||||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
$pdo->exec(
|
if ($applied === []) {
|
||||||
"CREATE TABLE IF NOT EXISTS migrations (
|
echo "Nothing to migrate.\n";
|
||||||
version TEXT PRIMARY KEY,
|
|
||||||
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
||||||
)"
|
|
||||||
);
|
|
||||||
|
|
||||||
$applied = array_column($pdo->query('SELECT version FROM migrations')->fetchAll(), 'version');
|
|
||||||
|
|
||||||
$files = glob($root . '/database/migrations/*.sql');
|
|
||||||
|
|
||||||
if ($files === false || $files === []) {
|
|
||||||
echo "Aucune migration trouvee.\n";
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
sort($files);
|
foreach ($applied as $version) {
|
||||||
|
|
||||||
$count = 0;
|
|
||||||
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$version = basename($file);
|
|
||||||
|
|
||||||
if (in_array($version, $applied, true)) {
|
|
||||||
echo "Skipped {$version}\n";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pdo->beginTransaction();
|
|
||||||
|
|
||||||
try {
|
|
||||||
$pdo->exec((string) file_get_contents($file));
|
|
||||||
|
|
||||||
$stmt = $pdo->prepare('INSERT INTO migrations (version) VALUES (:version)');
|
|
||||||
$stmt->execute(['version' => $version]);
|
|
||||||
|
|
||||||
$pdo->commit();
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
$pdo->rollBack();
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "Applied {$version}\n";
|
echo "Applied {$version}\n";
|
||||||
$applied[] = $version;
|
|
||||||
$count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($count === 0) {
|
|
||||||
echo "Nothing to migrate.\n";
|
|
||||||
}
|
}
|
||||||
+62
-13
@@ -8,21 +8,70 @@ final class Database
|
|||||||
|
|
||||||
public static function connect(): PDO
|
public static function connect(): PDO
|
||||||
{
|
{
|
||||||
if (self::$pdo !== null) {
|
if (self::$pdo === null) {
|
||||||
return self::$pdo;
|
self::init();
|
||||||
|
self::runMigrations();
|
||||||
}
|
}
|
||||||
|
|
||||||
$root = dirname(__DIR__);
|
|
||||||
$dsn = 'sqlite:' . $root . '/database/api_tube.sqlite';
|
|
||||||
|
|
||||||
self::$pdo = new PDO($dsn);
|
|
||||||
self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
self::$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|
||||||
self::$pdo->exec('PRAGMA foreign_keys = ON');
|
|
||||||
|
|
||||||
$schema = file_get_contents($root . '/database/schema.sql');
|
|
||||||
self::$pdo->exec($schema);
|
|
||||||
|
|
||||||
return self::$pdo;
|
return self::$pdo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function runMigrations(): array
|
||||||
|
{
|
||||||
|
if (self::$pdo === null) {
|
||||||
|
self::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
$root = dirname(__DIR__);
|
||||||
|
|
||||||
|
self::$pdo->exec(
|
||||||
|
"CREATE TABLE IF NOT EXISTS migrations (
|
||||||
|
version TEXT PRIMARY KEY,
|
||||||
|
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
)"
|
||||||
|
);
|
||||||
|
|
||||||
|
$applied = array_column(self::$pdo->query('SELECT version FROM migrations')->fetchAll(), 'version');
|
||||||
|
|
||||||
|
$files = glob($root . '/database/migrations/*.sql') ?: [];
|
||||||
|
sort($files);
|
||||||
|
|
||||||
|
$newlyApplied = [];
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$version = basename($file);
|
||||||
|
|
||||||
|
if (in_array($version, $applied, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
self::$pdo->beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
self::$pdo->exec((string) file_get_contents($file));
|
||||||
|
|
||||||
|
$stmt = self::$pdo->prepare('INSERT INTO migrations (version) VALUES (:version)');
|
||||||
|
$stmt->execute(['version' => $version]);
|
||||||
|
|
||||||
|
self::$pdo->commit();
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
self::$pdo->rollBack();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$newlyApplied[] = $version;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $newlyApplied;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function init(): void
|
||||||
|
{
|
||||||
|
$root = dirname(__DIR__);
|
||||||
|
|
||||||
|
self::$pdo = new PDO('sqlite:' . $root . '/database/api_tube.sqlite');
|
||||||
|
self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
self::$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||||
|
self::$pdo->exec('PRAGMA foreign_keys = ON');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user