diff --git a/.gitignore b/.gitignore
index 217f5dc..4d7719a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2233,4 +2233,4 @@ FodyWeavers.xsd
/vendor/phpunit/phpunit/src/Framework/Exception/ErrorLogNotWritableException.php
/vendor/phpunit/phpunit/src/Runner/ShutdownHandler.php
/.idea/codeStyles/
-/tests/secret_not_in_git/
\ No newline at end of file
+/tests/database_config.php
\ No newline at end of file
diff --git a/help/basic_usage/count_exist_data.md b/help/basic_usage/count_exist_data.md
index 6298863..4ca62e4 100644
--- a/help/basic_usage/count_exist_data.md
+++ b/help/basic_usage/count_exist_data.md
@@ -1,4 +1,4 @@
-# Пороверка существования данных и их количество
+# Проверка существования данных и их количество
Итак, в [прошлой статье](get_data.md) мы получали данные из таблицы `users`. Напомним, что она имеет вид:
diff --git a/help/class_desc/classes/Condition.md b/help/class_desc/classes/Condition.md
index 5bfd002..4c248c5 100644
--- a/help/class_desc/classes/Condition.md
+++ b/help/class_desc/classes/Condition.md
@@ -12,7 +12,7 @@ namespace goodboyalex\php_db_components_pack;
## Автор и версия
- **Автор**: Александр Бабаев
-- **Версия**: 1.0
+- **Версия**: 1.0.2
- **Дата начала поддержки**: с версии 1.0
## Назначение
@@ -70,7 +70,7 @@ $condition = new Condition('age', '>', 18);
#### Задание условий с помощью функции (`FUNC:`)
-Если в имени колонки передаётся какая-либо функция (начинать такую функцию следует с `FUNC:`), то при обработке она
+Если в имени колонки передаётся какая-либо функция (начинать такую функцию следует с `FUNC:`), то при обработке она
не обрабатывается как столбец. Это же касается и значения.
Например, давайте добавим условие, что каждое новое имя пользователя начинается с заглавной буквы
@@ -82,8 +82,10 @@ $condition = new Condition('FUNC:SUBSTR(name, 1, 1)', "=", 'FUNC:UPPER(SUBSTR(na
```
в результате запрос будет содержать:
+
```sql
-SUBSTR(name, 1, 1) = UPPER(SUBSTR(name, 1, 1)
+SUBSTR
+(name, 1, 1) = UPPER(SUBSTR(name, 1, 1)
```
### 2. Метод `Parse`
@@ -114,11 +116,12 @@ $parsedCondition = Condition::Parse(['age', '>', 18]);
**Синтаксис**:
```php
-public function Get(int $index = 0): Tuple;
+public function Get(DBDriver $driver, int $index = 0): Tuple;
```
**Описание**:
+- **$driver**: Тип драйвера СУБД.
- **$index**: Индексация для замены переменных (для предотвращения SQL-инъекций).
- Метод возвращает кортеж (tuple), состоящий из двух частей:
- SQL-строку с замещаемым параметром (`:paramX`), где X — номер индекса.
@@ -127,7 +130,7 @@ public function Get(int $index = 0): Tuple;
**Пример использования**:
```php
-[$sqlPart, $params] = $condition->Get();
+[$sqlPart, $params] = $condition->Get(\goodboyalex\php_db_components_pack\enums\DBDriver::MySQL);
// $sqlPart будет выглядеть примерно так: "`age` > :param0"
// $params будет содержать массив с фактическим значением: ["param0" => 18]
```
@@ -136,12 +139,13 @@ public function Get(int $index = 0): Tuple;
```php
use goodboyalex\php_db_components_pack\Condition;
+use goodboyalex\php_db_components_pack\enums\DBDriver;
// Создаём условие для поиска пользователей по возрасту
$condition = new Condition('age', '>', 18);
// Формируем условие для использования в SQL-запросе
-list($sql, $parameters) = $condition->Get();
+[$sql, $parameters] = $condition->Get(DBDriver::MySQL);
// Теперь можем использовать $sql и $parameters в запросе
$query = "SELECT * FROM users WHERE $sql";
diff --git a/help/class_desc/classes/ConditionBuilder.md b/help/class_desc/classes/ConditionBuilder.md
index fb380f0..ea517f8 100644
--- a/help/class_desc/classes/ConditionBuilder.md
+++ b/help/class_desc/classes/ConditionBuilder.md
@@ -13,7 +13,7 @@ namespace goodboyalex\php_db_components_pack\classes;
## Автор и версия
- **Автор**: Александр Бабаев
-- **Версия**: 1.0
+- **Версия**: 1.0.2
- **Дата начала поддержки**: с версии 1.0
## Назначение
@@ -125,11 +125,12 @@ $builder = new ConditionBuilder()->AddGroup(Condition::LOGIC_OR, [new Condition(
**Синтаксис**:
```php
-public function Build(): Tuple;
+public function Build(DBDriver $driver): Tuple;
```
**Описание**:
+- **$driver**: Тип драйвера СУБД.
- Метод возвращает кортеж (Tuple), состоящий из двух элементов:
- SQL-строка с условием, готовым к выполнению.
- Массив параметров, необходимых для последующей передачи в подготовленный SQL-запрос.
@@ -139,7 +140,7 @@ public function Build(): Tuple;
```php
// $sql будет (`age` >= :age), а params - [':age' = 18]
-[$sql, $params] = new ConditionBuilder()->AddCondition('age', '>=', 18)->Build();
+[$sql, $params] = new ConditionBuilder()->AddCondition('age', '>=', 18)->Build(\goodboyalex\php_db_components_pack\enums\DBDriver::MySQL);
```
---
@@ -317,9 +318,11 @@ public function WhereLike(string $column, string $value): ConditionBuilder;
```
**Описание**:
+
- **$column**: Имя колонки, по которой проводится поиск.
- **$value**: Шаблон для поиска (обычно включает символы `%` для указания маски).
-- Метод добавляет условие в виде `WHERE column LIKE '%value%'` и возвращает объект для продолжительного построения условий.
+- Метод добавляет условие в виде `WHERE column LIKE '%value%'` и возвращает объект для продолжительного построения
+ условий.
**Пример использования**:
@@ -341,10 +344,12 @@ public function AddCondition(string $column, string $operator, mixed $value): Co
```
**Описание**:
+
- **$column**: Имя колонки, участвующей в условии.
- **$operator**: Любой оператор сравнения (например, `=`, `!=`, `<`, `>`, `IN`, `BETWEEN`, и т.д.).
- **$value**: Значение, с которым производится сравнение.
-- Метод добавляет условие в форме `WHERE column OPERATOR value` и возвращает объект для продолжения построения цепочки условий.
+- Метод добавляет условие в форме `WHERE column OPERATOR value` и возвращает объект для продолжения построения цепочки
+ условий.
**Пример использования**:
diff --git a/help/class_desc/classes/ConditionGroup.md b/help/class_desc/classes/ConditionGroup.md
index 343fa2a..6d7164e 100644
--- a/help/class_desc/classes/ConditionGroup.md
+++ b/help/class_desc/classes/ConditionGroup.md
@@ -13,7 +13,7 @@ namespace goodboyalex\php_db_components_pack\classes;
## Автор и версия
- **Автор**: Александр Бабаев
-- **Версия**: 1.0
+- **Версия**: 1.0.2
- **Дата начала поддержки**: с версии 1.0
## Назначение
diff --git a/help/class_desc/enums/DBDriver.md b/help/class_desc/enums/DBDriver.md
index f2fb88d..6a9f535 100644
--- a/help/class_desc/enums/DBDriver.md
+++ b/help/class_desc/enums/DBDriver.md
@@ -6,7 +6,7 @@
## Основная информация
- **Автор**: Александр Бабаев
-- **Версия**: 1.0
+- **Версия**: 1.0.2
- **Дата начала поддержки**: с версии 1.0
## Пространство имен и зависимости
@@ -27,6 +27,64 @@ use goodboyalex\php_components_pack\traits\EnumExtensionsTrait;
| `OracleDB` | `3` | Драйвер Oracle |
| `SQLite` | `4` | Драйвер SQLite |
+## Методы
+
+### Метод `GetSigns`
+
+Метод `GetSigns` предназначен для получения знаков, которыми принято заключать имена полей и таблиц в различных системах
+управления базами данных (СУБД). Некоторые СУБД используют двойные кавычки `"`, квадратные скобки `[]`, обратные
+апострофы `` ` `` или другие специальные символы для экранирования идентификаторов (имен таблиц, колонок и других
+объектов базы данных).
+
+#### Синтаксис
+
+```php
+public static function GetSigns(DBDriver $driver): Tuple
+```
+
+#### Аргументы
+
+- **$driver**: Переменная типа `DBDriver`, указывающая на используемую СУБД (например, MySQL, PostgreSQL, SQLite и
+ т.д.).
+
+#### Возвращаемое значение
+
+Метод возвращает кортеж `Tuple`, содержащий два элемента:
+
+- Первый элемент — знак открывающий.
+- Второй элемент — знак закрывающий.
+
+Например, для `MySQL` и `PostgreSQL` чаще всего возвращаются символы обратной косой черты и прямой (```"``, ```"``)
+соответственно, а для `MS SQL Server` — квадратные скобки (`[`, `]`).
+
+#### Пример использования
+
+Допустим, у вас есть код, который выводит SQL-запрос с экранированием идентификатора в зависимости от используемой СУБД:
+
+```php
+use goodboyalex\php_db_components_pack\enums\DBDriver;
+
+// Получаем знаки для MySQL
+[$open, $close] = DBDriver::GetSigns(DBDriver::MYSQL);
+
+// Использование полученных знаков
+$sql = sprintf("SELECT %s%s%s FROM users;", $open, 'username', $close);
+```
+
+В результате для MySQL получится:
+
+```sql
+SELECT `username`
+FROM users;
+```
+
+Аналогично, для PostgreSQL:
+
+```sql
+SELECT "username"
+FROM users;
+```
+
## Особенности реализации
Используется trait `EnumExtensionsTrait`, предоставляющий дополнительные методы для работы с перечислениями, такие как
diff --git a/help/index.md b/help/index.md
index e92b35c..ed4d990 100644
--- a/help/index.md
+++ b/help/index.md
@@ -1,6 +1,6 @@
# Добро пожаловать в справочное руководство по компонентам PHP DB COMPONENTS PACK!
-**Руководство актуально для версии v1.0**
+**Руководство актуально для версии v1.0.2**
**Автор: Александр Бабаев**
@@ -12,7 +12,7 @@
2. [x] [Создание таблицы](basic_usage/create_table.md)
3. [x] [Вставка данных](basic_usage/insert_data.md)
4. [x] [Получение данных](basic_usage/get_data.md)
-5. [x] [Пороверка существования данных и их количество](basic_usage/count_exist_data.md)
+5. [x] [Проверка существования данных и их количество](basic_usage/count_exist_data.md)
6. [x] [Обновление данных](basic_usage/update_data.md)
7. [x] [Удаление данных](basic_usage/delete_data.md)
8. [x] [Удаление таблицы](basic_usage/drop_table.md)
diff --git a/sources/classes/Condition.php b/sources/classes/Condition.php
index e22ac1b..a3ffdd0 100644
--- a/sources/classes/Condition.php
+++ b/sources/classes/Condition.php
@@ -13,7 +13,7 @@
*
* @author Александр Бабаев
* @package php_db_components_pack
- * @version 1.0
+ * @version 1.0.2
* @since 1.0
*/
final class Condition implements IArrayable
diff --git a/sources/classes/ConditionBuilder.php b/sources/classes/ConditionBuilder.php
index 30b6748..a1f0fe0 100644
--- a/sources/classes/ConditionBuilder.php
+++ b/sources/classes/ConditionBuilder.php
@@ -15,7 +15,7 @@
*
* @author Александр Бабаев
* @package php_components_pack
- * @version 1.0
+ * @version 1.0.2
* @since 1.0
*/
final class ConditionBuilder implements IArrayable
diff --git a/sources/classes/ConditionGroup.php b/sources/classes/ConditionGroup.php
index 8d393d8..4d0ebd2 100644
--- a/sources/classes/ConditionGroup.php
+++ b/sources/classes/ConditionGroup.php
@@ -16,7 +16,7 @@
*
* @author Александр Бабаев
* @package php_components_pack
- * @version 1.0
+ * @version 1.0.2
* @since 1.0
*/
final class ConditionGroup implements IArrayable
diff --git a/sources/enums/DBDriver.php b/sources/enums/DBDriver.php
index 243805e..85f9dd9 100644
--- a/sources/enums/DBDriver.php
+++ b/sources/enums/DBDriver.php
@@ -10,7 +10,7 @@
*
* @author Александр Бабаев
* @package php_db_components_pack
- * @version 1.0
+ * @version 1.0.2
* @since 1.0
* @see \PDO
*/
diff --git a/sources/traits/Database/DatabaseCountExist.php b/sources/traits/Database/DatabaseCountExist.php
index 3f98fdd..2dda8ce 100644
--- a/sources/traits/Database/DatabaseCountExist.php
+++ b/sources/traits/Database/DatabaseCountExist.php
@@ -36,7 +36,7 @@
* @var string $sql_where Строка WHERE условий.
* @var array $params Параметры условий.
*/
- [$sql_where, $params] = $where->Build();
+ [$sql_where, $params] = $where->Build($this->Config->Driver);
// Подготавливаю имя таблицы
$table = $this->PrepareTableName($table);
diff --git a/sources/traits/Database/DatabaseDelete.php b/sources/traits/Database/DatabaseDelete.php
index a2164ad..174380a 100644
--- a/sources/traits/Database/DatabaseDelete.php
+++ b/sources/traits/Database/DatabaseDelete.php
@@ -29,16 +29,19 @@
*/
public function Delete (string $table, ConditionBuilder $where = new ConditionBuilder()): bool
{
+ // Подготавливаю имя таблицы
+ $table = $this->PrepareTableName($table);
+
/**
* Получаю SQL-запрос и параметры для where.
*
* @var string $sql_where SQL-запрос для where.
* @var array $params Параметры запроса.
*/
- [$sql_where, $params] = $where->Build();
+ [$sql_where, $params] = $where->Build($this->Config->Driver);
// Создаю запрос
- $sql = "DELETE FROM $this->DBSignOpen$table$this->DBSignClose";
+ $sql = "DELETE FROM $table";
// Если заданы where-параметры
if ($where->Count() > 0)
diff --git a/sources/traits/Database/DatabaseGet.php b/sources/traits/Database/DatabaseGet.php
index e18b4d8..1933621 100644
--- a/sources/traits/Database/DatabaseGet.php
+++ b/sources/traits/Database/DatabaseGet.php
@@ -7,6 +7,7 @@
use goodboyalex\php_components_pack\classes\ObjectArray;
use goodboyalex\php_db_components_pack\classes\ConditionBuilder;
+ use goodboyalex\php_db_components_pack\enums\DBDriver;
use goodboyalex\php_db_components_pack\enums\DBOperation;
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
use PDO;
@@ -33,22 +34,22 @@
* @return IDBItem|false Заполненный объект класса или false
в случае ошибки.
*/
public function GetRow (string $table, array $columns = [], ConditionBuilder $where = new ConditionBuilder(),
- string $className = "\\StdClass"): IDBItem|false
+ string $className = "\\StdClass"): IDBItem | false
{
// Задаю массив параметров
$params = [];
+ // Подготавливаю имя таблицы
+ $table = $this->PrepareTableName($table);
+
// Формируем SQL-запрос
$sql = $this->PrepareSQLForRowsQuery($table, $columns, $where, $params);
- // Добавляю лимит
- $sql .= " LIMIT 1";
-
// Получаю строку
- $row = $this->Query($sql, $params);
+ $row = $this->QueryFirst($sql, $params);
// Если не получено
- if ($row === false)
+ if ($row === false || count($row) == 0)
// - то вывожу false
return false;
@@ -75,11 +76,14 @@
* @return false|ObjectArray Массив найденных классов или false
в случае ошибки.
*/
public function GetRows (string $table, array $columns = [], ConditionBuilder $where = new ConditionBuilder(),
- string $className = "\\StdClass"): false|ObjectArray
+ string $className = "\\StdClass"): false | ObjectArray
{
// Задаю массив параметров
$params = [];
+ // Подготавливаю имя таблицы
+ $table = $this->PrepareTableName($table);
+
// Получаю SQL запрос
$sql = $this->PrepareSQLForRowsQuery($table, $columns, $where, $params);
@@ -124,18 +128,23 @@
* @see Query
*/
public function GetCol (string $table, string $column, ConditionBuilder $where = new ConditionBuilder()):
- false|array
- {
+ false | array {
/**
* Интерпретирую условия.
*
* @var string $sql_where Строка запроса.
* @var array $params Массив параметров строки запроса.
*/
- [$sql_where, $params] = $where->Build();
+ [$sql_where, $params] = $where->Build($this->Config->Driver);
+
+ // Получаю знаки открытия параметра и закрытия его
+ [$signOpen, $signClose] = DBDriver::GetSigns($this->Config->Driver);
+
+ // Подготавливаю имя таблицы
+ $table = $this->PrepareTableName($table);
// Создаю запрос
- $sql = "SELECT $this->DBSignOpen$column$this->DBSignClose FROM $this->DBSignOpen$table$this->DBSignClose";
+ $sql = "SELECT $signOpen$column$signClose FROM $table";
// Если заданы where-параметры
if ($where->Count() > 0)
diff --git a/sources/traits/Database/DatabaseInsert.php b/sources/traits/Database/DatabaseInsert.php
index 92ae7d9..831f4d7 100644
--- a/sources/traits/Database/DatabaseInsert.php
+++ b/sources/traits/Database/DatabaseInsert.php
@@ -119,6 +119,9 @@
// Подготавливаю массив параметров
$params = [];
+ // Получаю знаки открытия параметра и закрытия его
+ [$signOpen, $signClose] = DBDriver::GetSigns($this->Config->Driver);
+
// Получаю массив свойств
$properties = self::GetProperties($row, DBOperation::Insert);
@@ -157,7 +160,7 @@
$keyReal = $key[0] == ":" ? substr($key, 1) : $key;
// - добавляю в результирующий массив ключей
- $keys_params[] = "$this->DBSignOpen$keyReal$this->DBSignClose";
+ $keys_params[] = "$signOpen$keyReal$signClose";
// - добавляю в результирующий массив значений
$keys_values[] = ":$keyReal";
diff --git a/sources/traits/Database/DatabaseSpecial.php b/sources/traits/Database/DatabaseSpecial.php
index 6659386..c2557cf 100644
--- a/sources/traits/Database/DatabaseSpecial.php
+++ b/sources/traits/Database/DatabaseSpecial.php
@@ -291,12 +291,12 @@
* @param string $className Имя класса объекта.
* @param DBOperation $operation Операция.
*
- * @return object|null Экземпляр класса объекта или null
, если ошибка.
+ * @return IDBItem|null Экземпляр класса объекта или null
, если ошибка.
*/
- private function RestoreItem (array $row, string $className, DBOperation $operation): ?object
+ private function RestoreItem (array $row, string $className, DBOperation $operation): ?IDBItem
{
// Если целевой класс не реализует интерфейс IDBItem
- if (in_array(IDBItem::class, class_implements($className)))
+ if (!is_a($className, IDBItem::class, true))
// - то прерываем и возвращаем null
return null;
@@ -385,8 +385,12 @@
*/
private function PrepareColumn (array $columns): array
{
+ // Получаю знаки открытия параметра и закрытия его
+ [$signOpen, $signClose] = DBDriver::GetSigns($this->Config->Driver);
+
+ // Возвращаю результат
return array_map(
- function ($item)
+ function ($item) use ($signOpen, $signClose)
{
// Результирующая строка
$result = "";
@@ -399,18 +403,18 @@
// - последний символ
$lastLetter = substr($item, -1);
- // - если первый символ не $this->DBSignOpen
- if ($firstLetter !== $this->DBSignOpen)
+ // - если первый символ не $signOpen
+ if ($firstLetter !== $signOpen)
// -- то добавляем
- $result .= $this->DBSignOpen;
+ $result .= $signOpen;
// - добавляем строку
$result .= $item;
- // - если последний символ не $this->DBSignClose
- if ($lastLetter !== $this->DBSignClose)
+ // - если последний символ не $signClose
+ if ($lastLetter !== $signClose)
// -- то добавляем
- $result .= $this->DBSignClose;
+ $result .= $signClose;
}
// Возвращаем результат
@@ -438,13 +442,13 @@
* @var string $sql_where where-запрос SQL
* @var array $params Параметры и их значения (для защиты от SQL-инъекции)
*/
- [$sql_where, $params] = $whereConditions->Build();
+ [$sql_where, $params] = $whereConditions->Build($this->Config->Driver);
// Колонки
$sql_columns = count($columns) > 0 ? implode(', ', $this->PrepareColumn($columns)) : "*";
// Создаю запрос
- $sql = "SELECT $sql_columns FROM $this->DBSignOpen$table$this->DBSignClose";
+ $sql = "SELECT $sql_columns FROM $table";
// Если заданы where-параметры
if ($whereConditions->Count() > 0)
@@ -464,9 +468,13 @@
*/
private function PrepareTableName (string $table): string
{
+ // Получаю знаки открытия параметра и закрытия его
+ [$signOpen, $signClose] = DBDriver::GetSigns($this->Config->Driver);
+
+ // Возвращаю результат
return match ($this->Config->Driver) {
- DBDriver::MySQL, DBDriver::SQLite, DBDriver::OracleDB, DBDriver::PostgreSQL => $this->DBSignOpen
- . $table . $this->DBSignClose,
+ DBDriver::MySQL, DBDriver::SQLite, DBDriver::OracleDB, DBDriver::PostgreSQL =>
+ "$signOpen$table$signClose",
DBDriver::MSSQL => "[dbo].[$table]"
};
}
diff --git a/sources/traits/Database/DatabaseTableManagement.php b/sources/traits/Database/DatabaseTableManagement.php
index f405ade..70e7f7c 100644
--- a/sources/traits/Database/DatabaseTableManagement.php
+++ b/sources/traits/Database/DatabaseTableManagement.php
@@ -135,8 +135,11 @@
// - то возвращаем true
return true;
+ // Обрабатываю имя таблицы
+ $tableName = $this->PrepareTableName($tableName);
+
// SQL-запрос
- $sql = "DROP TABLE dbo.`$tableName`";
+ $sql = "DROP TABLE $tableName";
// Инициализирую транзакцию
$this->InitTransaction();
@@ -169,6 +172,6 @@
}
// Возвращаю, существует ли теперь таблица
- return $this->IsTableExist($tableName);
+ return !$this->IsTableExist($tableName);
}
}
\ No newline at end of file
diff --git a/sources/traits/Database/DatabaseUpdate.php b/sources/traits/Database/DatabaseUpdate.php
index a216f04..65bcb3b 100644
--- a/sources/traits/Database/DatabaseUpdate.php
+++ b/sources/traits/Database/DatabaseUpdate.php
@@ -7,6 +7,7 @@
use Exception;
use goodboyalex\php_db_components_pack\classes\ConditionBuilder;
+ use goodboyalex\php_db_components_pack\enums\DBDriver;
use goodboyalex\php_db_components_pack\enums\DBOperation;
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
use goodboyalex\php_db_components_pack\models\DBItemProperty;
@@ -33,6 +34,9 @@
*/
public function Update (string $table, IDBItem $item): bool
{
+ // Получаю знаки открытия параметра и закрытия его
+ [$signOpen, $signClose] = DBDriver::GetSigns($this->Config->Driver);
+
// Получаю свойства объекта
$properties = self::GetProperties($item, DBOperation::Update);
@@ -124,14 +128,19 @@
// Для каждого свойства для обновления
foreach ($propertyToSet as $key => $value) {
// - добавляю его в массив set
- $set[] = "$this->DBSignOpen$key$this->DBSignClose=:$key";
+ $set[] = "$key=:$key";//"$signOpen$key$signClose=:$key";
// - добавляю его в массив параметров set для обновления
$set_params[":$key"] = $value;
}
- // Строковая интерпретация массива set
- $sql_set = count($set) > 0 ? '(' . implode(", ", $set) . ')' : "";
+ // Если нечего изменять
+ if (count($set) == 0)
+ // - то прерываем с успехом
+ return true;
+
+ // Устанавливаю параметры обновления
+ $sql_set = implode(", ", $set);
/**
* Получаю WHERE-запрос и параметры.
@@ -139,13 +148,16 @@
* @var string $sql_where WHERE-запрос.
* @var array $where_params Параметры WHERE-запроса.
*/
- [$sql_where, $where_params] = $where->Build();
+ [$sql_where, $where_params] = $where->Build($this->Config->Driver);
// Объединяю все параметры в один массив
$params = array_merge($set_params, $where_params);
+ // Подготавливаю имя таблицы
+ $table = $this->PrepareTableName($table);
+
// Создаю запрос
- $sql = "UPDATE $this->DBSignOpen$table$this->DBSignClose SET $sql_set";
+ $sql = "UPDATE $table SET $sql_set";
// Если заданы where-параметры
if ($where->Count() > 0)
diff --git a/tests/classes/DatabaseTest.php b/tests/classes/DatabaseTest.php
new file mode 100644
index 0000000..060a7d1
--- /dev/null
+++ b/tests/classes/DatabaseTest.php
@@ -0,0 +1,408 @@
+ $terminate
+ ? die($exception->getMessage())
+ : print $exception->getMessage();
+
+ // Подключаем базу данных
+ $db = new Database($testConfig, $onException);
+
+ /* ТЕСТ 1: Создание таблицы */
+
+ // Задаём имя таблицы
+ $tableName = 'users';
+
+ // Создаю таблицу
+ $db->CreateTable(
+ tableName: $tableName,
+ dbItemClass: '\goodboyalex\php_db_components_pack\tests\data\UserModel'
+ );
+
+ // Проверяю создание
+ $this->assertTrue($db->IsTableExist($tableName));
+
+ /* 2. Добавление данных */
+
+ /* 2.1. Модели */
+
+ // Модель 1
+ $model1 = new UserModel(
+ id: GUID::Parse('8b5dab25-4445-436c-8f25-0f5352cb8500', true),
+ login: "account1",
+ password: "password1",
+ salt: GUID_EMPTY,
+ firstName: "firstName1",
+ middleName: "middleName1",
+ lastName: "lastName1",
+ email: "email1@ya.ru",
+ isEmailVerified: false,
+ groupName: "default",
+ createdAt: time(),
+ updatedAt: 0,
+ userData: ['key1' => 'value1', 'key2' => 'value2']
+ );
+
+ // Модель 2
+ $model2 = new UserModel(
+ id: GUID::Parse('3552914c-9ffc-4c73-8946-97c40b0d81b5'),
+ login: "account2",
+ password: "password2",
+ salt: GUID_EMPTY,
+ firstName: "firstName2",
+ middleName: "middleName2",
+ lastName: "lastName2",
+ email: "email2@ya.ru",
+ isEmailVerified: false,
+ groupName: "default",
+ createdAt: time(),
+ updatedAt: 0,
+ userData: ['key1' => 'value3', 'key2' => 4]
+ );
+
+ // Модель 3
+ $model3 = new UserModel(
+ id: GUID::Parse('73828df6-89a3-4feb-ae9a-ef79d0e67cb0'),
+ login: "account3",
+ password: "password3",
+ salt: GUID_EMPTY,
+ firstName: "firstName3",
+ middleName: "middleName3",
+ lastName: "lastName3",
+ email: "email3@ya.ru",
+ isEmailVerified: true,
+ groupName: "default1",
+ createdAt: time(),
+ updatedAt: time(),
+ userData: ['key1' => 1, 'key2' => 2]
+ );
+
+ // Модель 4
+ $model4 = new UserModel(
+ id: GUID::Parse('df39f53f-faff-42cf-bf00-f5855c3e11ec'),
+ login: "account4",
+ password: "password4",
+ salt: GUID_EMPTY,
+ firstName: "firstName4",
+ middleName: "middleName4",
+ lastName: "lastName4",
+ email: "email4@ya.ru",
+ isEmailVerified: true,
+ groupName: "default1",
+ createdAt: time(),
+ updatedAt: time(),
+ userData: ['key1' => 3, 'key2' => '2']
+ );
+
+ /* 2.2. Добавление 1 элемента */
+ // Вставляю $model1
+ $result = $db->Insert($tableName, $model1);
+
+ // Проверяю, успешно ли прошло
+ $this->assertTrue($result !== false);
+
+ // - и совпадает ли идентификатор
+ $this->assertTrue($model1->Id->IsEqualsTo($result));
+
+ /* 2.3. Добавление более 1 элемента */
+ // Массив ожидаемых результатов
+ $expectedResult = [
+ GUID::Parse('3552914c-9ffc-4c73-8946-97c40b0d81b5'),
+ GUID::Parse('73828df6-89a3-4feb-ae9a-ef79d0e67cb0'),
+ GUID::Parse('df39f53f-faff-42cf-bf00-f5855c3e11ec')
+ ];
+
+ // Вставляю несколько
+ $result = $db->InsertMany('users', $model2, $model3, $model4);
+
+ // Убеждаюсь, что вставка успешна
+ $this->assertTrue($result !== false);
+
+ // - и все идентификаторы совпадают
+ $this->assertEqualsCanonicalizing($expectedResult, $result);
+ }
+
+ public function testGetRow ()
+ {
+ $this->IncludeReq();
+
+ $db = $this->GetDatabase();
+
+ if (!$db->IsTableExist('users'))
+ die('Таблица не существует. Сперва запустите тест testCreateTable / Table does not exist. Run testCreateTable first');
+
+ if (!$db->IsExist(
+ table: 'users',
+ where: new ConditionBuilder()->WhereEquals('login', 'account1')
+ ))
+ die('Записи с логином account1 не существует в таблице users / Record with login account1 is not exists in table users');
+
+ /**
+ * @var false|UserModel $model
+ */
+ $model = $db->GetRow(
+ table: 'users',
+ where: new ConditionBuilder()->WhereEquals('login', 'account1'),
+ className: '\goodboyalex\php_db_components_pack\tests\data\UserModel'
+ );
+
+ $this->assertTrue($model !== false);
+ $this->assertEquals('account1', $model->Login);
+ $this->assertEquals(
+ 'account1', $model->Id->IsEqualsTo(GUID::Parse('8b5dab25-4445-436c-8f25-0f5352cb8500'))
+ );
+ }
+
+ public function testGetCol ()
+ {
+ $this->IncludeReq();
+
+ $db = $this->GetDatabase();
+
+ if (!$db->IsTableExist('users'))
+ die('Таблица не существует. Сперва запустите тест testCreateTable / Table does not exist. Run testCreateTable first');
+
+ if (!$db->IsExist(
+ table: 'users',
+ where: new ConditionBuilder()
+ ->WhereEquals('login', 'account2')
+ ->Or()
+ ->WhereEquals('login', 'account3')
+ ->Or()
+ ->WhereEquals('login', 'account4')
+ ))
+ die('Записи с логином account1 не существует в таблице users / Record with login account1 is not exists in table users');
+
+ $models = $db->GetCol(
+ table: 'users',
+ column: 'id',
+ where: new ConditionBuilder()->WhereNotEquals('login', 'account1')
+ );
+
+ $this->assertTrue($models !== false);
+
+ $expected = [
+ "3552914c-9ffc-4c73-8946-97c40b0d81b5",
+ "73828df6-89a3-4feb-ae9a-ef79d0e67cb0",
+ "df39f53f-faff-42cf-bf00-f5855c3e11ec"
+ ];
+
+ $this->assertEqualsCanonicalizing($expected, $models);
+ }
+
+ public function testGetRows ()
+ {
+ $this->IncludeReq();
+
+ $db = $this->GetDatabase();
+
+ if (!$db->IsTableExist('users'))
+ die('Таблица не существует. Сперва запустите тест testCreateTable / Table does not exist. Run testCreateTable first');
+
+ if (!$db->IsExist(
+ table: 'users',
+ where: new ConditionBuilder()
+ ->WhereEquals('login', 'account2')
+ ->Or()
+ ->WhereEquals('login', 'account3')
+ ->Or()
+ ->WhereEquals('login', 'account4')
+ ))
+ die('Записи с логином account1 не существует в таблице users / Record with login account1 is not exists in table users');
+
+ /**
+ * @var false|ObjectArray $model
+ */
+ $models = $db->GetRows(
+ table: 'users',
+ where: new ConditionBuilder()->WhereNotEquals('login', 'account1'),
+ className: '\goodboyalex\php_db_components_pack\tests\data\UserModel'
+ );
+
+ $this->assertTrue($models !== false);
+ $this->assertTrue($models->IsExist(fn (UserModel $model) => $model->Login == 'account2'));
+ }
+
+ public function testDropTable ()
+ {
+ $this->IncludeReq();
+
+ $db = $this->GetDatabase();
+
+ $result = $db->DropTable('users');
+
+ $this->assertTrue($result);
+ }
+
+ public function testGetValue ()
+ {
+ $this->IncludeReq();
+
+ $db = $this->GetDatabase();
+
+ if (!$db->IsTableExist('users'))
+ die('Таблица не существует. Сперва запустите тест testCreateTable / Table does not exist. Run testCreateTable first');
+
+ if (!$db->IsExist(
+ table: 'users',
+ where: new ConditionBuilder()
+ ->WhereEquals('login', 'account2')
+ ->Or()
+ ->WhereEquals('login', 'account3')
+ ->Or()
+ ->WhereEquals('login', 'account4')
+ ))
+ die('Записи с логином account1 не существует в таблице users / Record with login account1 is not exists in table users');
+
+ $id = $db->GetValue(
+ table: 'users',
+ column: 'id',
+ where: new ConditionBuilder()->WhereEquals('login', 'account2')
+ );
+
+ $this->assertEquals("3552914c-9ffc-4c73-8946-97c40b0d81b5", $id);
+ }
+
+ public function testUpdate ()
+ {
+ $this->IncludeReq();
+
+ $db = $this->GetDatabase();
+
+ if (!$db->IsTableExist('users'))
+ die('Таблица не существует. Сперва запустите тест testCreateTable / Table does not exist. Run testCreateTable first');
+
+ if (!$db->IsExist(
+ table: 'users',
+ where: new ConditionBuilder()->WhereEquals('login', 'account1')
+ ))
+ die('Запись с логином account1 не существует в таблице users. Сперва удалите запись с логином account1 (можно использовать метод testDelete) / Record with login account1 already exists in table users. Delete record with login account1 first');
+
+ $model = $db->GetRow(
+ 'users',
+ where: new ConditionBuilder()->WhereEquals('login', 'account1'),
+ className: '\goodboyalex\php_db_components_pack\tests\data\UserModel'
+ );
+
+ $this->assertTrue($model !== false);
+
+ $model->Email = 'account1@yandex.ru';
+
+ $result = $db->Update('users', $model);
+
+ $this->assertTrue($result);
+ }
+
+ public function testUpdateMany ()
+ {
+ $this->IncludeReq();
+
+ $db = $this->GetDatabase();
+
+ $model1 = $db->GetRow(
+ 'users',
+ where: new ConditionBuilder()->WhereEquals('login', 'account2'),
+ className: '\goodboyalex\php_db_components_pack\tests\data\UserModel'
+ );
+
+ $this->assertTrue($model1 !== false);
+
+ $model1->Email = 'account2@yandex.ru';
+ $model1->IsEmailVerified = true;
+
+ $model2 = $db->GetRow(
+ 'users',
+ where: new ConditionBuilder()->WhereEquals('login', 'account3'),
+ className: '\goodboyalex\php_db_components_pack\tests\data\UserModel'
+ );
+
+ $this->assertTrue($model2 !== false);
+
+
+ $model2->Email = 'account3@yandex.ru';
+ $model2->IsEmailVerified = true;
+
+ $model3 = $db->GetRow(
+ 'users',
+ where: new ConditionBuilder()->WhereEquals('login', 'account4'),
+ className: '\goodboyalex\php_db_components_pack\tests\data\UserModel'
+ );
+
+ $this->assertTrue($model3 !== false);
+
+ $model3->Email = 'account4@yandex.ru';
+ $model3->IsEmailVerified = true;
+
+
+ $result = $db->UpdateMany('users', $model1, $model2, $model3);
+
+ $this->assertTrue($result);
+ }
+
+ public function testDelete ()
+ {
+ $this->IncludeReq();
+
+ $db = $this->GetDatabase();
+
+ $result = $db->Delete('users', new ConditionBuilder()->WhereEquals('email_verified', 0));
+
+ $this->assertTrue($result);
+
+ $count = $db->Count('users');
+ $this->assertEquals(3, $count);
+
+ $result = $db->Delete('users');
+
+ $this->assertTrue($result);
+
+ $count = $db->Count('users');
+ $this->assertEquals(0, $count);
+ }
+
+ private function IncludeReq (): void {}
+
+ private function GetDatabase (): Database {}
+ }
\ No newline at end of file
diff --git a/tests/secret_not_in_git/Converters.php b/tests/data/Converters.php
similarity index 98%
rename from tests/secret_not_in_git/Converters.php
rename to tests/data/Converters.php
index 74b319c..5c11776 100644
--- a/tests/secret_not_in_git/Converters.php
+++ b/tests/data/Converters.php
@@ -1,6 +1,6 @@