157 lines
6.1 KiB
PHP
157 lines
6.1 KiB
PHP
<?php
|
||
/**
|
||
* @noinspection SqlNoDataSourceInspection
|
||
*/
|
||
|
||
namespace goodboyalex\php_db_components_pack\classes\tm_drivers;
|
||
|
||
use goodboyalex\php_components_pack\classes\ObjectArray;
|
||
use goodboyalex\php_db_components_pack\enums\DBDriver;
|
||
use goodboyalex\php_db_components_pack\enums\DBType;
|
||
use goodboyalex\php_db_components_pack\interfaces\ITableManager;
|
||
use goodboyalex\php_db_components_pack\models\DataBaseColumn;
|
||
use PDO;
|
||
|
||
/**
|
||
* Система менеджмента таблицами базы данных MySQL.
|
||
*
|
||
* @author Александр Бабаев
|
||
* @package php_db_components_pack
|
||
* @version 1.0
|
||
* @since 1.0
|
||
*/
|
||
final class MySQLTableManager implements ITableManager
|
||
{
|
||
/**
|
||
* @var array $TypeConversation Массив типов.
|
||
*/
|
||
public array $TypeConversation {
|
||
get => [
|
||
DBType::INT->name => 'INT',
|
||
DBType::FLOAT->name => 'DECIMAL',
|
||
DBType::STRING->name => 'VARCHAR',
|
||
DBType::BOOL->name => 'BOOLEAN',
|
||
DBType::DATE->name => 'TIMESTAMP',
|
||
DBType::ARRAY->name => 'JSON'
|
||
];
|
||
}
|
||
|
||
/**
|
||
* @inheritDoc
|
||
*/
|
||
public function IsTableExist (PDO $handle, string $tableName): bool
|
||
{
|
||
// Создаю SQL-запрос
|
||
$sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
|
||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = :tableName";
|
||
|
||
// Подготавливаю данные
|
||
$stmt = $handle->prepare($sql);
|
||
|
||
// Выполняю запрос
|
||
$stmt->execute(['tableName' => $tableName]);
|
||
|
||
// Получаю количество таблиц, если > 0, то вывожу true, иначе - false
|
||
return $stmt->fetchColumn() > 0;
|
||
}
|
||
|
||
/**
|
||
* @inheritDoc
|
||
*/
|
||
public function CreateTable (PDO $handle, string $tableName, ObjectArray $columns): bool
|
||
{
|
||
// Если таблица $tableName уже существует
|
||
if ($this->IsTableExist($handle, $tableName))
|
||
// - то прерываю
|
||
return false;
|
||
|
||
// Создаю массив столбцов
|
||
$colArray = [];
|
||
|
||
// Для каждого переданного столбца
|
||
foreach ($columns as $column)
|
||
// - конвертирую его в строку и добавляю в массив
|
||
$colArray[] = $this->ParseColumn($column);
|
||
|
||
// Конвертирую массив столбцов в строку
|
||
$columnsStr = implode(', ', $colArray);
|
||
|
||
// Создаю SQL запрос
|
||
$sql = "CREATE TABLE `$tableName` ($columnsStr)";
|
||
|
||
// Подготавливаю запрос
|
||
$stmt = $handle->prepare($sql);
|
||
|
||
// Выполняю запрос
|
||
$stmt->execute();
|
||
|
||
// Возвращаю, существует ли теперь таблица
|
||
return $this->IsTableExist($handle, $tableName);
|
||
}
|
||
|
||
/**
|
||
* @inheritDoc
|
||
*/
|
||
public function ParseColumn (DataBaseColumn $column): string
|
||
{
|
||
// Получаю тип данных
|
||
$dbType = $column->Type->Get(0);
|
||
|
||
// Получаю размер типа данных
|
||
$dbTypeSize = $column->Type->Get(1) ?? 0;
|
||
|
||
// Получаю SQL тип данных
|
||
$type = DBType::ToSQLType(DBDriver::MySQL, $dbType);
|
||
|
||
// Если тип данных - строка
|
||
if ($dbType == DBType::STRING)
|
||
// - то добавляю размер
|
||
$type .= '(' . ($dbTypeSize == 0 ? 'MAX' : $dbTypeSize) . ')';
|
||
|
||
// Формирую начало результата
|
||
$result = "`$column->Name` $type";
|
||
|
||
// Если должно быть ненулевое значение
|
||
if ($column->IsNotNull)
|
||
// - то добавляю NOT NULL
|
||
$result .= ' NOT NULL';
|
||
|
||
// Если должно быть уникальное значение
|
||
if ($column->IsUnique)
|
||
// - то добавляю UNIQUE
|
||
$result .= ' UNIQUE';
|
||
|
||
// Если это первичный ключ
|
||
if ($column->IsPrimaryKey)
|
||
// - то добавляю PRIMARY KEY
|
||
$result .= ' PRIMARY KEY';
|
||
|
||
// Получаю связанную таблицу
|
||
$fkDefinitionTable = $column->ForeignWith->Get(0);
|
||
// - и столбец в ней
|
||
$fkDefinitionKey = $column->ForeignWith->Get(1);
|
||
|
||
// Если связанная таблица и столбец определены
|
||
if (!($fkDefinitionTable == null || $fkDefinitionKey == null))
|
||
// - то добавляю REFERENCES
|
||
$result .= " REFERENCES $fkDefinitionTable($fkDefinitionKey)";
|
||
|
||
// Если заданы проверки
|
||
if ($column->Check->Count() > 0)
|
||
// - то добавляю CHECK
|
||
$result .= " CHECK({$column->Check->Build()})";
|
||
|
||
// Если задано значение по умолчанию
|
||
if ($column->Default != null)
|
||
// - то добавляю DEFAULT
|
||
$result .= " DEFAULT '$column->Default'";
|
||
|
||
// Если это поле AutoIncrement
|
||
if ($column->IsAutoIncrement)
|
||
// - то добавляю AUTO_INCREMENT
|
||
$result .= ' AUTO_INCREMENT';
|
||
|
||
// Вывожу результат
|
||
return $result;
|
||
}
|
||
} |