adjusted database and install scripts
This commit is contained in:
parent
cd360560fc
commit
4b6554b870
@ -7,12 +7,12 @@ use Core\Driver\SQL\SQL;
|
|||||||
use Core\Objects\DatabaseEntity\Controller\DatabaseEntity;
|
use Core\Objects\DatabaseEntity\Controller\DatabaseEntity;
|
||||||
use PHPUnit\Util\Exception;
|
use PHPUnit\Util\Exception;
|
||||||
|
|
||||||
class CreateDatabase extends DatabaseScript {
|
class CreateDatabase {
|
||||||
|
|
||||||
public static function createQueries(SQL $sql): array {
|
public static function createQueries(SQL $sql): array {
|
||||||
$queries = array();
|
$queries = array();
|
||||||
|
|
||||||
self::loadEntities($queries, $sql);
|
self::loadEntities($sql, $queries);
|
||||||
|
|
||||||
$queries[] = $sql->createTable("Settings")
|
$queries[] = $sql->createTable("Settings")
|
||||||
->addString("name", 32)
|
->addString("name", 32)
|
||||||
@ -33,34 +33,25 @@ class CreateDatabase extends DatabaseScript {
|
|||||||
->primaryKey("method")
|
->primaryKey("method")
|
||||||
->addBool("is_core", false);
|
->addBool("is_core", false);
|
||||||
|
|
||||||
self::loadDefaultACL($queries, $sql);
|
self::loadDefaultACL($sql, $queries);
|
||||||
self::loadPatches($queries, $sql);
|
self::loadPatches($sql, $queries);
|
||||||
|
|
||||||
return $queries;
|
return $queries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function loadPatches(&$queries, $sql) {
|
private static function loadPatches(SQL $sql, array &$queries): void {
|
||||||
$baseDirs = ["Core", "Site"];
|
$patchFiles = array_merge(
|
||||||
foreach ($baseDirs as $baseDir) {
|
glob('Core/Configuration/Patch/*.php'),
|
||||||
$patchDirectory = "./$baseDir/Configuration/Patch/";
|
glob('Site/Configuration/Patch/*.php')
|
||||||
if (file_exists($patchDirectory) && is_dir($patchDirectory)) {
|
);
|
||||||
$scan_arr = scandir($patchDirectory);
|
|
||||||
$files_arr = array_diff($scan_arr, array('.', '..'));
|
sort($patchFiles);
|
||||||
foreach ($files_arr as $file) {
|
foreach ($patchFiles as $file) {
|
||||||
$suffix = ".class.php";
|
@include_once $file;
|
||||||
if (endsWith($file, $suffix)) {
|
|
||||||
$className = substr($file, 0, strlen($file) - strlen($suffix));
|
|
||||||
$className = "\\$baseDir\\Configuration\\Patch\\$className";
|
|
||||||
$method = "$className::createQueries";
|
|
||||||
$patchQueries = call_user_func($method, $sql);
|
|
||||||
foreach ($patchQueries as $query) $queries[] = $query;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function loadEntities(&$queries, $sql) {
|
private static function loadEntities(SQL $sql, array &$queries): void {
|
||||||
$persistables = [];
|
$persistables = [];
|
||||||
$baseDirs = ["Core", "Site"];
|
$baseDirs = ["Core", "Site"];
|
||||||
foreach ($baseDirs as $baseDir) {
|
foreach ($baseDirs as $baseDir) {
|
||||||
@ -113,7 +104,7 @@ class CreateDatabase extends DatabaseScript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function loadDefaultACL(array &$queries, SQL $sql): void {
|
public static function loadDefaultACL(SQL $sql, array &$queries): void {
|
||||||
$query = $sql->insert("ApiPermission", ["method", "groups", "description", "is_core"]);
|
$query = $sql->insert("ApiPermission", ["method", "groups", "description", "is_core"]);
|
||||||
|
|
||||||
foreach (Request::getApiEndpoints() as $reflectionClass) {
|
foreach (Request::getApiEndpoints() as $reflectionClass) {
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Core\Configuration;
|
|
||||||
|
|
||||||
use Core\Driver\SQL\SQL;
|
|
||||||
|
|
||||||
abstract class DatabaseScript {
|
|
||||||
public static abstract function createQueries(SQL $sql);
|
|
||||||
}
|
|
47
Core/Configuration/Patch/2021_04_08-EntityLog.php
Normal file
47
Core/Configuration/Patch/2021_04_08-EntityLog.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Core\Driver\SQL\Column\IntColumn;
|
||||||
|
use Core\Driver\SQL\Type\CurrentColumn;
|
||||||
|
use Core\Driver\SQL\Type\CurrentTable;
|
||||||
|
use Core\Driver\SQL\Type\Trigger;
|
||||||
|
|
||||||
|
$queries[] = $sql->createTable("EntityLog")
|
||||||
|
->addInt("entityId")
|
||||||
|
->addString("tableName")
|
||||||
|
->addDateTime("modified", false, $sql->now())
|
||||||
|
->addInt("lifetime", false, 90);
|
||||||
|
|
||||||
|
$insertProcedure = $sql->createProcedure("InsertEntityLog")
|
||||||
|
->param(new CurrentTable())
|
||||||
|
->param(new IntColumn("id"))
|
||||||
|
->param(new IntColumn("lifetime", false, 90))
|
||||||
|
->returns(new Trigger())
|
||||||
|
->exec(array(
|
||||||
|
$sql->insert("EntityLog", ["entityId", "tableName", "lifetime"])
|
||||||
|
->addRow(new CurrentColumn("id"), new CurrentTable(), new CurrentColumn("lifetime"))
|
||||||
|
));
|
||||||
|
|
||||||
|
$updateProcedure = $sql->createProcedure("UpdateEntityLog")
|
||||||
|
->param(new CurrentTable())
|
||||||
|
->param(new IntColumn("id"))
|
||||||
|
->returns(new Trigger())
|
||||||
|
->exec(array(
|
||||||
|
$sql->update("EntityLog")
|
||||||
|
->set("modified", $sql->now())
|
||||||
|
->whereEq("entityId", new CurrentColumn("id"))
|
||||||
|
->whereEq("tableName", new CurrentTable())
|
||||||
|
));
|
||||||
|
|
||||||
|
$deleteProcedure = $sql->createProcedure("DeleteEntityLog")
|
||||||
|
->param(new CurrentTable())
|
||||||
|
->param(new IntColumn("id"))
|
||||||
|
->returns(new Trigger())
|
||||||
|
->exec(array(
|
||||||
|
$sql->delete("EntityLog")
|
||||||
|
->whereEq("entityId", new CurrentColumn("id"))
|
||||||
|
->whereEq("tableName", new CurrentTable())
|
||||||
|
));
|
||||||
|
|
||||||
|
$queries[] = $insertProcedure;
|
||||||
|
$queries[] = $updateProcedure;
|
||||||
|
$queries[] = $deleteProcedure;
|
@ -1,63 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Core\Configuration\Patch;
|
|
||||||
|
|
||||||
use Core\Configuration\DatabaseScript;
|
|
||||||
use Core\Driver\SQL\Column\IntColumn;
|
|
||||||
use Core\Driver\SQL\Condition\Compare;
|
|
||||||
use Core\Driver\SQL\SQL;
|
|
||||||
use Core\Driver\SQL\Type\CurrentColumn;
|
|
||||||
use Core\Driver\SQL\Type\CurrentTable;
|
|
||||||
use Core\Driver\SQL\Type\Trigger;
|
|
||||||
|
|
||||||
class EntityLog_2021_04_08 extends DatabaseScript {
|
|
||||||
|
|
||||||
public static function createQueries(SQL $sql): array {
|
|
||||||
|
|
||||||
$queries = array();
|
|
||||||
|
|
||||||
$queries[] = $sql->createTable("EntityLog")
|
|
||||||
->addInt("entityId")
|
|
||||||
->addString("tableName")
|
|
||||||
->addDateTime("modified", false, $sql->now())
|
|
||||||
->addInt("lifetime", false, 90);
|
|
||||||
|
|
||||||
$insertProcedure = $sql->createProcedure("InsertEntityLog")
|
|
||||||
->param(new CurrentTable())
|
|
||||||
->param(new IntColumn("id"))
|
|
||||||
->param(new IntColumn("lifetime", false, 90))
|
|
||||||
->returns(new Trigger())
|
|
||||||
->exec(array(
|
|
||||||
$sql->insert("EntityLog", ["entityId", "tableName", "lifetime"])
|
|
||||||
->addRow(new CurrentColumn("id"), new CurrentTable(), new CurrentColumn("lifetime"))
|
|
||||||
));
|
|
||||||
|
|
||||||
$updateProcedure = $sql->createProcedure("UpdateEntityLog")
|
|
||||||
->param(new CurrentTable())
|
|
||||||
->param(new IntColumn("id"))
|
|
||||||
->returns(new Trigger())
|
|
||||||
->exec(array(
|
|
||||||
$sql->update("EntityLog")
|
|
||||||
->set("modified", $sql->now())
|
|
||||||
->whereEq("entityId", new CurrentColumn("id"))
|
|
||||||
->whereEq("tableName", new CurrentTable())
|
|
||||||
));
|
|
||||||
|
|
||||||
$deleteProcedure = $sql->createProcedure("DeleteEntityLog")
|
|
||||||
->param(new CurrentTable())
|
|
||||||
->param(new IntColumn("id"))
|
|
||||||
->returns(new Trigger())
|
|
||||||
->exec(array(
|
|
||||||
$sql->delete("EntityLog")
|
|
||||||
->whereEq("entityId", new CurrentColumn("id"))
|
|
||||||
->whereEq("tableName", new CurrentTable())
|
|
||||||
));
|
|
||||||
|
|
||||||
$queries[] = $insertProcedure;
|
|
||||||
$queries[] = $updateProcedure;
|
|
||||||
$queries[] = $deleteProcedure;
|
|
||||||
|
|
||||||
return $queries;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -161,6 +161,7 @@ namespace Documents\Install {
|
|||||||
return self::CHECKING_REQUIREMENTS;
|
return self::CHECKING_REQUIREMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: also check the presence of react dist?
|
||||||
$externalDir = $this->getExternalDirectory();
|
$externalDir = $this->getExternalDirectory();
|
||||||
$autoload = implode(DIRECTORY_SEPARATOR, [$externalDir, "vendor", "autoload.php"]);
|
$autoload = implode(DIRECTORY_SEPARATOR, [$externalDir, "vendor", "autoload.php"]);
|
||||||
if (!is_file($autoload)) {
|
if (!is_file($autoload)) {
|
||||||
@ -238,6 +239,7 @@ namespace Documents\Install {
|
|||||||
"/Site/Configuration",
|
"/Site/Configuration",
|
||||||
"/Core/External/vendor",
|
"/Core/External/vendor",
|
||||||
"/files/uploaded",
|
"/files/uploaded",
|
||||||
|
"/react",
|
||||||
];
|
];
|
||||||
|
|
||||||
$nonWritableDirectories = [];
|
$nonWritableDirectories = [];
|
||||||
@ -801,7 +803,7 @@ namespace Documents\Install {
|
|||||||
$progressText = htmlspecialchars($currentView["progressText"]);
|
$progressText = htmlspecialchars($currentView["progressText"]);
|
||||||
$class = ["my-3"];
|
$class = ["my-3"];
|
||||||
if (!in_array($this->currentStep, [self::CHECKING_REQUIREMENTS, self::INSTALL_DEPENDENCIES])) {
|
if (!in_array($this->currentStep, [self::CHECKING_REQUIREMENTS, self::INSTALL_DEPENDENCIES])) {
|
||||||
$class[] = "hidden";
|
$class[] = "d-none";
|
||||||
}
|
}
|
||||||
|
|
||||||
$html .= html_tag("div", ["class" => $class, "id" => "progressText"], [$progressText, $spinnerIcon], false);
|
$html .= html_tag("div", ["class" => $class, "id" => "progressText"], [$progressText, $spinnerIcon], false);
|
||||||
@ -851,7 +853,7 @@ namespace Documents\Install {
|
|||||||
|
|
||||||
$attrs = ["id" => $id, "class" => ["m-1", "btn", "btn-$type"]];
|
$attrs = ["id" => $id, "class" => ["m-1", "btn", "btn-$type"]];
|
||||||
if (isset($button["hidden"]) && $button["hidden"]) {
|
if (isset($button["hidden"]) && $button["hidden"]) {
|
||||||
$attrs["class"][] = "hidden";
|
$attrs["class"][] = "d-none";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($button["disabled"]) && $button["disabled"]) {
|
if (isset($button["disabled"]) && $button["disabled"]) {
|
||||||
|
39
cli.php
39
cli.php
@ -8,7 +8,6 @@ require_once 'Core/datetime.php';
|
|||||||
include_once 'Core/constants.php';
|
include_once 'Core/constants.php';
|
||||||
|
|
||||||
use Core\API\Request;
|
use Core\API\Request;
|
||||||
use Core\Configuration\DatabaseScript;
|
|
||||||
use Core\Driver\SQL\Column\Column;
|
use Core\Driver\SQL\Column\Column;
|
||||||
use Core\Driver\SQL\Condition\Compare;
|
use Core\Driver\SQL\Condition\Compare;
|
||||||
use Core\Driver\SQL\Condition\CondIn;
|
use Core\Driver\SQL\Condition\CondIn;
|
||||||
@ -79,23 +78,9 @@ function printHelp(array $argv): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyPatch(\Core\Driver\SQL\SQL $sql, string $patchName): bool {
|
function applyPatch(SQL $sql, string $patchFile): bool {
|
||||||
$class = str_replace('/', '\\', $patchName);
|
$queries = [];
|
||||||
$className = "\\Core\\Configuration\\$class";
|
@include_once $patchFile;
|
||||||
$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) {
|
foreach ($queries as $query) {
|
||||||
if (!$query->execute($sql)) {
|
if (!$query->execute($sql)) {
|
||||||
printLine($sql->getLastError());
|
printLine($sql->getLastError());
|
||||||
@ -288,7 +273,10 @@ function onMaintenance(array $argv): void {
|
|||||||
_exit("Maintenance disabled");
|
_exit("Maintenance disabled");
|
||||||
} else if ($action === "update") {
|
} else if ($action === "update") {
|
||||||
$logger->info("Update started");
|
$logger->info("Update started");
|
||||||
$oldPatchFiles = glob('Core/Configuration/Patch/*.php');
|
$oldPatchFiles = array_merge(
|
||||||
|
glob('Core/Configuration/Patch/*.php'),
|
||||||
|
glob('Site/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) {
|
||||||
@ -351,16 +339,19 @@ function onMaintenance(array $argv): void {
|
|||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: also collect patches from Site/Configuration/Patch ... and what about database entities?
|
// TODO: how to handle modified database entities?
|
||||||
$newPatchFiles = glob('Core/Configuration/Patch/*.php');
|
$newPatchFiles = array_merge(
|
||||||
|
glob('Core/Configuration/Patch/*.php'),
|
||||||
|
glob('Site/Configuration/Patch/*.php')
|
||||||
|
);
|
||||||
$newPatchFiles = array_diff($newPatchFiles, $oldPatchFiles);
|
$newPatchFiles = array_diff($newPatchFiles, $oldPatchFiles);
|
||||||
if (count($newPatchFiles) > 0) {
|
if (count($newPatchFiles) > 0) {
|
||||||
if ($sql) {
|
if ($sql) {
|
||||||
printLine("Applying new database patches");
|
printLine("Applying new database patches");
|
||||||
|
sort($newPatchFiles);
|
||||||
foreach ($newPatchFiles as $patchFile) {
|
foreach ($newPatchFiles as $patchFile) {
|
||||||
if (preg_match("/Core\/Configuration\/(Patch\/.*)\.class\.php/", $patchFile, $match)) {
|
if (preg_match("/(Core|Site)\/Configuration\/Patch\/(.*)\.php/", $patchFile, $match)) {
|
||||||
$patchName = $match[1];
|
applyPatch($sql, $patchFile);
|
||||||
applyPatch($sql, $patchName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
version: "3.9"
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
container_name: webbase-web
|
container_name: webbase-web
|
||||||
|
@ -27,7 +27,7 @@ function setState(state) {
|
|||||||
icon = 'fas fa-times-circle';
|
icon = 'fas fa-times-circle';
|
||||||
text = "Failed";
|
text = "Failed";
|
||||||
color = "danger";
|
color = "danger";
|
||||||
$("#btnRetry").show();
|
$("#btnRetry").removeClass("d-none");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -74,7 +74,7 @@ function sendRequest(params, done) {
|
|||||||
setState(ERROR);
|
setState(ERROR);
|
||||||
statusBox.addClass("alert-danger");
|
statusBox.addClass("alert-danger");
|
||||||
statusBox.html("An error occurred during installation. Try <a href=\"/index.php\">restarting the process</a>.");
|
statusBox.html("An error occurred during installation. Try <a href=\"/index.php\">restarting the process</a>.");
|
||||||
statusBox.show();
|
statusBox.removeClass("d-none");
|
||||||
}).always(function() {
|
}).always(function() {
|
||||||
if(done) done(success);
|
if(done) done(success);
|
||||||
});
|
});
|
||||||
@ -82,15 +82,15 @@ function sendRequest(params, done) {
|
|||||||
|
|
||||||
function retry() {
|
function retry() {
|
||||||
let progressText = $("#progressText");
|
let progressText = $("#progressText");
|
||||||
let wasHidden = progressText.hasClass("hidden");
|
let wasHidden = progressText.hasClass("d-none");
|
||||||
$("#btnRetry").hide();
|
$("#btnRetry").addClass("d-none");
|
||||||
progressText.removeClass("hidden");
|
progressText.removeClass("d-none");
|
||||||
sendRequest({ }, function(success) {
|
sendRequest({ }, function(success) {
|
||||||
if (wasHidden) {
|
if (wasHidden) {
|
||||||
$("#progressText").addClass("hidden");
|
$("#progressText").addClass("d-none");
|
||||||
}
|
}
|
||||||
if(!success) {
|
if(!success) {
|
||||||
$("#btnRetry").show();
|
$("#btnRetry").removeClass("d-none");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user