143 lines
No EOL
3.9 KiB
PHP
143 lines
No EOL
3.9 KiB
PHP
<?php
|
||
//Действия с базой данных согласно json файлу.
|
||
|
||
class Database_JsonInstall {
|
||
public $db_manager;
|
||
public $serialColumns;
|
||
|
||
public function __construct(Database_Manager $db_manager) {
|
||
$this->db_manager = $db_manager;
|
||
}
|
||
|
||
function install($dbinit_path, $dbfill_path = null) {
|
||
$dbinit_file = file_get_contents($dbinit_path);
|
||
if (is_string($dbinit_file)) {
|
||
$initActions = json_decode($dbinit_file, true);
|
||
if (!$initActions) {
|
||
echo "Invalid dbinit.json ".$dbinit_file;
|
||
return 0;
|
||
}
|
||
} else {
|
||
echo "No dbinit.json";
|
||
return 0;
|
||
}
|
||
|
||
$this->initDataBase($initActions, $dbinit_path);
|
||
if ($dbfill_path) {
|
||
$this->fillDataBase($dbfill_path);
|
||
}
|
||
$this->makeConstraints($initActions);
|
||
}
|
||
|
||
function missingTables($tables) {
|
||
$actual_tables = $this->db_manager->GetAllTableNames();
|
||
$missingTables = [];
|
||
foreach ($tables as $table) {
|
||
if (!in_array($table, $actual_tables))
|
||
$missingTables[] = $table;
|
||
}
|
||
return $missingTables;
|
||
}
|
||
|
||
//Создать таблицы
|
||
function initDataBase(/*.array.*/$initActions, $dbinit_path) {
|
||
$pg = $this->db_manager->db->isPostgres();
|
||
if (!$pg) {
|
||
$refs = [];
|
||
//В sqlite нет alter reference. Референсы надо создавать при создании таблицы.
|
||
foreach ($initActions as $action) {
|
||
if ($action["type"] == "alterReference") {
|
||
if (!isset($refs[$action["table"]]))
|
||
$refs[$action["table"]] = [];
|
||
$refs[$action["table"]][]=$action;//добавить к списку референсов для таблицы
|
||
}
|
||
}
|
||
}
|
||
|
||
foreach ($initActions as $action) {
|
||
if (!$pg) {
|
||
if ($action["type"] == "createTable") {
|
||
$table_name = $action["table_name"];
|
||
if (isset($refs[$table_name])) {
|
||
foreach ($refs[$table_name] as $value) {
|
||
$action['fields'][$value['column']]['references'] =
|
||
$value['refTable']."(".$value['refColumn'].")";
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
if ($action["type"] != "alterReference") {
|
||
$this->db_manager->ExecuteAction($action, $dbinit_path);
|
||
}
|
||
}
|
||
|
||
//Запомнить все колонки serial
|
||
$this->serialColumns = [];
|
||
if ($pg) {
|
||
foreach ($initActions as $action) {
|
||
if ($action["type"] == "createTable") {
|
||
foreach ($action["fields"] as $name => $field) {
|
||
if ($field["type"]=="serial") {
|
||
$this->serialColumns[] = [
|
||
"table"=>$action["table_name"],
|
||
"column"=>$name
|
||
];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//Заполнить данными
|
||
function fillDataBase($dbfill_file_path) {
|
||
$dbfill_file = file_get_contents($dbfill_file_path);
|
||
if (is_string($dbfill_file)) {
|
||
$actions = json_decode($dbfill_file,true);
|
||
if ($actions) {
|
||
|
||
//Проверка что упоминаемые в списке действий таблицы уже есть в базе
|
||
$affected_tables = [];
|
||
foreach ($actions as $action) {
|
||
if ($action["table_name"]) {
|
||
$affected_tables[$action["table_name"]] = 1;
|
||
}
|
||
}
|
||
|
||
$missing = $this->missingTables(array_keys($affected_tables));
|
||
if (!empty($missing)) {
|
||
echo "dbfill error. Missing tables: ".implode(" ", $missing);
|
||
return;
|
||
}
|
||
|
||
//Выполнение действий
|
||
foreach ($actions as $action) {
|
||
$this->db_manager->ExecuteAction($action, $dbfill_file_path);
|
||
}
|
||
} else {
|
||
echo "Invalid dbfill.json";
|
||
}
|
||
} else {
|
||
echo "No dbfill.json";
|
||
}
|
||
}
|
||
|
||
//Обновить ключи serial и создать ограничения
|
||
function makeConstraints($initActions) {
|
||
$pg = $this->db_manager->db->isPostgres();
|
||
if ($pg) {
|
||
foreach ($this->serialColumns as $serialColumn) {
|
||
$this->db_manager->UpdateSerial($serialColumn["table"], $serialColumn["column"]);
|
||
}
|
||
|
||
|
||
foreach ($initActions as $action) {
|
||
if ($action["type"] == "alterReference") {
|
||
$this->db_manager->ExecuteAction($action);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
} |