From 93c0a67241c0e4646e58c76fe7d6ad6e9664d2a8 Mon Sep 17 00:00:00 2001 From: anatoly Date: Fri, 31 Mar 2023 18:09:34 +0300 Subject: [PATCH] creating views --- src/Database/Manager.php | 409 ++++++++++++++++++++------------------- 1 file changed, 209 insertions(+), 200 deletions(-) diff --git a/src/Database/Manager.php b/src/Database/Manager.php index 354a722..c54bd73 100644 --- a/src/Database/Manager.php +++ b/src/Database/Manager.php @@ -1,227 +1,236 @@ -db = $db; - } + function __construct(Database $db) { + $this->db = $db; + } - public function ExecuteAction($action/*: array*/, $db_file = "") { - switch($action["type"]) { - case "dropTable": - $this->DropTableQuery($action["table_name"], true); - break; - case "createTable": - $constraints = isset($action["constraints"]) ? $action["constraints"] : NULL; - $this->CreateTableQuery($action["table_name"], $action["fields"], $constraints); - break; - case "addColumn": - $this->AddColumn($action["table_name"], $action["column_name"], $action["field"]); - break; - case "insert": - $this->db->insertQuery($action["table_name"], $action["values"]); - break; - case "alterReference": - $this->AlterReference($action["table"], $action["column"], $action["refTable"], $action["refColumn"]); - break; - case "renameColumn": - $this->RenameColumn($action["table"], $action["old_name"], $action["new_name"]); - break; - case "executeFile": - if ($this->db->isPostgres() && isset($action["pgsql"])) { - $file = $action["pgsql"]; - } else { - $file = $action["source"]; - } + public function ExecuteAction($action/*: array*/, $db_file = "") { + switch($action["type"]) { + case "dropTable": + $this->DropTableQuery($action["table_name"], true); + break; + case "createTable": + $constraints = isset($action["constraints"]) ? $action["constraints"] : NULL; + $this->CreateTableQuery($action["table_name"], $action["fields"], $constraints); + break; + case "addColumn": + $this->AddColumn($action["table_name"], $action["column_name"], $action["field"]); + break; + case "insert": + $this->db->insertQuery($action["table_name"], $action["values"]); + break; + case "alterReference": + $this->AlterReference($action["table"], $action["column"], $action["refTable"], $action["refColumn"]); + break; + case "renameColumn": + $this->RenameColumn($action["table"], $action["old_name"], $action["new_name"]); + break; + case "createView": + $this->recreateView($action["view"], $action["select"]); + break; + case "executeFile": + if ($this->db->isPostgres() && isset($action["pgsql"])) { + $file = $action["pgsql"]; + } else { + $file = $action["source"]; + } - $stmtList = SQLStatementExtractor::extractFile(Path::join(dirname($db_file), $file)); - foreach($stmtList as $stmt) { - $this->db->executeQuery($stmt); - } + $stmtList = SQLStatementExtractor::extractFile(Path::join(dirname($db_file), $file)); + foreach($stmtList as $stmt) { + $this->db->executeQuery($stmt); + } - break; - default: - throw new Exception("unknown action ". $action["type"] . PHP_EOL); - } - } + break; + default: + throw new Exception("unknown action ". $action["type"] . PHP_EOL); + } + } - public function DropTableQuery($table, $cascade=false) { - $statement = "DROP TABLE IF EXISTS ".$table; - if ($this->db->isPostgres()&&$cascade) { - $statement = $statement." CASCADE"; - } - $this->db->query($statement); - } + //Дропает и создаёт SQL VIEW + public function recreateView($viewName, $selectStatement) { + $this->db->query("DROP VIEW ".$viewName); + $this->db->query("CREATE VIEW ".$viewName." AS ".$selectStatement); + } - public function AlterReference($table,$column,$refTable,$refColumn) { - $this->db->query("ALTER TABLE ".$table." ADD CONSTRAINT ".$table."_".$column."fk"." FOREIGN KEY (".$column.") REFERENCES ".$refTable." (".$refColumn.")"); - } + public function DropTableQuery($table, $cascade=false) { + $statement = "DROP TABLE IF EXISTS ".$table; + if ($this->db->isPostgres()&&$cascade) { + $statement = $statement." CASCADE"; + } + $this->db->query($statement); + } - //Извлечение информации о полях таблицы - public function TableInfo($table) { - $pg = $this->db->isPostgres(); - if ($pg) { - throw new Exception("Not implemented for postgres"); - } else { - $results = $this->db->fetchAllArray("PRAGMA table_info(".$table.");"); - if (empty($results)) { - return null; - } - $fields = []; - foreach ($results as $result) { - $fields[$result["name"]] = [ - "type"=> $result["type"], - "not_null"=> boolval($result["notnull"]), - "constraint"=> ((boolean) $result["pk"]) ? "PRIMARY KEY" : null - ]; - } - return $fields; - } - } + public function AlterReference($table,$column,$refTable,$refColumn) { + $this->db->query("ALTER TABLE ".$table." ADD CONSTRAINT ".$table."_".$column."fk"." FOREIGN KEY (".$column.") REFERENCES ".$refTable." (".$refColumn.")"); + } - public function RenameColumn($table, $old_name, $new_name) { - $pg = $this->db->isPostgres(); - if ($pg) { - $this->db->query("ALTER TABLE ".$table." RENAME COLUMN ".$old_name." TO ".$new_name); - } else { - $tmp_table = "tmp_" . $table; - $this->DropTableQuery($tmp_table); - $table_info = $this->TableInfo($table); + //Извлечение информации о полях таблицы + public function TableInfo($table) { + $pg = $this->db->isPostgres(); + if ($pg) { + throw new Exception("Not implemented for postgres"); + } else { + $results = $this->db->fetchAllArray("PRAGMA table_info(".$table.");"); + if (empty($results)) { + return null; + } + $fields = []; + foreach ($results as $result) { + $fields[$result["name"]] = [ + "type"=> $result["type"], + "not_null"=> boolval($result["notnull"]), + "constraint"=> ((boolean) $result["pk"]) ? "PRIMARY KEY" : null + ]; + } + return $fields; + } + } - if (isset($table_info[$new_name])) { - return; - } + public function RenameColumn($table, $old_name, $new_name) { + $pg = $this->db->isPostgres(); + if ($pg) { + $this->db->query("ALTER TABLE ".$table." RENAME COLUMN ".$old_name." TO ".$new_name); + } else { + $tmp_table = "tmp_" . $table; + $this->DropTableQuery($tmp_table); + $table_info = $this->TableInfo($table); - $data/*: array*/ = $this->DumpTable($table); + if (isset($table_info[$new_name])) { + return; + } - $this->db->query("ALTER TABLE ".$table." RENAME TO ".$tmp_table.";"); - $table_info[$new_name] = $table_info[$old_name]; - unset($table_info[$old_name]); - $this->CreateTableQuery($table,$table_info,null); + $data/*: array*/ = $this->DumpTable($table); - foreach ($data as $row) { - $values = $row['values']; - $values[$new_name] = $values[$old_name]; - unset($values[$old_name]); - $this->db->insertQuery($table, $values); - } - $this->DropTableQuery($tmp_table); - } - } + $this->db->query("ALTER TABLE ".$table." RENAME TO ".$tmp_table.";"); + $table_info[$new_name] = $table_info[$old_name]; + unset($table_info[$old_name]); + $this->CreateTableQuery($table,$table_info,null); - //Обновление ключа serial после ручной вставки - public function UpdateSerial($table,$column) { - $this->db->query("SELECT setval(pg_get_serial_sequence('".$table."', '".$column."'), coalesce(max(".$column."),0) + 1, false) FROM ".$table); - } + foreach ($data as $row) { + $values = $row['values']; + $values[$new_name] = $values[$old_name]; + unset($values[$old_name]); + $this->db->insertQuery($table, $values); + } + $this->DropTableQuery($tmp_table); + } + } - public function Column_Definition($name,$data,$pg){ - $constraint = isset($data['constraint'])?" ".$data['constraint']:""; - $references = ""; - if (isset($data['references'])) { - $references = " REFERENCES ".$data['references']; - } - if (isset($data["not_null"]) && $data["not_null"]) - $constraint .=" NOT NULL"; - $type = $data['type']; - if (!$pg) { - if (strtolower($type)=="serial") - $type = "integer"; - //if (strtolower($type)=="boolean") - // $type = "integer"; - } - return $name." ".$type.$references.$constraint; - } + //Обновление ключа serial после ручной вставки + public function UpdateSerial($table,$column) { + $this->db->query("SELECT setval(pg_get_serial_sequence('".$table."', '".$column."'), coalesce(max(".$column."),0) + 1, false) FROM ".$table); + } - public function AddColumn($table_name,$column_name,$field){ - $pg = $this->db->isPostgres(); - $q = "ALTER TABLE ".$table_name." ADD COLUMN ". - $this->Column_Definition($column_name, $field, $pg); - $this->db->query($q); - } + public function Column_Definition($name,$data,$pg){ + $constraint = isset($data['constraint'])?" ".$data['constraint']:""; + $references = ""; + if (isset($data['references'])) { + $references = " REFERENCES ".$data['references']; + } + if (isset($data["not_null"]) && $data["not_null"]) + $constraint .=" NOT NULL"; + $type = $data['type']; + if (!$pg) { + if (strtolower($type)=="serial") + $type = "integer"; + //if (strtolower($type)=="boolean") + // $type = "integer"; + } + return $name." ".$type.$references.$constraint; + } - function getConstraintDef($c/*: array*/) { - if ($c['type'] == 'unique') { - return "UNIQUE(" . implode(", ", $c['fields']) . ")"; - } - return ""; + public function AddColumn($table_name,$column_name,$field){ + $pg = $this->db->isPostgres(); + $q = "ALTER TABLE ".$table_name." ADD COLUMN ". + $this->Column_Definition($column_name, $field, $pg); + $this->db->query($q); + } + + function getConstraintDef($c/*: array*/) { + if ($c['type'] == 'unique') { + return "UNIQUE(" . implode(", ", $c['fields']) . ")"; + } + return ""; + } + + //CreateTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']]) + public function CreateTableQuery($table, $fields, $constraints) { + $pg = $this->db->isPostgres(); + if ($constraints) { + if (is_array($constraints)) { + $constraints = $this->getConstraintDef($constraints); + } + $constraints = ", " . $constraints; } - //CreateTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']]) - public function CreateTableQuery($table, $fields, $constraints) { - $pg = $this->db->isPostgres(); - if ($constraints) { - if (is_array($constraints)) { - $constraints = $this->getConstraintDef($constraints); + $statement = "CREATE TABLE $table (" . implode(",", + array_map(function($name,$data) use ($pg) { + return $this->Column_Definition($name,$data,$pg); + }, array_keys($fields), array_values($fields)) + ) . " " . $constraints . ")"; + $this->db->query($statement); + } + + public function DumpTable($table_name) { + $pg = $this->db->isPostgres(); + + $result/*: array*/ = array(); + $data/*: array*/ = $this->db->fetchAllArray("SELECT * FROM ".$table_name.";"); + + if (!$pg) { + $table_fields = $this->TableInfo($table_name); + foreach ($table_fields as $name => $value) { + $type = strtolower($value['type']); + if ($type == "boolean") { + foreach ($data as &$row) { + $row/*: array*/ = $row; + if (isset($row[$name])) { + $row[$name] = boolval($row[$name]); } - $constraints = ", " . $constraints; + } } + } + } + foreach ($data as $r) { + $result[] = array( + "type" => "insert", + "table_name" => $table_name, + "values" => $r + ); + } + return $result; + } - $statement = "CREATE TABLE $table (" . implode(",", - array_map(function($name,$data) use ($pg) { - return $this->Column_Definition($name,$data,$pg); - }, array_keys($fields), array_values($fields)) - ) . " " . $constraints . ")"; - $this->db->query($statement); - } + public function GetAllTableNames() { + $result = []; + if ($this->db->isPostgres()) { + $query = "SELECT table_name as name FROM information_schema.tables WHERE table_schema='public'"; + } else { + $query = "SELECT * FROM sqlite_master WHERE type='table'"; + } + $tables = $this->db->fetchAllArray($query); + foreach ($tables as $table) { + $result[] = $table['name']; + } + return $result; + } - public function DumpTable($table_name) { - $pg = $this->db->isPostgres(); - - $result/*: array*/ = array(); - $data/*: array*/ = $this->db->fetchAllArray("SELECT * FROM ".$table_name.";"); - - if (!$pg) { - $table_fields = $this->TableInfo($table_name); - foreach ($table_fields as $name => $value) { - $type = strtolower($value['type']); - if ($type == "boolean") { - foreach ($data as &$row) { - $row/*: array*/ = $row; - if (isset($row[$name])) { - $row[$name] = boolval($row[$name]); - } - } - } - } - } - foreach ($data as $r) { - $result[] = array( - "type" => "insert", - "table_name" => $table_name, - "values" => $r - ); - } - return $result; - } - - public function GetAllTableNames() { - $result = []; - if ($this->db->isPostgres()) { - $query = "SELECT table_name as name FROM information_schema.tables WHERE table_schema='public'"; - } else { - $query = "SELECT * FROM sqlite_master WHERE type='table'"; - } - $tables = $this->db->fetchAllArray($query); - foreach ($tables as $table) { - $result[] = $table['name']; - } - return $result; - } - - public function DumpInserts() { - $table_names = $this->GetAllTableNames(); - $result = array(); - foreach ($table_names as $table_name) { - $result = array_merge($result, $this->DumpTable($table_name)); - } - return $result; - } -} \ No newline at end of file + public function DumpInserts() { + $table_names = $this->GetAllTableNames(); + $result = array(); + foreach ($table_names as $table_name) { + $result = array_merge($result, $this->DumpTable($table_name)); + } + return $result; + } +}