This commit is contained in:
2025-08-01 18:29:11 +03:00
parent 2f3dd81d0a
commit ccdcc3e047
10 changed files with 1226 additions and 51 deletions

View File

@@ -0,0 +1,125 @@
<?php
namespace goodboyalex\php_db_components_pack\traits\ConditionBuilder;
use goodboyalex\php_db_components_pack\classes\Condition;
use goodboyalex\php_db_components_pack\classes\ConditionBuilder;
/**
* Трейт для построителя условий запроса выборки, отвечающий за задание цепочки условий.
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0
* @since 1.0
*/
trait ConditionBuilderConditionsSet
{
/**
* Добавляет условие равенства.
*
* @param string $column Имя колонки.
* @param mixed $value Значение.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function WhereEquals (string $column, mixed $value): ConditionBuilder
{
return $this->AddCondition($column, '=', $value);
}
/**
* Добавляет условие не равенства.
*
* @param string $column Имя колонки.
* @param mixed $value Значение.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function WhereNotEquals (string $column, mixed $value): ConditionBuilder
{
return $this->AddCondition($column, '<>', $value);
}
/**
* Добавляет условие больше.
*
* @param string $column Имя колонки.
* @param mixed $value Значение.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function WhereGreaterThan (string $column, mixed $value): ConditionBuilder
{
return $this->AddCondition($column, '>', $value);
}
/**
* Добавляет условие меньше.
*
* @param string $column Имя колонки.
* @param mixed $value Значение.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function WhereLessThan (string $column, mixed $value): ConditionBuilder
{
return $this->AddCondition($column, '<', $value);
}
/**
* Добавляет условие больше или равно.
*
* @param string $column Имя колонки.
* @param mixed $value Значение.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function WhereGreaterThanEqual (string $column, mixed $value): ConditionBuilder
{
return $this->AddCondition($column, '>=', $value);
}
/**
* Добавляет условие меньше или равно.
*
* @param string $column Имя колонки.
* @param mixed $value Значение.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function WhereLessThanEqual (string $column, mixed $value): ConditionBuilder
{
return $this->AddCondition($column, '<=', $value);
}
/**
* Добавляет условие.
*
* @param string $column Имя колонки.
* @param string $operator Оператор (<=, <, =, >, >=).
* @param mixed $value Значение.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
private function AddCondition (string $column, string $operator, mixed $value): ConditionBuilder
{
return $this->AddConditionA(new Condition($column, $operator, $value));
}
/**
* Добавляет условие.
*
* @param Condition $condition Условие.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
private function AddConditionA (Condition $condition): ConditionBuilder
{
// Добавляем условие
$this->Conditions[] = $condition;
// Возвращаем объект
return $this;
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace goodboyalex\php_db_components_pack\traits\ConditionBuilder;
use goodboyalex\php_db_components_pack\classes\Condition;
use goodboyalex\php_db_components_pack\classes\ConditionBuilder;
/**
* Трейт для построителя условий запроса выборки, отвечающий за задание логических операторов в цепочку условий.
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0
* @since 1.0
*/
trait ConditionBuilderLogicalOperationSet
{
/**
* Добавляет логический оператор.
*
* @param string $operator Оператор.
*
* @return false|ConditionBuilder Возвращает объект для цепочек или <code>false</code>, если оператор не верный.
*/
public function AddLogicalOperator (string $operator): false|ConditionBuilder
{
// Подготавливаем оператор
$operator = self::PrepareLogicalOperator($operator);
// Проверяем оператор, и если он не верный
if ($operator === false)
// - то возвращаем false
return false;
// Добавляем условие
$this->Conditions[] = $operator;
// Возвращаем объект
return $this;
}
/**
* Добавляет логическое И.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function And (): ConditionBuilder
{
// Добавляем условие
$this->Conditions[] = Condition::LOGIC_AND;
// Возвращаем объект
return $this;
}
/**
* Добавляет логическое ИЛИ.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function Or (): ConditionBuilder
{
// Добавляем условие
$this->Conditions[] = Condition::LOGIC_OR;
// Возвращаем объект
return $this;
}
/**
* Добавляет логическое НЕ.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function Not (): ConditionBuilder
{
// Добавляем условие
$this->Conditions[] = Condition::LOGIC_NOT;
// Возвращаем объект
return $this;
}
/**
* Добавляет логическое ИСКЛЮЧАЮЩЕЕ ИЛИ.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function Xor (): ConditionBuilder
{
// Добавляем условие
$this->Conditions[] = Condition::LOGIC_XOR;
// Возвращаем объект
return $this;
}
/**
* Добавляет логическое НЕ И.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function Nand (): ConditionBuilder
{
// Добавляем условие
$this->Conditions[] = Condition::LOGIC_NAND;
// Возвращаем объект
return $this;
}
/**
* Добавляет логическое НЕ ИЛИ.
*
* @return ConditionBuilder Возвращает объект для цепочек.
*/
public function Nor (): ConditionBuilder
{
// Добавляем условие
$this->Conditions[] = Condition::LOGIC_NOR;
// Возвращаем объект
return $this;
}
}

View File

@@ -0,0 +1,121 @@
<?php
/**
* @noinspection SqlNoDataSourceInspection
*/
namespace goodboyalex\php_db_components_pack\traits\Database;
use Exception;
use goodboyalex\php_db_components_pack\classes\ConditionBuilder;
use PDO;
/**
* Трейт для работы с получением данных из базы данных.
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0
* @since 1.0
* @see PDO
*/
trait DatabaseGet
{
/**
* Получает первую строку в массиве данных, удовлетворяющую выборке
*
* @param string $table Имя таблицы
* @param array $columns Колонки, которые нужно включить в запрос
* @param ConditionBuilder $where Параметры выборки
*
* @return false|array Строка в формате массива или false в случае ошибки
*
* @see Query
* @see QueryFirst
* @see QueryLast
* @see QueryScalar
* @see GetRows
*/
public function GetRowColumns (string $table, array $columns, ConditionBuilder $where): false|array
{
// Задаю массив параметров
$params = [];
// Получаю SQL запрос
$sql = $this->PrepareSQLForRowsQuery($table, $columns, $where, $params);
// Получаю строку на основании запроса
return $this->QueryScalar($sql, $params);
}
/**
* Извлекает одну запись из базы данных и создает соответствующий объект класса
*
* @param string $table Название таблицы
* @param ConditionBuilder $condition Условия выборки
* @param string $className Полное имя класса, реализуемого интерфейсом IDBItem
*
* @return object Заполненный объект класса
*/
public function GetRow (string $table, ConditionBuilder $condition, string $className): object
{
try {
// Строим условие WHERE для SQL-запроса
$whereClause = $condition->Build();
// Формируем SQL-запрос
$sql = "SELECT * FROM $table WHERE $whereClause LIMIT 1;";
// Подготовленное выражение
$stmt = $this->pdo->prepare($sql);
// Присваивание параметров
foreach ($params as $col => $val) {
$stmt->bindParam(":$col", $val);
}
// Выполнение запроса
$stmt->execute();
// Получаем первую строку результатов
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) {
throw new Exception("No data found with the given conditions.");
}
// Создание объекта желаемого класса
$obj = new $className();
// Заполняем поля объекта соответствующими значениями из БД
foreach ($row as $column => $value) {
// Анализируем свойства класса и находим соответствующее свойство
$properties = (new ReflectionClass($obj))->getProperties(ReflectionProperty::IS_PUBLIC);
foreach ($properties as $prop) {
// Проверяем, соответствует ли данное свойство указанному полю
$attributes = $prop->getAttributes(FieldName::class);
if ($attributes && $attributes[0]->getArguments()['name'] === $column) {
// Применяем процедуру конвертации (если указана)
$convertAttrs = $prop->getAttributes(ConvertToDB::class);
if ($convertAttrs) {
$converter = $convertAttrs[0]->getArguments()['fromDb'];
if ($converter !== null) {
$value = call_user_func($converter, $value);
}
}
// Устанавливаем значение свойства
$obj->{$prop->getName()} = $value;
break;
}
}
}
return $obj;
}
catch (\PDOException|\Exception $e) {
error_log("Error fetching data: " . $e->getMessage());
return null;
}
}
}

