100 lines
2.8 KiB
PHP
100 lines
2.8 KiB
PHP
<?php
|
|
namespace nulib\db\_private;
|
|
|
|
use nulib\cl;
|
|
use nulib\db\IDatabase;
|
|
use nulib\php\func;
|
|
|
|
abstract class _migration {
|
|
const MIGRATION = null;
|
|
|
|
function __construct($migrations, string $channel="", ?IDatabase $db=null) {
|
|
$this->db = $db;
|
|
$this->channel = $channel;
|
|
if ($migrations === null) $migrations = static::MIGRATION;
|
|
if ($migrations === null) $migrations = [];
|
|
elseif (is_string($migrations)) $migrations = [$migrations];
|
|
elseif (is_callable($migrations)) $migrations = [$migrations];
|
|
elseif (!is_array($migrations)) $migrations = [strval($migrations)];
|
|
$this->migrations = $migrations;
|
|
}
|
|
|
|
protected ?IDatabase $db;
|
|
|
|
protected string $channel;
|
|
|
|
const MIGRATION_TABLE = "_migration";
|
|
const MIGRATION_COLS = [
|
|
"channel" => "varchar not null",
|
|
"name" => "varchar not null",
|
|
"done" => "integer not null default 0",
|
|
"primary key (channel, name)",
|
|
];
|
|
|
|
protected function ensureTable(): void {
|
|
$this->db->exec([
|
|
"create table if not exists",
|
|
"table" => static::MIGRATION_TABLE,
|
|
"cols" => static::MIGRATION_COLS,
|
|
]);
|
|
}
|
|
|
|
protected function isMigrated(string $name): bool {
|
|
return boolval($this->db->get([
|
|
"select 1",
|
|
"from" => static::MIGRATION_TABLE,
|
|
"where" => [
|
|
"channel" => $this->channel,
|
|
"name" => $name,
|
|
"done" => 1,
|
|
],
|
|
]));
|
|
}
|
|
|
|
abstract protected function setMigrated(string $name, bool $done): void;
|
|
|
|
/** @var callable[]|string[] */
|
|
protected $migrations;
|
|
|
|
function migrate(?IDatabase $db=null): void {
|
|
$db = ($this->db ??= $db);
|
|
$this->ensureTable();
|
|
foreach ($this->migrations as $name => $migration) {
|
|
if ($this->isMigrated($name)) continue;
|
|
$this->setMigrated($name, false);
|
|
if (func::is_callable($migration)) {
|
|
func::with($migration)->bind($this)->invoke([$db, $name]);
|
|
} else {
|
|
foreach (cl::with($migration) as $query) {
|
|
$db->exec($query);
|
|
}
|
|
}
|
|
$this->setMigrated($name, true);
|
|
}
|
|
}
|
|
|
|
protected static function sql_prefix(?string $source=null): string {
|
|
$prefix = "-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8\n";
|
|
if ($source !== null) $prefix .= "-- autogénéré à partir de $source\n";
|
|
return $prefix;
|
|
}
|
|
|
|
function getSql(?string $source=null, ?IDatabase $db=null): string {
|
|
$db = ($this->db ??= $db);
|
|
$lines = [self::sql_prefix($source)];
|
|
foreach ($this->migrations as $name => $migration) {
|
|
$lines[] = "-- $name";
|
|
if (func::is_callable($migration)) {
|
|
$lines[] = "-- <fonction PHP>";
|
|
} else {
|
|
foreach (cl::with($migration) as $query) {
|
|
$sql = $db->getSql($query);
|
|
$lines[] = "$sql;";
|
|
}
|
|
}
|
|
$lines[] = "";
|
|
}
|
|
return implode("\n", $lines);
|
|
}
|
|
}
|