20250819
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
use goodboyalex\php_components_pack\classes\Tuple;
|
use goodboyalex\php_components_pack\classes\Tuple;
|
||||||
use goodboyalex\php_components_pack\extensions\StringExtension;
|
use goodboyalex\php_components_pack\extensions\StringExtension;
|
||||||
use goodboyalex\php_components_pack\interfaces\IArrayable;
|
use goodboyalex\php_components_pack\interfaces\IArrayable;
|
||||||
|
use goodboyalex\php_db_components_pack\enums\DBDriver;
|
||||||
use PHPUnit\Event\InvalidArgumentException;
|
use PHPUnit\Event\InvalidArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,15 +102,19 @@
|
|||||||
/**
|
/**
|
||||||
* Формирует условие.
|
* Формирует условие.
|
||||||
*
|
*
|
||||||
|
* @param DBDriver $driver Тип драйвера СУБД.
|
||||||
* @param int $index Индекс замены параметров для защиты от SQL-инъекций.
|
* @param int $index Индекс замены параметров для защиты от SQL-инъекций.
|
||||||
*
|
*
|
||||||
* @return Tuple (string, array) Сформированное условие: SQL-запрос и параметры запроса.
|
* @return Tuple (string, array) Сформированное условие: SQL-запрос и параметры запроса.
|
||||||
*/
|
*/
|
||||||
public function Get (int $index = 0): Tuple
|
public function Get (DBDriver $driver, int $index = 0): Tuple
|
||||||
{
|
{
|
||||||
|
// Получаю знаки открытия и закрытия
|
||||||
|
[$signOpen, $signClose] = $driver->GetSigns($driver);
|
||||||
|
|
||||||
// Начинаю формировать SQL
|
// Начинаю формировать SQL
|
||||||
$sql = (!str_starts_with($this->ColumnName, "FUNC:"))
|
$sql = (!str_starts_with($this->ColumnName, "FUNC:"))
|
||||||
? "`$this->ColumnName`"
|
? "$signOpen$this->ColumnName$signClose"
|
||||||
: StringExtension::Replace('FUNC:', '', $this->ColumnName);
|
: StringExtension::Replace('FUNC:', '', $this->ColumnName);
|
||||||
|
|
||||||
// Добавляю оператор
|
// Добавляю оператор
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
use goodboyalex\php_components_pack\classes\Tuple;
|
use goodboyalex\php_components_pack\classes\Tuple;
|
||||||
use goodboyalex\php_components_pack\extensions\ArrayExtension;
|
use goodboyalex\php_components_pack\extensions\ArrayExtension;
|
||||||
use goodboyalex\php_components_pack\interfaces\IArrayable;
|
use goodboyalex\php_components_pack\interfaces\IArrayable;
|
||||||
|
use goodboyalex\php_db_components_pack\enums\DBDriver;
|
||||||
use goodboyalex\php_db_components_pack\traits\ConditionBuilder\ConditionBuilderConditionsSet;
|
use goodboyalex\php_db_components_pack\traits\ConditionBuilder\ConditionBuilderConditionsSet;
|
||||||
use goodboyalex\php_db_components_pack\traits\ConditionBuilder\ConditionBuilderLogicalOperationSet;
|
use goodboyalex\php_db_components_pack\traits\ConditionBuilder\ConditionBuilderLogicalOperationSet;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
@@ -64,7 +65,9 @@
|
|||||||
// --- если ошибка
|
// --- если ошибка
|
||||||
if ($builder === false)
|
if ($builder === false)
|
||||||
// ---- то выбрасываем исключение
|
// ---- то выбрасываем исключение
|
||||||
throw new InvalidArgumentException("Неверный логический оператор: $condition / The logical operator is invalid: $condition.");
|
throw new InvalidArgumentException(
|
||||||
|
"Неверный логический оператор: $condition / The logical operator is invalid: $condition."
|
||||||
|
);
|
||||||
|
|
||||||
// --- идём к следующему элементу
|
// --- идём к следующему элементу
|
||||||
continue;
|
continue;
|
||||||
@@ -93,7 +96,7 @@
|
|||||||
* @return false|string Возвращает правильно отформатированный оператор или <code>false</code>, если оператор
|
* @return false|string Возвращает правильно отформатированный оператор или <code>false</code>, если оператор
|
||||||
* не является логическим.
|
* не является логическим.
|
||||||
*/
|
*/
|
||||||
private static function PrepareLogicalOperator (string $operator): false|string
|
private static function PrepareLogicalOperator (string $operator): false | string
|
||||||
{
|
{
|
||||||
// Задаем массив логических операторов
|
// Задаем массив логических операторов
|
||||||
$logicalOperators = ['AND', 'OR', 'NOT', 'XOR', 'NAND', 'NOR'];
|
$logicalOperators = ['AND', 'OR', 'NOT', 'XOR', 'NAND', 'NOR'];
|
||||||
@@ -178,6 +181,81 @@
|
|||||||
return new ConditionGroup($operator, $conditionItems);
|
return new ConditionGroup($operator, $conditionItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Собирает условие в виде, пригодном для SQL.
|
||||||
|
*
|
||||||
|
* @param DBDriver $driver Тип драйвера СУБД.
|
||||||
|
* @param array $conditions Условия.
|
||||||
|
*
|
||||||
|
* @return Tuple (string, array) Возвращает условие в виде, пригодном для SQL и массив параметров для защиты
|
||||||
|
* от SQL-инъекций.
|
||||||
|
*/
|
||||||
|
private static function ProcessConditions (DBDriver $driver, array $conditions): Tuple
|
||||||
|
{
|
||||||
|
// Задаём массив частей
|
||||||
|
$parts = [];
|
||||||
|
|
||||||
|
// Задаём массив параметров для защиты от SQL-инъекций
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
// Задаём счётчик
|
||||||
|
$count = 0;
|
||||||
|
|
||||||
|
// Перебираем условия
|
||||||
|
foreach ($conditions as $condition) {
|
||||||
|
// - если это группа условий
|
||||||
|
if ($condition instanceof ConditionGroup) {
|
||||||
|
// -- парсим её и добавляем результат
|
||||||
|
$result = $condition->GetConditions($count);
|
||||||
|
|
||||||
|
// -- добавляем условие в массив частей
|
||||||
|
$parts[] = $result->Get(0);
|
||||||
|
|
||||||
|
// -- добавляем параметры для защиты от SQL-инъекций в массив
|
||||||
|
$params = array_merge($params, $result->Get(1));
|
||||||
|
|
||||||
|
// -- увеличиваем счётчик
|
||||||
|
$count = $count + count($result->Get(1));
|
||||||
|
|
||||||
|
// -- идём к следующему элементу
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - если это условие
|
||||||
|
if ($condition instanceof Condition) {
|
||||||
|
// -- парсим его
|
||||||
|
$result = $condition->Get($driver, $count);
|
||||||
|
|
||||||
|
// -- добавляем условие в массив частей
|
||||||
|
$parts[] = $result->Get(0);
|
||||||
|
|
||||||
|
// -- добавляем параметры для защиты от SQL-инъекций в массив
|
||||||
|
$params = array_merge($params, $result->Get(1));
|
||||||
|
|
||||||
|
// -- увеличиваем счётчик на 1
|
||||||
|
$count++;
|
||||||
|
|
||||||
|
// -- идём к следующему элементу
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// - иначе считаем, что это логический оператор, проверим это
|
||||||
|
$condition = self::PrepareLogicalOperator($condition);
|
||||||
|
|
||||||
|
// - если это не логический оператор
|
||||||
|
if ($condition === false)
|
||||||
|
// -- то пропускаем его
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// - добавляем его в массив частей
|
||||||
|
$parts[] = $condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возвращаем результат
|
||||||
|
return new Tuple(implode(' ', $parts), $params);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Добавляет группу условий.
|
* Добавляет группу условий.
|
||||||
*
|
*
|
||||||
@@ -194,16 +272,18 @@
|
|||||||
/**
|
/**
|
||||||
* Собирает условие в виде пригодном для SQL. Также возвращает массив параметров защиты от SQL-инъекций.
|
* Собирает условие в виде пригодном для SQL. Также возвращает массив параметров защиты от SQL-инъекций.
|
||||||
*
|
*
|
||||||
|
* @param DBDriver $driver Тип драйвера СУБД.
|
||||||
|
*
|
||||||
* @return Tuple (string, array) Возвращает условие в виде, пригодном для SQL и массив параметров для защиты от
|
* @return Tuple (string, array) Возвращает условие в виде, пригодном для SQL и массив параметров для защиты от
|
||||||
* SQL-инъекций.
|
* SQL-инъекций.
|
||||||
*/
|
*/
|
||||||
public function Build (): Tuple
|
public function Build (DBDriver $driver): Tuple
|
||||||
{
|
{
|
||||||
// Очищаем цепочку от пустых элементов
|
// Очищаем цепочку от пустых элементов
|
||||||
ArrayExtension::RemoveEmpties($this->Conditions);
|
ArrayExtension::RemoveEmpties($this->Conditions);
|
||||||
|
|
||||||
// Парсим цепочку и возвращаем результат
|
// Парсим цепочку и возвращаем результат
|
||||||
return $this->ProcessConditions($this->Conditions);
|
return self::ProcessConditions($driver, $this->Conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -337,78 +417,4 @@
|
|||||||
// Возвращаем объект
|
// Возвращаем объект
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Собирает условие в виде, пригодном для SQL.
|
|
||||||
*
|
|
||||||
* @param array $conditions Условия.
|
|
||||||
*
|
|
||||||
* @return Tuple (string, array) Возвращает условие в виде, пригодном для SQL и массив параметров для защиты
|
|
||||||
* от SQL-инъекций.
|
|
||||||
*/
|
|
||||||
private function ProcessConditions (array $conditions): Tuple
|
|
||||||
{
|
|
||||||
// Задаём массив частей
|
|
||||||
$parts = [];
|
|
||||||
|
|
||||||
// Задаём массив параметров для защиты от SQL-инъекций
|
|
||||||
$params = [];
|
|
||||||
|
|
||||||
// Задаём счётчик
|
|
||||||
$count = 0;
|
|
||||||
|
|
||||||
// Перебираем условия
|
|
||||||
foreach ($conditions as $condition) {
|
|
||||||
// - если это группа условий
|
|
||||||
if ($condition instanceof ConditionGroup) {
|
|
||||||
// -- парсим её и добавляем результат
|
|
||||||
$result = $condition->GetConditions($count);
|
|
||||||
|
|
||||||
// -- добавляем условие в массив частей
|
|
||||||
$parts[] = $result->Get(0);
|
|
||||||
|
|
||||||
// -- добавляем параметры для защиты от SQL-инъекций в массив
|
|
||||||
$params = array_merge($params, $result->Get(1));
|
|
||||||
|
|
||||||
// -- увеличиваем счётчик
|
|
||||||
$count = $count + count($result->Get(1));
|
|
||||||
|
|
||||||
// -- идём к следующему элементу
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - если это условие
|
|
||||||
if ($condition instanceof Condition) {
|
|
||||||
// -- парсим его
|
|
||||||
$result = $condition->Get($count);
|
|
||||||
|
|
||||||
// -- добавляем условие в массив частей
|
|
||||||
$parts[] = $result->Get(0);
|
|
||||||
|
|
||||||
// -- добавляем параметры для защиты от SQL-инъекций в массив
|
|
||||||
$params = array_merge($params, $result->Get(1));
|
|
||||||
|
|
||||||
// -- увеличиваем счётчик на 1
|
|
||||||
$count++;
|
|
||||||
|
|
||||||
// -- идём к следующему элементу
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// - иначе считаем, что это логический оператор, проверим это
|
|
||||||
$condition = self::PrepareLogicalOperator($condition);
|
|
||||||
|
|
||||||
// - если это не логический оператор
|
|
||||||
if ($condition === false)
|
|
||||||
// -- то пропускаем его
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// - добавляем его в массив частей
|
|
||||||
$parts[] = $condition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Возвращаем результат
|
|
||||||
return new Tuple(implode(' ', $parts), $params);
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
use goodboyalex\php_components_pack\classes\Tuple;
|
use goodboyalex\php_components_pack\classes\Tuple;
|
||||||
use goodboyalex\php_components_pack\interfaces\IArrayable;
|
use goodboyalex\php_components_pack\interfaces\IArrayable;
|
||||||
|
use goodboyalex\php_db_components_pack\enums\DBDriver;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,11 +46,12 @@
|
|||||||
/**
|
/**
|
||||||
* Формирует массив условий.
|
* Формирует массив условий.
|
||||||
*
|
*
|
||||||
|
* @param DBDriver $driver Тип драйвера СУБД.
|
||||||
* @param int $index Индекс замены параметров для защиты от SQL-инъекций.
|
* @param int $index Индекс замены параметров для защиты от SQL-инъекций.
|
||||||
*
|
*
|
||||||
* @return Tuple (string, array) Массив условий (строка SQL, параметры SQL).
|
* @return Tuple (string, array) Массив условий (строка SQL, параметры SQL).
|
||||||
*/
|
*/
|
||||||
public function GetConditions (int $index = 0): Tuple
|
public function GetConditions (DBDriver $driver, int $index = 0): Tuple
|
||||||
{
|
{
|
||||||
// Создаём результирующую строку
|
// Создаём результирующую строку
|
||||||
$resultString = "";
|
$resultString = "";
|
||||||
@@ -66,7 +68,7 @@
|
|||||||
$count++;
|
$count++;
|
||||||
|
|
||||||
// - получаем условие
|
// - получаем условие
|
||||||
$result = $this->WriteCondition($this->Conditions[$i], $count);
|
$result = $this->WriteCondition($driver, $this->Conditions[$i], $count);
|
||||||
|
|
||||||
// - записываем условие в строку
|
// - записываем условие в строку
|
||||||
$resultString .= $result->Get(0);
|
$resultString .= $result->Get(0);
|
||||||
@@ -182,22 +184,23 @@
|
|||||||
/**
|
/**
|
||||||
* Формирует условие.
|
* Формирует условие.
|
||||||
*
|
*
|
||||||
|
* @param DBDriver $driver Тип драйвера СУБД.
|
||||||
* @param mixed $condition Условие.
|
* @param mixed $condition Условие.
|
||||||
* @param int $index Индекс замены параметров для защиты от SQL-инъекций.
|
* @param int $index Индекс замены параметров для защиты от SQL-инъекций.
|
||||||
*
|
*
|
||||||
* @return string Возвращает условие в виде строки SQL.
|
* @return Tuple Возвращает условие в виде строки SQL.
|
||||||
*/
|
*/
|
||||||
private function WriteCondition (mixed $condition, int $index = 0): Tuple
|
private function WriteCondition (DBDriver $driver, mixed $condition, int $index = 0): Tuple
|
||||||
{
|
{
|
||||||
// Проверяем, является ли условие объектом класса Condition
|
// Проверяем, является ли условие объектом класса Condition
|
||||||
if ($condition instanceof Condition)
|
if ($condition instanceof Condition)
|
||||||
// - если да, то возвращаем его значение
|
// - если да, то возвращаем его значение
|
||||||
return $condition->Get($index);
|
return $condition->Get($driver, $index);
|
||||||
|
|
||||||
// Проверяем, является ли условие объектом класса ConditionGroup
|
// Проверяем, является ли условие объектом класса ConditionGroup
|
||||||
if ($condition instanceof ConditionGroup)
|
if ($condition instanceof ConditionGroup)
|
||||||
// - если да, то возвращаем его значения
|
// - если да, то возвращаем его значения
|
||||||
return $condition->GetConditions($index);
|
return $condition->GetConditions($driver, $index);
|
||||||
|
|
||||||
// Если условие не является ни классом Condition, ни классом ConditionGroup, то это ошибка. Выбрасываем
|
// Если условие не является ни классом Condition, ни классом ConditionGroup, то это ошибка. Выбрасываем
|
||||||
// исключение.
|
// исключение.
|
||||||
|
@@ -36,16 +36,6 @@
|
|||||||
*/
|
*/
|
||||||
private ?PDO $DataBaseHandle;
|
private ?PDO $DataBaseHandle;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string $DBSignOpen Символ открытия для подстановки в запросы к базе.
|
|
||||||
*/
|
|
||||||
private string $DBSignOpen;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string $DBSignСlose Символ закрытия для подстановки в запросы к базе.
|
|
||||||
*/
|
|
||||||
private string $DBSignClose;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Closure $OnException Обработчик исключений. Анонимная функция формата:
|
* @var Closure $OnException Обработчик исключений. Анонимная функция формата:
|
||||||
*
|
*
|
||||||
@@ -96,21 +86,6 @@
|
|||||||
DBDriver::SQLite => "sqlite:$dbname"
|
DBDriver::SQLite => "sqlite:$dbname"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Задаю DBSign
|
|
||||||
// - Open
|
|
||||||
$this->DBSignOpen = match ($this->Config->Driver) {
|
|
||||||
DBDriver::MySQL, DBDriver::SQLite => '`',
|
|
||||||
DBDriver::MSSQL => '[',
|
|
||||||
DBDriver::PostgreSQL, DBDriver::OracleDB => '"'
|
|
||||||
};
|
|
||||||
|
|
||||||
// - Close
|
|
||||||
$this->DBSignClose = match ($this->Config->Driver) {
|
|
||||||
DBDriver::MySQL, DBDriver::SQLite => '`',
|
|
||||||
DBDriver::MSSQL => ']',
|
|
||||||
DBDriver::PostgreSQL, DBDriver::OracleDB => '"'
|
|
||||||
};
|
|
||||||
|
|
||||||
// Создаю объект для связи с базой данных
|
// Создаю объект для связи с базой данных
|
||||||
$this->DataBaseHandle = new PDO($dsn, username: $user, password: $password);
|
$this->DataBaseHandle = new PDO($dsn, username: $user, password: $password);
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace goodboyalex\php_db_components_pack\enums;
|
namespace goodboyalex\php_db_components_pack\enums;
|
||||||
|
|
||||||
|
use goodboyalex\php_components_pack\classes\Tuple;
|
||||||
use goodboyalex\php_components_pack\traits\EnumExtensionsTrait;
|
use goodboyalex\php_components_pack\traits\EnumExtensionsTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,4 +43,20 @@
|
|||||||
* SQLite
|
* SQLite
|
||||||
*/
|
*/
|
||||||
case SQLite = 4;
|
case SQLite = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получить знаки открытия/закрытия полей для СУБД.
|
||||||
|
*
|
||||||
|
* @param DBDriver $driver Драйвер СУБД.
|
||||||
|
*
|
||||||
|
* @return Tuple Возвращает кортеж [знак открытия, знак закрытия].
|
||||||
|
*/
|
||||||
|
public static function GetSigns (DBDriver $driver): Tuple
|
||||||
|
{
|
||||||
|
return match ($driver) {
|
||||||
|
DBDriver::MySQL, DBDriver::SQLite => new Tuple('`', '`'),
|
||||||
|
DBDriver::MSSQL => new Tuple('[', ']'),
|
||||||
|
DBDriver::PostgreSQL, DBDriver::OracleDB => new Tuple('"', '"'),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
@@ -38,8 +38,11 @@
|
|||||||
*/
|
*/
|
||||||
[$sql_where, $params] = $where->Build();
|
[$sql_where, $params] = $where->Build();
|
||||||
|
|
||||||
|
// Подготавливаю имя таблицы
|
||||||
|
$table = $this->PrepareTableName($table);
|
||||||
|
|
||||||
// Создаю запрос
|
// Создаю запрос
|
||||||
$sql = "SELECT COUNT(*) FROM $this->DBSignOpen$table$this->DBSignClose";
|
$sql = "SELECT COUNT(*) FROM $table";
|
||||||
|
|
||||||
// Если заданы where-параметры
|
// Если заданы where-параметры
|
||||||
if ($where->Count() > 0)
|
if ($where->Count() > 0)
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
use goodboyalex\php_db_components_pack\enums\DBDriver;
|
use goodboyalex\php_db_components_pack\enums\DBDriver;
|
||||||
use goodboyalex\php_db_components_pack\enums\DBOperation;
|
use goodboyalex\php_db_components_pack\enums\DBOperation;
|
||||||
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
|
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
|
||||||
|
use goodboyalex\php_db_components_pack\models\DBItemProperty;
|
||||||
use PDO;
|
use PDO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,7 +37,7 @@
|
|||||||
public function Insert (string $table, IDBItem $row): mixed
|
public function Insert (string $table, IDBItem $row): mixed
|
||||||
{
|
{
|
||||||
// Подготавливаю запрос
|
// Подготавливаю запрос
|
||||||
[$sql, $params] = $this->PrepareInsertSQL($table, $row);
|
[$sql, $params, $primaryKeyValue] = $this->PrepareInsertSQL($table, $row);
|
||||||
|
|
||||||
// Выполняю запрос
|
// Выполняю запрос
|
||||||
$count = $this->Execute($sql, $params);
|
$count = $this->Execute($sql, $params);
|
||||||
@@ -48,7 +49,7 @@
|
|||||||
|
|
||||||
// Задаю переменную для последнего id
|
// Задаю переменную для последнего id
|
||||||
$lastId = match ($this->Config->Driver) {
|
$lastId = match ($this->Config->Driver) {
|
||||||
DBDriver::MSSQL => $this->DataBaseHandle->query('SELECT SCOPE_IDENTITY()')->fetchColumn(),
|
DBDriver::MSSQL => $this->Query('SELECT SCOPE_IDENTITY() AS last_inserted_id;')['last_inserted_id'],
|
||||||
DBDriver::MySQL, DBDriver::SQLite => $this->DataBaseHandle->lastInsertId(),
|
DBDriver::MySQL, DBDriver::SQLite => $this->DataBaseHandle->lastInsertId(),
|
||||||
DBDriver::PostgreSQL, DBDriver::OracleDB => $this->DataBaseHandle->lastInsertId('sequence_name')
|
DBDriver::PostgreSQL, DBDriver::OracleDB => $this->DataBaseHandle->lastInsertId('sequence_name')
|
||||||
};
|
};
|
||||||
@@ -58,6 +59,11 @@
|
|||||||
// - то вывожу просто true
|
// - то вывожу просто true
|
||||||
$lastId = true;
|
$lastId = true;
|
||||||
|
|
||||||
|
// Если id не генерировался
|
||||||
|
if ($lastId === null)
|
||||||
|
// - то вывожу -1
|
||||||
|
$lastId = $primaryKeyValue !== "NULL" ? $primaryKeyValue : true;
|
||||||
|
|
||||||
// Вывожу последний id
|
// Вывожу последний id
|
||||||
return $lastId;
|
return $lastId;
|
||||||
}
|
}
|
||||||
@@ -106,12 +112,35 @@
|
|||||||
* @param string $table Имя таблицы.
|
* @param string $table Имя таблицы.
|
||||||
* @param IDBItem $row Элемент.
|
* @param IDBItem $row Элемент.
|
||||||
*
|
*
|
||||||
* @return Tuple Возвращает [запрос, параметры запроса].
|
* @return Tuple Возвращает [запрос, параметры запроса, значение первичного ключа].
|
||||||
*/
|
*/
|
||||||
private function PrepareInsertSQL (string $table, IDBItem $row): Tuple
|
private function PrepareInsertSQL (string $table, IDBItem $row): Tuple
|
||||||
{
|
{
|
||||||
// Подготавливаю массив параметров
|
// Подготавливаю массив параметров
|
||||||
$params = $this->PrepareParamsArray(source: $row, operation: DBOperation::Insert);
|
$params = [];
|
||||||
|
|
||||||
|
// Получаю массив свойств
|
||||||
|
$properties = self::GetProperties($row, DBOperation::Insert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Для каждого свойства...
|
||||||
|
*
|
||||||
|
* @var DBItemProperty $property Свойство.
|
||||||
|
*/
|
||||||
|
foreach ($properties as $property) {
|
||||||
|
// - пропускаю игнорируемые поля
|
||||||
|
if ($property->IsIgnored)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// - получаю значение имени поля
|
||||||
|
$fieldName = $property->Column->Name;
|
||||||
|
|
||||||
|
// - преобразую тип
|
||||||
|
$value = call_user_func($property->ConvertToDB, $property->Value);
|
||||||
|
|
||||||
|
// - добавляю в массив
|
||||||
|
$params[$fieldName] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
// Получаю ключи параметров
|
// Получаю ключи параметров
|
||||||
$keys = array_keys($params);
|
$keys = array_keys($params);
|
||||||
@@ -140,10 +169,26 @@
|
|||||||
// Значения sql запроса
|
// Значения sql запроса
|
||||||
$sql_values = implode(', ', $keys_values);
|
$sql_values = implode(', ', $keys_values);
|
||||||
|
|
||||||
|
// Подготавливаю имя таблицы
|
||||||
|
$table = $this->PrepareTableName($table);
|
||||||
|
|
||||||
// Создаю запрос
|
// Создаю запрос
|
||||||
$sql = "INSERT INTO $this->DBSignOpen$table$this->DBSignClose ($sql_keys) VALUES ($sql_values);";
|
$sql = "INSERT INTO $table ($sql_keys) VALUES ($sql_values);";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получаю первичный ключ таблицы.
|
||||||
|
*
|
||||||
|
* @var false|DBItemProperty $key Первичный ключ таблицы.
|
||||||
|
*/
|
||||||
|
$key = $properties->GetRow(
|
||||||
|
selectCondition: fn (DBItemProperty $property): bool => $property->Column->IsPrimaryKey
|
||||||
|
);
|
||||||
|
|
||||||
|
// Передаю первичный ключ в переменную
|
||||||
|
$pKey = $key === false ? 'NULL' : $key->Value ?? "NULL";
|
||||||
|
|
||||||
|
|
||||||
// Возвращаю результат
|
// Возвращаю результат
|
||||||
return new Tuple($sql, $params);
|
return new Tuple($sql, $params, $pKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -23,6 +23,7 @@
|
|||||||
use goodboyalex\php_db_components_pack\attributes\PrimaryKey;
|
use goodboyalex\php_db_components_pack\attributes\PrimaryKey;
|
||||||
use goodboyalex\php_db_components_pack\attributes\Unique;
|
use goodboyalex\php_db_components_pack\attributes\Unique;
|
||||||
use goodboyalex\php_db_components_pack\classes\ConditionBuilder;
|
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\enums\DBOperation;
|
||||||
use goodboyalex\php_db_components_pack\enums\DBType;
|
use goodboyalex\php_db_components_pack\enums\DBType;
|
||||||
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
|
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
|
||||||
@@ -283,45 +284,6 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Подготавливает массив параметров
|
|
||||||
*
|
|
||||||
* @param IDBItem $source Объект со свойствами.
|
|
||||||
* @param DBOperation $operation Текущая операция.
|
|
||||||
*
|
|
||||||
* @return array|false Подготовленный массив параметров или false в случае ошибки
|
|
||||||
*/
|
|
||||||
private function PrepareParamsArray (IDBItem $source, DBOperation $operation): array | false
|
|
||||||
{
|
|
||||||
$result = [];
|
|
||||||
|
|
||||||
// Получаю массив свойств
|
|
||||||
$properties = self::GetProperties($source, $operation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Для каждого свойства...
|
|
||||||
*
|
|
||||||
* @var DBItemProperty $property Свойство.
|
|
||||||
*/
|
|
||||||
foreach ($properties as $property) {
|
|
||||||
// - пропускаю игнорируемые поля
|
|
||||||
if ($property->IsIgnored)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// - получаю значение имени поля
|
|
||||||
$fieldName = $property->Column->Name;
|
|
||||||
|
|
||||||
// - преобразую тип
|
|
||||||
$value = call_user_func($property->ConvertToDB, $property->Value);
|
|
||||||
|
|
||||||
// - добавляю в массив
|
|
||||||
$result[$fieldName] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Возвращаю результат
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Восстанавливает объект из БД.
|
* Восстанавливает объект из БД.
|
||||||
*
|
*
|
||||||
@@ -492,4 +454,20 @@
|
|||||||
// Возвращаю запрос
|
// Возвращаю запрос
|
||||||
return $sql;
|
return $sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Генерирует имя таблицы для использования в запросах.
|
||||||
|
*
|
||||||
|
* @param string $table Имя таблицы.
|
||||||
|
*
|
||||||
|
* @return string Готовое имя таблицы для использования в запросах.
|
||||||
|
*/
|
||||||
|
private function PrepareTableName (string $table): string
|
||||||
|
{
|
||||||
|
return match ($this->Config->Driver) {
|
||||||
|
DBDriver::MySQL, DBDriver::SQLite, DBDriver::OracleDB, DBDriver::PostgreSQL => $this->DBSignOpen
|
||||||
|
. $table . $this->DBSignClose,
|
||||||
|
DBDriver::MSSQL => "[dbo].[$table]"
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user