From 06d92863ee767e6669246f3358073e12c5123b08 Mon Sep 17 00:00:00 2001 From: babaev-an Date: Mon, 4 Aug 2025 18:05:04 +0300 Subject: [PATCH] 20250804 --- sources/attributes/AutoIncrement.php | 30 ++++ sources/attributes/Check.php | 38 +++++ sources/attributes/DataType.php | 45 ++++++ sources/attributes/DefaultValue.php | 37 +++++ sources/attributes/ForeignKey.php | 44 ++++++ sources/attributes/NotNull.php | 30 ++++ sources/attributes/Unique.php | 30 ++++ sources/classes/DBItemProperty.php | 12 +- sources/classes/DataBaseHeadItem.php | 94 ++++++++++++ sources/classes/DataBaseHeader.php | 29 ++++ sources/classes/Database.php | 8 +- .../classes/tm_drivers/MSSQLTableManager.php | 52 +++++++ .../classes/tm_drivers/MySQLTableManager.php | 53 +++++++ .../tm_drivers/OracleDBTableManager.php | 52 +++++++ .../tm_drivers/PostgreSQLTableManager.php | 56 +++++++ .../classes/tm_drivers/SQLiteTableManager.php | 52 +++++++ sources/enums/DBType.php | 49 ++++++ sources/interfaces/IDBItem.php | 21 +-- sources/interfaces/ITableManager.php | 48 ++++++ sources/traits/Database/DatabaseSpecial.php | 144 ++++++++++++++++-- .../Database/DatabaseTableManagement.php | 49 ++++++ 21 files changed, 928 insertions(+), 45 deletions(-) create mode 100644 sources/attributes/AutoIncrement.php create mode 100644 sources/attributes/Check.php create mode 100644 sources/attributes/DataType.php create mode 100644 sources/attributes/DefaultValue.php create mode 100644 sources/attributes/ForeignKey.php create mode 100644 sources/attributes/NotNull.php create mode 100644 sources/attributes/Unique.php create mode 100644 sources/classes/DataBaseHeadItem.php create mode 100644 sources/classes/DataBaseHeader.php create mode 100644 sources/classes/tm_drivers/MSSQLTableManager.php create mode 100644 sources/classes/tm_drivers/MySQLTableManager.php create mode 100644 sources/classes/tm_drivers/OracleDBTableManager.php create mode 100644 sources/classes/tm_drivers/PostgreSQLTableManager.php create mode 100644 sources/classes/tm_drivers/SQLiteTableManager.php create mode 100644 sources/enums/DBType.php create mode 100644 sources/interfaces/ITableManager.php create mode 100644 sources/traits/Database/DatabaseTableManagement.php diff --git a/sources/attributes/AutoIncrement.php b/sources/attributes/AutoIncrement.php new file mode 100644 index 0000000..0b460db --- /dev/null +++ b/sources/attributes/AutoIncrement.php @@ -0,0 +1,30 @@ +Condition = $condition; + } + } \ No newline at end of file diff --git a/sources/attributes/DataType.php b/sources/attributes/DataType.php new file mode 100644 index 0000000..e2a28c0 --- /dev/null +++ b/sources/attributes/DataType.php @@ -0,0 +1,45 @@ +Type = $type; + $this->Size = $size; + } + } \ No newline at end of file diff --git a/sources/attributes/DefaultValue.php b/sources/attributes/DefaultValue.php new file mode 100644 index 0000000..37cda52 --- /dev/null +++ b/sources/attributes/DefaultValue.php @@ -0,0 +1,37 @@ +Value = $value; + } + } \ No newline at end of file diff --git a/sources/attributes/ForeignKey.php b/sources/attributes/ForeignKey.php new file mode 100644 index 0000000..df29b7b --- /dev/null +++ b/sources/attributes/ForeignKey.php @@ -0,0 +1,44 @@ +TableName = $table; + $this->FieldName = $fieldName; + } + } \ No newline at end of file diff --git a/sources/attributes/NotNull.php b/sources/attributes/NotNull.php new file mode 100644 index 0000000..ff32b90 --- /dev/null +++ b/sources/attributes/NotNull.php @@ -0,0 +1,30 @@ +Value = $value; // - установка имени поля в таблице БД $this->FieldName = StringExtension::IsNullOrWhitespace($fieldName) ? $name : $fieldName; - // - установка признака того, что свойство является первичным ключом - $this->IsPrimaryKey = $isPrimaryKey; + // - установка свойств столбца + $this->Column = $column; // - установка признака того, что свойство игнорируется при сохранении в / загрузке из БД $this->IsIgnored = $isIgnored; // - установка конвертеров значения свойства в значение поля БД diff --git a/sources/classes/DataBaseHeadItem.php b/sources/classes/DataBaseHeadItem.php new file mode 100644 index 0000000..24d56df --- /dev/null +++ b/sources/classes/DataBaseHeadItem.php @@ -0,0 +1,94 @@ +Name = $name; + $this->Type = $type; + $this->IsNotNull = $isNotNull; + $this->IsUnique = $isUnique; + $this->IsPrimaryKey = $isPrimaryKey; + $this->ForeignWith = $foreignWith; + $this->Check = $check; + $this->Default = $default; + $this->IsAutoIncrement = $isAutoIncrement; + } + } \ No newline at end of file diff --git a/sources/classes/DataBaseHeader.php b/sources/classes/DataBaseHeader.php new file mode 100644 index 0000000..dc428dc --- /dev/null +++ b/sources/classes/DataBaseHeader.php @@ -0,0 +1,29 @@ +Container = new ObjectArray(); + } + } \ No newline at end of file diff --git a/sources/classes/Database.php b/sources/classes/Database.php index c2fdd9d..00cf550 100644 --- a/sources/classes/Database.php +++ b/sources/classes/Database.php @@ -1,9 +1,5 @@ prepare($sql); + + // Выполняю запрос + $stmt->execute(['tableName' => $tableName]); + + // Получаю количество таблиц и вывожу true или false + return $stmt->fetchColumn() === '1'; + } + + public function CreateTable (PDO $handle, string $tableName, DataBaseHeader $columns): bool + { + // TODO: Implement CreateTable() method. + + return false; + } + + public function DropTable (PDO $handle, string $tableName): bool + { + // TODO: Implement DropTable() method. + return false; + } + } \ No newline at end of file diff --git a/sources/classes/tm_drivers/MySQLTableManager.php b/sources/classes/tm_drivers/MySQLTableManager.php new file mode 100644 index 0000000..ac256a1 --- /dev/null +++ b/sources/classes/tm_drivers/MySQLTableManager.php @@ -0,0 +1,53 @@ +prepare($sql); + + // Выполняю запрос + $stmt->execute(['tableName' => $tableName]); + + // Получаю количество таблиц, если > 0, то вывожу true, иначе - false + return $stmt->fetchColumn() > 0; + } + + public function CreateTable (PDO $handle, string $tableName, DataBaseHeader $columns): bool + { + // TODO: Implement CreateTable() method. + + return false; + } + + public function DropTable (PDO $handle, string $tableName): bool + { + // TODO: Implement DropTable() method. + return false; + } + } \ No newline at end of file diff --git a/sources/classes/tm_drivers/OracleDBTableManager.php b/sources/classes/tm_drivers/OracleDBTableManager.php new file mode 100644 index 0000000..89582ff --- /dev/null +++ b/sources/classes/tm_drivers/OracleDBTableManager.php @@ -0,0 +1,52 @@ +prepare($sql); + + // Выполняю запрос + $stmt->execute(['tableName' => $tableName]); + + // Получаю количество таблиц, если >0, то вывожу true, иначе - false + return $stmt->fetchColumn() > 0; + } + + public function CreateTable (PDO $handle, string $tableName, DataBaseHeader $columns): bool + { + // TODO: Implement CreateTable() method. + + return false; + } + + public function DropTable (PDO $handle, string $tableName): bool + { + // TODO: Implement DropTable() method. + return false; + } + } \ No newline at end of file diff --git a/sources/classes/tm_drivers/PostgreSQLTableManager.php b/sources/classes/tm_drivers/PostgreSQLTableManager.php new file mode 100644 index 0000000..fdc7916 --- /dev/null +++ b/sources/classes/tm_drivers/PostgreSQLTableManager.php @@ -0,0 +1,56 @@ +prepare($sql); + + // Выполняю запрос + $stmt->execute(['tableName' => $tableName]); + + // Получаю количество таблиц, если = "true", то вывожу true, иначе - false + return $stmt->fetchColumn() === 'true'; + } + + public function CreateTable (PDO $handle, string $tableName, DataBaseHeader $columns): bool + { + // TODO: Implement CreateTable() method. + + return false; + } + + public function DropTable (PDO $handle, string $tableName): bool + { + // TODO: Implement DropTable() method. + return false; + } + } \ No newline at end of file diff --git a/sources/classes/tm_drivers/SQLiteTableManager.php b/sources/classes/tm_drivers/SQLiteTableManager.php new file mode 100644 index 0000000..f57b32d --- /dev/null +++ b/sources/classes/tm_drivers/SQLiteTableManager.php @@ -0,0 +1,52 @@ +prepare($sql); + + // Выполняю запрос + $stmt->execute(['tableName' => $tableName]); + + // Получаю количество таблиц, если >0, то вывожу true, иначе - false + return $stmt->fetchColumn() > 0; + } + + public function CreateTable (PDO $handle, string $tableName, DataBaseHeader $columns): bool + { + // TODO: Implement CreateTable() method. + + return false; + } + + public function DropTable (PDO $handle, string $tableName): bool + { + // TODO: Implement DropTable() method. + return false; + } + } \ No newline at end of file diff --git a/sources/enums/DBType.php b/sources/enums/DBType.php new file mode 100644 index 0000000..2ca5a91 --- /dev/null +++ b/sources/enums/DBType.php @@ -0,0 +1,49 @@ +true, если таблица существует, иначе возвращает false. + */ + public function IsTableExist (PDO $handle, string $tableName): bool; + + /** + * Создает таблицу в базе данных. + * + * @param PDO $handle Представляет соединение между PHP и сервером базы данных. + * @param string $tableName Имя таблицы. + * @param DataBaseHeader $columns Колонки таблицы. + * + * @return bool Возвращает true, если таблица успешно создана, иначе возвращает false. + */ + public function CreateTable (PDO $handle, string $tableName, DataBaseHeader $columns): bool; + + /** + * Удаляет таблицу из базы данных. + * + * @param PDO $handle Представляет соединение между PHP и сервером базы данных. + * @param string $tableName Имя таблицы. + * + * @return bool Возвращает true, если таблица успешно удалена, иначе возвращает false. + */ + public function DropTable (PDO $handle, string $tableName): bool; + } \ No newline at end of file diff --git a/sources/traits/Database/DatabaseSpecial.php b/sources/traits/Database/DatabaseSpecial.php index 236782b..1556776 100644 --- a/sources/traits/Database/DatabaseSpecial.php +++ b/sources/traits/Database/DatabaseSpecial.php @@ -8,13 +8,23 @@ use Exception; use goodboyalex\php_components_pack\classes\ObjectArray; + use goodboyalex\php_components_pack\classes\Tuple; + use goodboyalex\php_db_components_pack\attributes\AutoIncrement; + use goodboyalex\php_db_components_pack\attributes\Check; use goodboyalex\php_db_components_pack\attributes\ConvertToDB; + use goodboyalex\php_db_components_pack\attributes\DataType; + use goodboyalex\php_db_components_pack\attributes\DefaultValue; use goodboyalex\php_db_components_pack\attributes\FieldName; + use goodboyalex\php_db_components_pack\attributes\ForeignKey; use goodboyalex\php_db_components_pack\attributes\IgnoredInDB; + use goodboyalex\php_db_components_pack\attributes\NotNull; use goodboyalex\php_db_components_pack\attributes\PrimaryKey; + use goodboyalex\php_db_components_pack\attributes\Unique; use goodboyalex\php_db_components_pack\classes\ConditionBuilder; + use goodboyalex\php_db_components_pack\classes\DataBaseHeadItem; use goodboyalex\php_db_components_pack\classes\DBItemProperty; use goodboyalex\php_db_components_pack\enums\DBOperation; + use goodboyalex\php_db_components_pack\enums\DBType; use goodboyalex\php_db_components_pack\interfaces\IDBItem; use PDO; use ReflectionClass; @@ -68,11 +78,11 @@ continue; // - получаю рефлексию класса - $reflectedClass = new ReflectionClass(get_class($source)); + $class = new ReflectionClass(get_class($source)); try { // - получаю рефлексию свойства - $reflectionProperty = $reflectedClass->getProperty($key); + $property = $class->getProperty($key); } catch (ReflectionException) { // - если ошибка, то вывожу пустой массив @@ -80,22 +90,12 @@ } // - пропускаю не публичные свойства - if (!$reflectionProperty->isPublic()) + if (!$property->isPublic()) // -- пропускаю continue; // - получаю атрибуты - $attributes = $reflectionProperty->getAttributes(); - - /** - * Фильтруем поля, игнорируемые для данной операции - * - * @var PrimaryKey|null $pkAttr Атрибут первичного ключа. - */ - $pkAttr = self::FindAttribute($attributes, PrimaryKey::class); - - // - это первичный ключ? - $isPrimary = $pkAttr !== null; + $attributes = $property->getAttributes(); /** * Фильтруем поля, игнорируемые для данной операции @@ -131,8 +131,100 @@ $converterFromDB = $convertAttr?->ConvertFromDB; $compareFunc = $convertAttr?->Compare; + // - получаем свойства столбца + /** + * Атрибут первичного ключа. + * + * @var PrimaryKey|null $pkAttr Атрибут первичного ключа. + */ + $pkAttr = self::FindAttribute($attributes, PrimaryKey::class); + + // -- это первичный ключ? + $isPrimary = $pkAttr !== null; + + /** + * Тип данных поля. + * + * @var DataType|null $dtAttr Атрибут типа данных + */ + $dtAttr = self::FindAttribute($attributes, DataType::class); + + // - тип данных + $dataType = $dtAttr !== null + ? new Tuple($dtAttr->Type, $dtAttr->Size) + : new Tuple(self::GetDBTypeForType($property->getType()->getName()), 0); + + /** + * Атрибут "не пустое значение". + * + * @var NotNull|null $nnAttr Атрибут нет пустому значению. + */ + $nnAttr = self::FindAttribute($attributes, NotNull::class); + + // -- это первичный ключ? + $isNotNull = $nnAttr !== null; + + /** + * Атрибут "уникальное значение". + * + * @var Unique|null $unqAttr Атрибут уникального значения. + */ + $unqAttr = self::FindAttribute($attributes, Unique::class); + + // -- это уникальный ключ? + $isUnique = $unqAttr !== null; + + /** + * Ключ для связывания поля. + * + * @var ForeignKey|null $chkAttr Атрибут связывания. + */ + $chkAttr = self::FindAttribute($attributes, ForeignKey::class); + + // - связывание с другой таблицей + $foreignWith = $chkAttr !== null + ? new Tuple($chkAttr->TableName, $chkAttr->FieldName) + : new Tuple(null, null); + + /** + * Атрибут проверки поля. + * + * @var Check|null $chkAttr Атрибут проверки поля. + */ + $chkAttr = self::FindAttribute($attributes, Check::class); + + // - проверка данных поля + $checkFunc = $chkAttr !== null + ? $chkAttr->Condition + : new ConditionBuilder(); + + /** + * Атрибут значения по умолчанию поля. + * + * @var DefaultValue|null $dvAttr Атрибут значения по умолчанию поля. + */ + $dvAttr = self::FindAttribute($attributes, DefaultValue::class); + + // - значение по умолчанию + $default = $dvAttr?->Value; + + /** + * Атрибут "автоматической генерации". + * + * @var AutoIncrement|null $aiAttr Атрибут "автоматической генерации". + */ + $aiAttr = self::FindAttribute($attributes, AutoIncrement::class); + + // -- это атрибут "автоматической генерации"? + $isAutoIncrement = $aiAttr !== null; + + // - создаю заголовок + $columnHeader = new DataBaseHeadItem($fieldName, $dataType, $isNotNull, $isUnique, $isPrimary, + $foreignWith, $checkFunc, $default, $isAutoIncrement); + + // - создаю объект свойства - $item = new DBItemProperty($key, $value, $fieldName, $isPrimary, $isIgnore, $converterToDB, + $item = new DBItemProperty($key, $value, $fieldName, $columnHeader, $isIgnore, $converterToDB, $converterFromDB, $compareFunc); // - добавляю в массив @@ -143,6 +235,28 @@ return $result; } + /** + * Получает тип из базы данных по типу переменной. + * + * @param string $type Тип. + * + * @return DBType Тип из базы данных. + */ + private static function GetDBTypeForType (string $type): DBType + { + /** + * @noinspection SpellCheckingInspection Отключаю проверку из-за того, что многие типы будут в lower case + */ + return match (strtolower($type)) { + "int", "integer" => DBType::INT, + "float", "double" => DBType::FLOAT, + "bool", "boolean" => DBType::BOOL, + "dateonly", "timeonly", "datetime", "datetimeimmutable" => DBType::DATE, + "array" => DBType::ARRAY, + default => DBType::STRING + }; + } + /** * Подготавливает массив параметров * diff --git a/sources/traits/Database/DatabaseTableManagement.php b/sources/traits/Database/DatabaseTableManagement.php new file mode 100644 index 0000000..80f3b3a --- /dev/null +++ b/sources/traits/Database/DatabaseTableManagement.php @@ -0,0 +1,49 @@ +true - таблица существует, false - не существует. + */ + public function IsTableExist (string $tableName): bool + { + // Получаю систему управления таблицами БД + $dbDrv = match ($this->Config->Driver) { + DBDriver::MySQL => new MySQLTableManager(), + DBDriver::MSSQL => new MSSQLTableManager(), + DBDriver::PostgreSQL => new PostgreSQLTableManager(), + DBDriver::OracleDB => new OracleDBTableManager(), + DBDriver::SQLite => new SQLiteTableManager() + }; + + // Проверяю существование таблицы, вывожу результат + return $dbDrv->isTableExist($this->DataBaseHandle, $tableName); + } + } \ No newline at end of file