2025-07-29 17:50:57 +03:00

248 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @noinspection SqlNoDataSourceInspection
*/
namespace goodboyalex\php_db_components_pack\traits\Database;
use Exception;
use goodboyalex\php_components_pack\exceptions\TypeException;
use goodboyalex\php_components_pack\extensions\TypeExtension;
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
use PDO;
/**
* Трейт для функций поддержки для работы с базой данных.
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0
* @since 1.0
* @see PDO
*/
trait DatabaseSpecial
{
/**
* Добавляет параметр в массив.
*
* @param array $array Массив.
* @param string $key Имя параметра.
* @param mixed $value Значение параметра.
*
* @return void
*/
private static function AddArrayItem (array &$array, string $key, mixed $value): void
{
// Если ключ параметра начинается с ":"
if ($key[0] == ":")
// - то сразу добавляем его в результирующий массив
$array[$key] = $value;
else
// - в противном случае, предварительно добавим в имя ключа ":"
$array[':' . $key] = $value;
}
/**
* Обрабатывает исключение.
*
* @param Exception $exception Исключение.
*
* @return void
*/
private function HandleException (Exception $exception): void
{
// Выбираю обработчик исключений
$onException = $this->OnException ?? fn (Exception $e) => die($e->getMessage());
// Выполняю обработчик исключений
$onException($exception);
}
/**
* Подготавливает массив параметров
*
* @param IDBItem $source Объект со свойствами.
* @param bool $withId Добавлять ли id в массив.
* @param array $options Опции.
*
* @return array|false Подготовленный массив параметров или false в случае ошибки
*/
private function PrepareParamsArray (IDBItem $source, bool $withId = true, array $options = []): array|false
{
// Создаём результирующий массив
$result = [];
// Если есть игнорируемые или разрешенные свойства
if (!(count($options['ignore']) == 0 && count($options['allow']) == 0))
// -- то для каждого игнорируемого свойства
foreach ($options['ignored'] as $ignoredProperty)
// --- и если оно есть в массиве разрешенных
if (in_array($ignoredProperty, $options['allowed']))
// ---- то исключаю его из массива разрешенных
unset($options['allowed'][array_search($ignoredProperty, $options['allowed'])]);
// Получаю массив свойств
$properties = $source->ToSQL($withId);
// Для каждого элемента массива
foreach ($properties as $name => $value) {
// - если свойство игнорируется
if (in_array($name, $options['ignored']))
// -- пропускаю
continue;
// - если свойство не разрешено
if (count($options['allowed']) > 0 && !in_array($name, $options['allowed']))
// -- пропускаю
continue;
// - если свойство является объектом
if (is_object($source->$name)) {
try {
// -- пытаюсь преобразовать его в массив
self::AddArrayItem($result, $name, json_encode(TypeExtension::ToArray($source->$name),
JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}
catch (TypeException) {
// -- если не получилось, то сериализую его
self::AddArrayItem($result, $name,
json_encode($source->$name, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}
// -- пропускаю
continue;
}
// - если свойство является массивом
if (is_array($source->$name)) {
// -- сериализую его
self::AddArrayItem($result, $name, json_encode($source->$name, JSON_UNESCAPED_UNICODE |
JSON_PRETTY_PRINT));
// -- пропускаю
continue;
}
// - иначе просто добавляю свойство в массив
self::AddArrayItem($result, $name, $source->$name);
}
// Вывожу результирующий массив
return $result;
}
/**
* Подготавливает массив столбцов для использования в базе данных
*
* @param array $columns Массив колонок.
*
* @return array Массив преобразованных колонок.
*/
private function PrepareColumn (array $columns): array
{
return array_map(function ($item)
{
// Результирующая строка
$result = "";
// Если длинна строки > 0
if (strlen($item) > 0) {
// - первый символ
$firstLetter = substr($item, 0, 1);
// - последний символ
$lastLetter = substr($item, -1);
// - если первый символ не $this->DBSignOpen
if ($firstLetter !== $this->DBSignOpen)
// -- то добавляем
$result .= $this->DBSignOpen;
// - добавляем строку
$result .= $item;
// - если последний символ не $this->DBSignClose
if ($lastLetter !== $this->DBSignClose)
// -- то добавляем
$result .= $this->DBSignClose;
}
// Возвращаем результат
return $result;
}, $columns);
}
/**
* Генерирует SQL запрос выборки строк.
*
* @param string $table Имя таблицы
* @param array $columns Колонки, которые нужно включить в запрос
* @param array $where Параметры выборки
* @param array $params Параметры и их значения
*
* @return string SQL-запрос
*/
private function PrepareSQLForRowsQuery (string $table, array $columns = [], array $where = [],
array &$params = []): string
{
// Очищаю параметры
$params = [];
// Строковая интерпретация массива условий
$sql_where = $this->PrepareQueryWhere($where, $params);
// Колонки
$sql_columns = count($columns) > 0 ? implode(', ', $this->PrepareColumn($columns)) : "*";
// Создаю запрос
$sql = "SELECT $sql_columns FROM $this->DBSignOpen$table$this->DBSignClose";
// Если заданы where-параметры
if (count($where) > 0) {
// - то добавляю их
$sql .= " WHERE $sql_where";
}
// Возвращаю запрос
return $sql;
}
/**
* Готовит выражение для WHERE-запроса
*
* @param array $where Массив условий
* @param array $params Очищенные параметры
*
* @return string Строка WHERE-запроса
*/
private function PrepareQueryWhere (array $where, array &$params): string
{
// Очищаю параметры
$params = [];
// Задаю результат
$result = "";
// Если массив условий не пуст
if (count($where) > 0) {
// - то для каждого условия
foreach ($where as $key => $value) {
// -- получаю ключ 100%-но без ":" в начале
$where_key = $key[0] == ":" ? substr($key, 1) : $key;
// -- добавляю префикс для 2 или более итерации
$prefix = $result == "" ? "" : " AND ";
// -- добавляю данные в $sql_where
$result .= $prefix . $this->DBSignOpen . $where_key . $this->DBSignClose . " = :" . $where_key;
// -- добавляю данные в параметры
$params[$where_key] = "$value";
}
}
// Вывожу результат
return $result;
}
}