chore: Аннотации к типам
This commit is contained in:
parent
e5713e9015
commit
530a3b931d
22 changed files with 388 additions and 131 deletions
|
|
@ -4,26 +4,37 @@ namespace ctiso\Database;
|
|||
use ctiso\Database;
|
||||
|
||||
class IdGenerator {
|
||||
/** @var Database */
|
||||
private $db;
|
||||
|
||||
function __construct(Database $db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function isBeforeInsert() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAfterInsert() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function isAfterInsert() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $seq
|
||||
* @return int
|
||||
*/
|
||||
function getId($seq) {
|
||||
if ($this->db->isPostgres()) {
|
||||
$result = $this->db->fetchOneArray("SELECT nextval('$seq') AS nextval");
|
||||
} else {
|
||||
$result = $this->db->fetchOneArray("SELECT last_insert_rowid() AS nextval");
|
||||
}
|
||||
}
|
||||
return (int)$result['nextval'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,20 @@ namespace ctiso\Database;
|
|||
use ctiso\Database\Manager;
|
||||
|
||||
class JsonInstall {
|
||||
/** @var Manager */
|
||||
public $db_manager;
|
||||
/** @var array */
|
||||
public $serialColumns;
|
||||
|
||||
public function __construct(Manager $db_manager) {
|
||||
$this->db_manager = $db_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Установить базу данных
|
||||
* @param string $dbinit_path
|
||||
* @param ?string $dbfill_path
|
||||
*/
|
||||
function install($dbinit_path, $dbfill_path = null) {
|
||||
$dbinit_file = file_get_contents($dbinit_path);
|
||||
if (is_string($dbinit_file)) {
|
||||
|
|
@ -32,6 +39,11 @@ class JsonInstall {
|
|||
$this->makeConstraints($initActions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список таблиц, которые не существуют в базе данных
|
||||
* @param array $tables
|
||||
* @return array
|
||||
*/
|
||||
function missingTables($tables) {
|
||||
$actual_tables = $this->db_manager->getAllTableNames();
|
||||
$missingTables = [];
|
||||
|
|
@ -42,7 +54,12 @@ class JsonInstall {
|
|||
return $missingTables;
|
||||
}
|
||||
|
||||
// Создать таблицы
|
||||
/**
|
||||
* Создать таблицы
|
||||
* @param array $initActions
|
||||
* @param string $dbinit_path
|
||||
* @return void
|
||||
*/
|
||||
function initDataBase(array $initActions, $dbinit_path) {
|
||||
$pg = $this->db_manager->db->isPostgres();
|
||||
if (!$pg) {
|
||||
|
|
@ -73,7 +90,7 @@ class JsonInstall {
|
|||
}
|
||||
}
|
||||
if ($action["type"] != "alterReference") {
|
||||
$this->db_manager->ExecuteAction($action, $dbinit_path);
|
||||
$this->db_manager->executeAction($action, $dbinit_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +112,11 @@ class JsonInstall {
|
|||
}
|
||||
}
|
||||
|
||||
//Заполнить данными
|
||||
/**
|
||||
* Заполнить данными
|
||||
* @param string $dbfill_file_path
|
||||
* @return void
|
||||
*/
|
||||
function fillDataBase($dbfill_file_path) {
|
||||
$dbfill_file = file_get_contents($dbfill_file_path);
|
||||
if (is_string($dbfill_file)) {
|
||||
|
|
@ -128,7 +149,11 @@ class JsonInstall {
|
|||
}
|
||||
}
|
||||
|
||||
//Обновить ключи serial и создать ограничения
|
||||
/**
|
||||
* Обновить ключи serial и создать ограничения
|
||||
* @param array $initActions
|
||||
* @return void
|
||||
*/
|
||||
function makeConstraints($initActions) {
|
||||
$pg = $this->db_manager->db->isPostgres();
|
||||
if ($pg) {
|
||||
|
|
|
|||
|
|
@ -17,9 +17,15 @@ class Manager
|
|||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function executeAction(array $action, $db_file = "")
|
||||
/**
|
||||
* Выполняет действие
|
||||
* @param array $action
|
||||
* @param string $db_file
|
||||
* @throws Exception
|
||||
*/
|
||||
public function executeAction(array $action, $db_file = ""): void
|
||||
{
|
||||
switch($action["type"]) {
|
||||
switch ($action["type"]) {
|
||||
case "dropTable":
|
||||
$this->dropTableQuery($action["table_name"], true);
|
||||
break;
|
||||
|
|
@ -56,59 +62,85 @@ class Manager
|
|||
|
||||
break;
|
||||
default:
|
||||
throw new Exception("unknown action ". $action["type"] . PHP_EOL);
|
||||
throw new Exception("unknown action " . $action["type"] . PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
//Дропает и создаёт SQL VIEW
|
||||
public function recreateView($viewName, $selectStatement)
|
||||
/**
|
||||
* Дропает и создаёт SQL VIEW
|
||||
* @param string $viewName
|
||||
* @param string $selectStatement
|
||||
*/
|
||||
public function recreateView($viewName, $selectStatement): void
|
||||
{
|
||||
$this->db->query("DROP VIEW ".$viewName);
|
||||
$this->db->query("CREATE VIEW ".$viewName." AS ".$selectStatement);
|
||||
$this->db->query("DROP VIEW " . $viewName);
|
||||
$this->db->query("CREATE VIEW " . $viewName . " AS " . $selectStatement);
|
||||
}
|
||||
|
||||
public function dropTableQuery($table, $cascade=false)
|
||||
/**
|
||||
* Дропает таблицу
|
||||
* @param string $table
|
||||
* @param bool $cascade
|
||||
*/
|
||||
public function dropTableQuery($table, $cascade = false): void
|
||||
{
|
||||
$statement = "DROP TABLE IF EXISTS ".$table;
|
||||
if ($this->db->isPostgres()&&$cascade) {
|
||||
$statement = "DROP TABLE IF EXISTS " . $table;
|
||||
if ($this->db->isPostgres() && $cascade) {
|
||||
$statement .= " CASCADE";
|
||||
}
|
||||
$this->db->query($statement);
|
||||
}
|
||||
|
||||
public function alterReference($table, $column, $refTable, $refColumn)
|
||||
/**
|
||||
* Добавляет ссылку на другую таблицу
|
||||
* @param string $table
|
||||
* @param string $column
|
||||
* @param string $refTable
|
||||
* @param string $refColumn
|
||||
*/
|
||||
public function alterReference($table, $column, $refTable, $refColumn): void
|
||||
{
|
||||
$this->db->query("ALTER TABLE ".$table." ADD CONSTRAINT ".$table."_".$column."fk"." FOREIGN KEY (".$column.") REFERENCES ".$refTable." (".$refColumn.")");
|
||||
$this->db->query("ALTER TABLE " . $table . " ADD CONSTRAINT " . $table . "_" . $column . "fk" . " FOREIGN KEY (" . $column . ") REFERENCES " . $refTable . " (" . $refColumn . ") ON DELETE CASCADE ON UPDATE CASCADE");
|
||||
}
|
||||
|
||||
//Извлечение информации о полях таблицы
|
||||
/**
|
||||
* Извлечение информации о полях таблицы
|
||||
* @param string $table
|
||||
* @return array{type:string,not_null:bool,constraint:?string}[]|null
|
||||
*/
|
||||
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.");");
|
||||
$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"=> ((bool) $result["pk"]) ? "PRIMARY KEY" : null
|
||||
"type" => $result["type"],
|
||||
"not_null" => boolval($result["notnull"]),
|
||||
"constraint" => ((bool) $result["pk"]) ? "PRIMARY KEY" : null
|
||||
];
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
public function renameColumn($table, $old_name, $new_name)
|
||||
/**
|
||||
* Переименование столбца в таблице
|
||||
* @param string $table
|
||||
* @param string $old_name
|
||||
* @param string $new_name
|
||||
*/
|
||||
public function renameColumn($table, $old_name, $new_name): void
|
||||
{
|
||||
$pg = $this->db->isPostgres();
|
||||
if ($pg) {
|
||||
$this->db->query("ALTER TABLE ".$table." RENAME COLUMN ".$old_name." TO ".$new_name);
|
||||
$this->db->query("ALTER TABLE " . $table . " RENAME COLUMN " . $old_name . " TO " . $new_name);
|
||||
} else {
|
||||
$tmp_table = "tmp_" . $table;
|
||||
$this->dropTableQuery($tmp_table);
|
||||
|
|
@ -120,7 +152,7 @@ class Manager
|
|||
|
||||
$data = $this->dumpTable($table);
|
||||
|
||||
$this->db->query("ALTER TABLE ".$table." RENAME TO ".$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);
|
||||
|
|
@ -135,41 +167,63 @@ class Manager
|
|||
}
|
||||
}
|
||||
|
||||
//Обновление ключа serial после ручной вставки
|
||||
public function updateSerial($table, $column)
|
||||
/**
|
||||
* Обновление ключа serial после ручной вставки
|
||||
* @param string $table
|
||||
* @param string $column
|
||||
*/
|
||||
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);
|
||||
$this->db->query("SELECT setval(pg_get_serial_sequence('" . $table . "', '" . $column . "'), coalesce(max(" . $column . "),0) + 1, false) FROM " . $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает определение столбца
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param bool $pg
|
||||
* @return string
|
||||
*/
|
||||
public function columnDefinition($name, $data, $pg)
|
||||
{
|
||||
$constraint = isset($data['constraint']) ? " ".$data['constraint'] : "";
|
||||
$constraint = isset($data['constraint']) ? " " . $data['constraint'] : "";
|
||||
$references = "";
|
||||
if (isset($data['references'])) {
|
||||
$references = " REFERENCES " . $data['references']['refTable'] . '(' .$data['references']['refColumn'] . ')';
|
||||
$references = " REFERENCES " . $data['references']['refTable'] . '(' . $data['references']['refColumn'] . ')';
|
||||
}
|
||||
if (isset($data["not_null"]) && $data["not_null"]) {
|
||||
$constraint .=" NOT NULL";
|
||||
$constraint .= " NOT NULL";
|
||||
}
|
||||
$type = $data['type'];
|
||||
if (!$pg) {
|
||||
if (strtolower($type)=="serial") {
|
||||
if (strtolower($type) == "serial") {
|
||||
$type = "integer";
|
||||
}
|
||||
//if (strtolower($type)=="boolean")
|
||||
// $type = "integer";
|
||||
}
|
||||
return $name." ".$type.$references.$constraint;
|
||||
return $name . " " . $type . $references . $constraint;
|
||||
}
|
||||
|
||||
public function addColumn($table_name, $column_name, $field)
|
||||
/**
|
||||
* Добавляет столбец в таблицу
|
||||
* @param string $table_name
|
||||
* @param string $column_name
|
||||
* @param array $field
|
||||
*/
|
||||
public function addColumn($table_name, $column_name, $field): void
|
||||
{
|
||||
$pg = $this->db->isPostgres();
|
||||
$q = "ALTER TABLE ".$table_name." ADD COLUMN ".
|
||||
$this->columnDefinition($column_name, $field, $pg);
|
||||
$q = "ALTER TABLE " . $table_name . " ADD COLUMN " .
|
||||
$this->columnDefinition($column_name, $field, $pg);
|
||||
$this->db->query($q);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает определение ограничения
|
||||
* @param array{fields: string[], type: string} $c
|
||||
* @return string
|
||||
*/
|
||||
public function getConstraintDef(array $c)
|
||||
{
|
||||
if ($c['type'] == 'unique') {
|
||||
|
|
@ -178,7 +232,14 @@ class Manager
|
|||
return "";
|
||||
}
|
||||
|
||||
//CreateTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']])
|
||||
|
||||
/**
|
||||
* Создает таблицу
|
||||
* @example createTableQuery('users',['id'=>['type'=>'integer','constraint'=>'PRIMARY KEY']])
|
||||
* @param string $table
|
||||
* @param array $fields
|
||||
* @param array|string|null $constraints
|
||||
*/
|
||||
public function createTableQuery($table, $fields, $constraints)
|
||||
{
|
||||
$pg = $this->db->isPostgres();
|
||||
|
|
@ -198,12 +259,17 @@ class Manager
|
|||
$this->db->query($statement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает дамп таблицы
|
||||
* @param string $table_name
|
||||
* @return array
|
||||
*/
|
||||
public function dumpTable($table_name)
|
||||
{
|
||||
$pg = $this->db->isPostgres();
|
||||
|
||||
$result = [];
|
||||
$data = $this->db->fetchAllArray("SELECT * FROM ".$table_name.";");
|
||||
$data = $this->db->fetchAllArray("SELECT * FROM " . $table_name . ";");
|
||||
|
||||
if (!$pg) {
|
||||
$table_fields = $this->tableInfo($table_name);
|
||||
|
|
@ -220,14 +286,18 @@ class Manager
|
|||
}
|
||||
foreach ($data as $r) {
|
||||
$result[] = [
|
||||
"type" => "insert",
|
||||
"table_name" => $table_name,
|
||||
"values" => $r
|
||||
"type" => "insert",
|
||||
"table_name" => $table_name,
|
||||
"values" => $r
|
||||
];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает все имена таблиц
|
||||
* @return array
|
||||
*/
|
||||
public function getAllTableNames()
|
||||
{
|
||||
$result = [];
|
||||
|
|
@ -243,6 +313,10 @@ class Manager
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает дамп всех таблиц
|
||||
* @return array
|
||||
*/
|
||||
public function dumpInserts()
|
||||
{
|
||||
$table_names = $this->getAllTableNames();
|
||||
|
|
|
|||
|
|
@ -32,29 +32,41 @@ class Statement
|
|||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
function setInt($n, $value) {
|
||||
/**
|
||||
* @param int|string $n
|
||||
* @param int $value
|
||||
*/
|
||||
function setInt($n, $value): void {
|
||||
$this->binds [] = [$n, $value, PDO::PARAM_INT];
|
||||
}
|
||||
|
||||
function setString($n, $value) {
|
||||
/**
|
||||
* @param int|string $n
|
||||
* @param string $value
|
||||
*/
|
||||
function setString($n, $value): void {
|
||||
$this->binds [] = [$n, $value, PDO::PARAM_STR];
|
||||
}
|
||||
|
||||
function setBlob($n, $value) {
|
||||
/**
|
||||
* @param int|string $n
|
||||
* @param mixed $value
|
||||
*/
|
||||
function setBlob($n, $value): void {
|
||||
$this->binds [] = [$n, $value, PDO::PARAM_LOB];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
*/
|
||||
function setLimit($limit) {
|
||||
function setLimit($limit): void {
|
||||
$this->limit = $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
*/
|
||||
function setOffset($offset) {
|
||||
function setOffset($offset): void {
|
||||
$this->offset = $offset;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ class StatementIterator implements \Iterator
|
|||
{
|
||||
|
||||
private $result;
|
||||
/** @var int */
|
||||
private $pos = 0;
|
||||
/** @var int */
|
||||
private $row_count;
|
||||
|
||||
/**
|
||||
|
|
@ -37,15 +39,15 @@ class StatementIterator implements \Iterator
|
|||
return $this->result->cache[$this->pos];
|
||||
}
|
||||
|
||||
function next(): void{
|
||||
function next(): void {
|
||||
$this->pos++;
|
||||
}
|
||||
|
||||
function seek($index) {
|
||||
function seek($index): void {
|
||||
$this->pos = $index;
|
||||
}
|
||||
|
||||
function count() {
|
||||
function count(): int {
|
||||
return $this->row_count;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue