62 lines
1.6 KiB
PHP
62 lines
1.6 KiB
PHP
<?php
|
||||
|
|
declare(strict_types=1);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 数据库迁移入口 —— **只在命令行跑**。
|
|||
|
|
*
|
|||
|
|
* php tools/migrate.php 执行迁移(幂等,可反复跑)
|
|||
|
|
* php tools/migrate.php --status 只看当前版本,不改任何东西
|
|||
|
|
*
|
|||
|
|
* 放在站点目录里意味着它理论上能被 HTTP 访问到,所以第一件事就是
|
|||
|
|
* 拒绝非 CLI 调用 —— 否则任何人都能触发一次结构变更。
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
if (PHP_SAPI !== 'cli') {
|
|||
|
|
http_response_code(404);
|
|||
|
|
exit('Not Found');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
require dirname(__DIR__) . '/src/Database.php';
|
|||
|
|
require dirname(__DIR__) . '/src/Migrate.php';
|
|||
|
|
|
|||
|
|
use App\Database;
|
|||
|
|
use App\Migrate;
|
|||
|
|
|
|||
|
|
$statusOnly = in_array('--status', $argv, true);
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
$db = Database::get();
|
|||
|
|
} catch (Throwable $e) {
|
|||
|
|
fwrite(STDERR, "无法连接数据库:" . $e->getMessage() . "\n");
|
|||
|
|
exit(1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$current = Migrate::currentVersion($db);
|
|||
|
|
$target = Migrate::VERSION;
|
|||
|
|
|
|||
|
|
echo "数据库:迁移版本 当前={$current} 目标={$target}\n";
|
|||
|
|
|
|||
|
|
if ($statusOnly) {
|
|||
|
|
echo $current === $target ? "状态:已是最新\n" : "状态:需要执行迁移(php tools/migrate.php)\n";
|
|||
|
|
exit(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($current === $target) {
|
|||
|
|
echo "无需迁移。\n";
|
|||
|
|
exit(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
echo "开始迁移……\n";
|
|||
|
|
try {
|
|||
|
|
$done = Migrate::run($db, static function (string $s): void {
|
|||
|
|
echo $s . "\n";
|
|||
|
|
});
|
|||
|
|
} catch (Throwable $e) {
|
|||
|
|
fwrite(STDERR, "迁移失败:" . $e->getMessage() . "\n");
|
|||
|
|
exit(1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
echo $done === []
|
|||
|
|
? "本次没有需要执行的步骤(结构已是目标状态)。\n"
|
|||
|
|
: '迁移完成,共 ' . count($done) . " 步。\n";
|