View File

@@ -8,10 +8,10 @@
use Exception;
use goodboyalex\php_components_pack\classes\Tuple;
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;
use PDOException;
/**
* Трейт для работы со вставкой строк в базу данных.
@@ -46,23 +46,17 @@
// - то и общий результат - false
return false;
$lastId = -1;
// Задаю переменную для последнего id
$lastId = match ($this->Config->Driver) {
DBDriver::MSSQL => $this->DataBaseHandle->query('SELECT SCOPE_IDENTITY()')->fetchColumn(),
DBDriver::MySQL, DBDriver::SQLite => $this->DataBaseHandle->lastInsertId(),
DBDriver::PostgreSQL, DBDriver::OracleDB => $this->DataBaseHandle->lastInsertId('sequence_name')
};
try {
// Получаю последний id этой записи
$lastIdResult = $this->DataBaseHandle->lastInsertId();
// Если получение неудачное
if ($lastIdResult === false)
// - то вывожу -1
return $lastId;
// Устанавливаю последний id
$lastId = $lastIdResult;
}
catch (PDOException $e) {
$this->HandleException($e);
}
// Если id не получен
if ($lastId === false)
// - то вывожу просто true
$lastId = true;
// Вывожу последний id
return $lastId;
@@ -72,33 +66,38 @@
* Вставляет несколько строк в базу данных.
*
* @param string $table Имя таблицы.
* @param array $options Параметры.
* @param IDBItem ...$sources Модели или классы, реализующие интерфейс IDBItem, для вставки.
*
* @return void
* @return false|array Возвращает массив id созданных записей и <code>false</code>, если ошибка.
*/
public function InsertMany (string $table, array $options, IDBItem ...$sources): void
public function InsertMany (string $table, IDBItem ...$sources): false|array
{
// Инициализирую транзакцию
$this->InitTransaction();
// Подготавливаю массив последних id
$result = [];
try {
// Для каждого источника
foreach ($sources as $source)
// - вставляю строку
$this->Insert($table, $source, $options);
$result[] = $this->Insert($table, $source);
// Если вставка успешна, то подтверждаю транзакцию
$this->Commit();
}
catch (Exception $exception) {
catch (Exception) {
// - если ошибка, то откатываю транзакцию
$this->RollBack();
// - и вывожу ошибку
$this->HandleException($exception);
return false;
}
// Вывожу результат
return $result;
}
/**
@@ -106,7 +105,6 @@
*
* @param string $table Имя таблицы.
* @param IDBItem $row Элемент.
* @param array $options Параметры.
*
* @return Tuple Возвращает [запрос, параметры запроса].
*/

View File

@@ -10,6 +10,7 @@
use goodboyalex\php_db_components_pack\attributes\ConvertToDB;
use goodboyalex\php_db_components_pack\attributes\FieldName;
use goodboyalex\php_db_components_pack\attributes\IgnoredInDB;
use goodboyalex\php_db_components_pack\classes\ConditionBuilder;
use goodboyalex\php_db_components_pack\enums\DBOperation;
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
use PDO;
@@ -235,7 +236,7 @@
*
* @return string SQL-запрос
*/
private function PrepareSQLForRowsQuery (string $table, array $columns = [], array $where = [],
private function PrepareSQLForRowsQuery (string $table, array $columns, ConditionBuilder $where,
array &$params = []): string
{
// Очищаю параметры