CLI update apply db patches

This commit is contained in:
Roman 2021-04-09 12:37:24 +02:00
parent c863a9083e
commit a18b35f784
3 changed files with 69 additions and 28 deletions

85
cli.php

@ -21,7 +21,7 @@ function _exit(string $line = "") {
die(); die();
} }
if (php_sapi_name() !== "cli") { if (!is_cli()) {
_exit("Can only be executed via CLI"); _exit("Can only be executed via CLI");
} }
@ -36,11 +36,12 @@ function getDatabaseConfig(): ConnectionData {
return new $configClass(); return new $configClass();
} }
function getUser(): User { function getUser(): ?User {
$config = new Configuration(); $config = new Configuration();
$user = new User($config); $user = new User($config);
if (!$user->getSQL() || !$user->getSQL()->isConnected()) { if (!$user->getSQL() || !$user->getSQL()->isConnected()) {
_exit("Could not establish database connection"); printLine("Could not establish database connection");
return null;
} }
return $user; return $user;
@ -50,6 +51,33 @@ function printHelp() {
// TODO: help // TODO: help
} }
function applyPatch(\Driver\SQL\SQL $sql, string $patchName): bool {
$class = str_replace('/', '\\', $patchName);
$className = "\\Configuration\\$class";
$classPath = getClassPath($className);
if (!file_exists($classPath) || !is_readable($classPath)) {
printLine("Database script file does not exist or is not readable");
return false;
}
include_once $classPath;
$obj = new $className();
if (!($obj instanceof DatabaseScript)) {
printLine("Not a database script");
return false;
}
$queries = $obj->createQueries($sql);
foreach ($queries as $query) {
if (!$query->execute($sql)) {
printLine($sql->getLastError());
return false;
}
}
return true;
}
function handleDatabase(array $argv) { function handleDatabase(array $argv) {
$action = $argv[2] ?? ""; $action = $argv[2] ?? "";
@ -59,27 +87,9 @@ function handleDatabase(array $argv) {
_exit("Usage: cli.php db migrate <class name>"); _exit("Usage: cli.php db migrate <class name>");
} }
$class = str_replace('/', '\\', $class); $user = getUser() or die();
$className = "\\Configuration\\$class";
$classPath = getClassPath($className);
if (!file_exists($classPath) || !is_readable($classPath)) {
_exit("Database script file does not exist or is not readable");
}
include_once $classPath;
$obj = new $className();
if (!($obj instanceof DatabaseScript)) {
_exit("Not a database script");
}
$user = getUser();
$sql = $user->getSQL(); $sql = $user->getSQL();
$queries = $obj->createQueries($sql); applyPatch($sql, $class);
foreach ($queries as $query) {
if (!$query->execute($sql)) {
_exit($sql->getLastError());
}
}
} else if ($action === "export" || $action === "import") { } else if ($action === "export" || $action === "import") {
// database config // database config
@ -160,7 +170,7 @@ function handleDatabase(array $argv) {
proc_close($process); proc_close($process);
} }
} else if ($action === "clean") { } else if ($action === "clean") {
$user = getUser(); $user = getUser() or die();
$sql = $user->getSQL(); $sql = $user->getSQL();
printLine("Deleting user related data older than 90 days..."); printLine("Deleting user related data older than 90 days...");
@ -242,6 +252,7 @@ function onMaintenance(array $argv) {
_exit("Maintenance disabled"); _exit("Maintenance disabled");
} else if ($action === "update") { } else if ($action === "update") {
$oldPatchFiles = glob('core/Configuration/Patch/*.php');
printLine("$ git remote -v"); printLine("$ git remote -v");
exec("git remote -v", $gitRemote, $ret); exec("git remote -v", $gitRemote, $ret);
if ($ret !== 0) { if ($ret !== 0) {
@ -294,9 +305,26 @@ function onMaintenance(array $argv) {
printLine("Update could not be applied, check the git output."); printLine("Update could not be applied, check the git output.");
printLine("Follow the instructions and afterwards turn off the maintenance mode again using:"); printLine("Follow the instructions and afterwards turn off the maintenance mode again using:");
printLine("cli.php maintenance off"); printLine("cli.php maintenance off");
printLine("Also don't forget to apply new database patches using: cli.php db migrate");
die(); die();
} }
$newPatchFiles = glob('core/Configuration/Patch/*.php');
$newPatchFiles = array_diff($newPatchFiles, $oldPatchFiles);
if (count($newPatchFiles) > 0) {
printLine("Applying new database patches");
$user = getUser();
if ($user) {
$sql = $user->getSQL();
foreach ($newPatchFiles as $patchFile) {
if (preg_match("/core\/Configuration\/(Patch\/.*)\.class\.php/", $patchFile, $match)) {
$patchName = $match[1];
applyPatch($sql, $patchName);
}
}
}
}
// disable maintenance mode again // disable maintenance mode again
if (!$isMaintenanceEnabled) { if (!$isMaintenanceEnabled) {
printLine("Turning off maintenance mode"); printLine("Turning off maintenance mode");
@ -343,7 +371,7 @@ function printTable(array $head, array $body) {
// TODO: add missing api functions (should be all internal only i guess) // TODO: add missing api functions (should be all internal only i guess)
function onRoutes(array $argv) { function onRoutes(array $argv) {
$user = getUser(); $user = getUser() or die();
$action = $argv[2] ?? "list"; $action = $argv[2] ?? "list";
if ($action === "list") { if ($action === "list") {
@ -427,6 +455,10 @@ function onRoutes(array $argv) {
} }
} }
function onTest($argv) {
}
$argv = $_SERVER['argv']; $argv = $_SERVER['argv'];
if (count($argv) < 2) { if (count($argv) < 2) {
_exit("Usage: cli.php <db|routes|settings|maintenance> [options...]"); _exit("Usage: cli.php <db|routes|settings|maintenance> [options...]");
@ -446,6 +478,9 @@ switch ($command) {
case 'maintenance': case 'maintenance':
onMaintenance($argv); onMaintenance($argv);
break; break;
case 'test':
onTest($argv);
break;
default: default:
printLine("Unknown command '$command'"); printLine("Unknown command '$command'");
printLine(); printLine();

@ -22,13 +22,16 @@ class User extends ApiObject {
private array $groups; private array $groups;
public function __construct($configuration) { public function __construct($configuration) {
session_start();
$this->configuration = $configuration; $this->configuration = $configuration;
$this->setLanguage(Language::DEFAULT_LANGUAGE());
$this->reset(); $this->reset();
$this->connectDb(); $this->connectDb();
if (!is_cli()) {
session_start();
$this->setLanguage(Language::DEFAULT_LANGUAGE());
$this->parseCookies(); $this->parseCookies();
} }
}
public function __destruct() { public function __destruct() {
if($this->sql && $this->sql->isConnected()) { if($this->sql && $this->sql->isConnected()) {

@ -12,6 +12,9 @@ spl_autoload_register(function($class) {
} }
}); });
function is_cli(): bool {
return php_sapi_name() === "cli";
}
function getProtocol(): string { function getProtocol(): string {
$isSecure = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || $isSecure = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ||