diff --git a/src/Controller/Installer.php b/src/Controller/Installer.php deleted file mode 100644 index e00b705..0000000 --- a/src/Controller/Installer.php +++ /dev/null @@ -1,121 +0,0 @@ -_registry = $_registry; - } - - public function setUp($db_manager, $installPath) - { - $this->db_manager = $db_manager; - $this->installPath = $installPath; - } - - function getSetupFile($name) - { - $setup = Path::join(call_user_func($this->installPath, $name), "install.json"); - return $setup; - } - - function getUninstallFile($name) { - return Path::join(call_user_func($this->installPath, $name), "sql", "uninstall.json"); - } - - // Проверка версии обновления - function isChanged($name) // Информация о модулях - { - $item = $this->_registry->get($name); - if ($item) { - $setup = $this->getSetupFile($name); - if (file_exists($setup) && (filemtime($setup) > $item['time'])) { - return true; - } - return false; - } - return true; - } - - function installSQL(array $sql, $version_new, $version_old, $name) - { - $result = []; - $json_installer = new JsonInstall($this->db_manager); - foreach ($sql as $version => $install) { - if (version_compare($version, $version_new, "<=") && version_compare($version, $version_old, ">")) { - $file = Path::join(call_user_func($this->installPath, $name), "sql", $install); - $json_installer->install($file, null); - $result[] = $version; - } - } - return $result; - } - - function uninstall($name){ - $uninstall = $this->getUninstallFile($name); - if (file_exists($uninstall)) { - $json_installer = new JsonInstall($this->db_manager); - $json_installer->install($uninstall,null); - } - $this->_registry->removeKey($name); - $this->_registry->write(); - } - - // Устанавливает обновления если есть - function doUpdates($name, $force = false) // Установка модуля - { - $result = []; - $setup = $this->getSetupFile($name); - - if (file_exists($setup) && ($this->isChanged($name) || $force)) { - $registry = $this->_registry; - - $settings = new Settings($setup); - $settings->read(); - - $item = $registry->get($name); - - $version_new = $settings->get('version'); - if ($item) { - $version_old = $item['version']; - } else { - $version_old = "0.0"; - $registry->writeKey([$name], []); - } - if (version_compare($version_old, $settings->get('version'), "!=")) { - $sql = $settings->get('sql'); - if (is_array($sql)) { - $res = $this->installSQL($sql, $version_new, $version_old, $name); - if ($res) { - $result[]=$res; - } - } - } - - // Обновление версии меню - $registry->removeKey($name); - $registry->set($name, [ - 'version' => $version_new, - 'time' => filemtime($setup) - ]); - // $registry->writeKey([$name], $settings->export()); - - $registry->write(); - } - return $result; - } - - function install($dbinit_path, $dbfill_path = null) { - $json_installer = new JsonInstall($this->db_manager); - $json_installer->install($dbinit_path, $dbfill_path); - } -} diff --git a/src/Database/JsonInstall.php b/src/Database/JsonInstall.php index 3e6eef1..253cd39 100644 --- a/src/Database/JsonInstall.php +++ b/src/Database/JsonInstall.php @@ -3,16 +3,21 @@ namespace ctiso\Database; use ctiso\Database\Manager; +use App\DbMigrate\DataBaseInfo; +use App\DbMigrate\DiffPatch; +/** + * Уcтсановить базу данных из json файла. + */ class JsonInstall { - public $db_manager; + public Manager $db_manager; public $serialColumns; public function __construct(Manager $db_manager) { $this->db_manager = $db_manager; } - function install($dbinit_path, $dbfill_path = null) { + public function install(string $dbinit_path, ?string $dbfill_path = null) { $dbinit_file = file_get_contents($dbinit_path); if (is_string($dbinit_file)) { $initActions = json_decode($dbinit_file, true); @@ -32,7 +37,7 @@ class JsonInstall { $this->makeConstraints($initActions); } - function missingTables($tables) { + protected function missingTables(array $tables) { $actual_tables = $this->db_manager->getAllTableNames(); $missingTables = []; foreach ($tables as $table) { @@ -42,16 +47,19 @@ class JsonInstall { return $missingTables; } - //Создать таблицы - function initDataBase($initActions/*: array*/, $dbinit_path) { + /** + * Создать таблицы + */ + function initDataBase(array $initActions, string $dbinit_path): void { $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"]])) + if (!isset($refs[$action["table"]])) { $refs[$action["table"]] = []; + } $refs[$action["table"]][]=$action;//добавить к списку референсов для таблицы } } @@ -73,7 +81,7 @@ class JsonInstall { } } if ($action["type"] != "alterReference") { - $this->db_manager->ExecuteAction($action, $dbinit_path); + $this->db_manager->executeAction($action, $dbinit_path); } } @@ -95,14 +103,15 @@ class JsonInstall { } } - //Заполнить данными - function fillDataBase($dbfill_file_path) { + /** + * Заполнить данными + */ + function fillDataBase(string $dbfill_file_path): void { $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"]) { @@ -128,15 +137,16 @@ class JsonInstall { } } - //Обновить ключи serial и создать ограничения - function makeConstraints($initActions) { + /** + * Обновить ключи serial и создать ограничения + */ + protected function makeConstraints(array $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); @@ -145,4 +155,18 @@ class JsonInstall { } } + /** + * Обновить базу данных + */ + function update(array $patches): void { + $db = $this->db_manager->db; + $dbi = new DataBaseInfo(); + $diff = new DiffPatch($db); + $diff->readPatches($dbi, $patches); + + // Применяем изменения + $db->beginTransaction(); + $diff->patchDatabase($diff->getCurrentSchema(), $dbi); + $db->commit(); + } } \ No newline at end of file diff --git a/src/Database/Manager.php b/src/Database/Manager.php index 1629a92..7783739 100644 --- a/src/Database/Manager.php +++ b/src/Database/Manager.php @@ -9,15 +9,13 @@ use Exception; class Manager { - public $db/*: Database*/; + public Database $db; - public function __construct(Database $db) - { + public function __construct(Database $db) { $this->db = $db; } - public function executeAction($action/*: array*/, $db_file = "") - { + public function executeAction(array $action, string $db_file = ""): void { switch($action["type"]) { case "dropTable": $this->dropTableQuery($action["table_name"], true); @@ -59,9 +57,10 @@ class Manager } } - //Дропает и создаёт SQL VIEW - public function recreateView($viewName, $selectStatement) - { + /** + * Дропает и создаёт SQL VIEW + */ + public function recreateView($viewName, $selectStatement) { $this->db->query("DROP VIEW ".$viewName); $this->db->query("CREATE VIEW ".$viewName." AS ".$selectStatement); } @@ -95,7 +94,7 @@ class Manager foreach ($results as $result) { $fields[$result["name"]] = [ "type"=> $result["type"], - "not_null"=> boolval($result["notnull"]), + "nullable"=> !boolval($result["notnull"]), "constraint"=> ((bool) $result["pk"]) ? "PRIMARY KEY" : null ]; } @@ -103,7 +102,7 @@ class Manager } } - public function renameColumn($table, $old_name, $new_name) + public function renameColumn(string $table, string $old_name, string $new_name): void { $pg = $this->db->isPostgres(); if ($pg) { @@ -117,7 +116,7 @@ class Manager return; } - $data/*: array*/ = $this->dumpTable($table); + $data = $this->dumpTable($table); $this->db->query("ALTER TABLE ".$table." RENAME TO ".$tmp_table.";"); $table_info[$new_name] = $table_info[$old_name]; @@ -134,20 +133,22 @@ class Manager } } - //Обновление ключа serial после ручной вставки - public function updateSerial($table, $column) + /** + * Обновление ключа serial после ручной вставки + */ + public function updateSerial($table, $column): void { $this->db->query("SELECT setval(pg_get_serial_sequence('".$table."', '".$column."'), coalesce(max(".$column."),0) + 1, false) FROM ".$table); } - public function columnDefinition($name, $data, $pg) + public function columnDefinition(string $name, $data, $pg): string { $constraint = isset($data['constraint']) ? " ".$data['constraint'] : ""; $references = ""; if (isset($data['references'])) { - $references = " REFERENCES " . $data['references']['refTable'] . '(' .$data['references']['refColumn'] . ')'; + $references = " REFERENCES " . $data['references']['table'] . '(' .$data['references']['column'] . ')'; } - if (isset($data["not_null"]) && $data["not_null"]) { + if (isset($data["nullable"]) && $data["nullable"] === false) { $constraint .=" NOT NULL"; } $type = $data['type']; @@ -155,21 +156,20 @@ class Manager if (strtolower($type)=="serial") { $type = "integer"; } - //if (strtolower($type)=="boolean") - // $type = "integer"; } return $name." ".$type.$references.$constraint; } - public function addColumn($table_name, $column_name, $field) + public function addColumn(string $table_name, string $column_name, $field): void { $pg = $this->db->isPostgres(); $q = "ALTER TABLE ".$table_name." ADD COLUMN ". - $this->columnDefinition($column_name, $field, $pg); + $this->columnDefinition($column_name, $field, $pg); + $this->db->query($q); } - public function getConstraintDef($c/*: array*/) + public function getConstraintDef(array $c) { if ($c['type'] == 'unique') { return "UNIQUE(" . implode(", ", $c['fields']) . ")"; @@ -178,7 +178,7 @@ class Manager } //CreateTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']]) - public function createTableQuery($table, $fields, $constraints) + public function createTableQuery(string $table, array $fields, $constraints): void { $pg = $this->db->isPostgres(); if ($constraints) { @@ -197,7 +197,7 @@ class Manager $this->db->query($statement); } - public function dumpTable($table_name) + public function dumpTable(string $table_name): array { $pg = $this->db->isPostgres(); @@ -209,7 +209,7 @@ class Manager foreach ($table_fields as $name => $value) { $type = strtolower($value['type']); if ($type == "boolean") { - foreach ($data as &$row) { + foreach ($data as &$row) { if (isset($row[$name])) { $row[$name] = boolval($row[$name]); } @@ -227,7 +227,7 @@ class Manager return $result; } - public function getAllTableNames() + public function getAllTableNames(): array { $result = []; if ($this->db->isPostgres()) { @@ -242,7 +242,7 @@ class Manager return $result; } - public function dumpInserts() + public function dumpInserts(): array { $table_names = $this->getAllTableNames(); $result = [];