load(); \support\App::loadAllConfig(['route']); use support\think\Db; $sql = (new ReflectionClass(Db::class))->getFileName(); $path = dirname(__DIR__) . '/plugin/saiadmin/db/20260923_add_water_mini_identity_menu.sql'; if (!is_file($path)) { fwrite(STDERR, "Migration file missing: $path\n"); exit(1); } $raw = file_get_contents($path); $statements = array_filter(array_map('trim', preg_split('/;\s*[\r\n]+/', $raw))); if (!$statements) { fwrite(STDERR, "No statements parsed.\n"); exit(1); } $apply = in_array('--apply', $argv, true); if (!$apply) { echo "Plan: " . count($statements) . " statements (idempotent). Re-run with --apply to execute.\n"; exit; } $conn = Db::connect(); $conn->startTrans(); try { foreach ($statements as $stmt) { $conn->execute($stmt); } $conn->commit(); echo "Applied: " . count($statements) . " statements.\n"; } catch (\Throwable $e) { $conn->rollback(); fwrite(STDERR, "Rollback due to: " . $e->getMessage() . "\n"); exit(1); }