20250729
This commit is contained in:
parent
e4c8d7e6c8
commit
8436569ce5
70
.idea/codeStyles/Project.xml
generated
Normal file
70
.idea/codeStyles/Project.xml
generated
Normal file
@ -0,0 +1,70 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<PHPCodeStyleSettings>
|
||||
<option name="INDENT_CODE_IN_PHP_TAGS" value="true" />
|
||||
<option name="PHPDOC_BLANK_LINE_BEFORE_TAGS" value="true" />
|
||||
<option name="PHPDOC_BLANK_LINES_AROUND_PARAMETERS" value="true" />
|
||||
<option name="PHPDOC_WRAP_LONG_LINES" value="true" />
|
||||
<option name="ANONYMOUS_BRACE_STYLE" value="5" />
|
||||
<option name="LINK_WEIGHT" value="11" />
|
||||
<option name="AUTHOR_WEIGHT" value="3" />
|
||||
<option name="USES_WEIGHT" value="9" />
|
||||
<option name="VERSION_WEIGHT" value="5" />
|
||||
<option name="COPYRIGHT_WEIGHT" value="7" />
|
||||
<option name="PACKAGE_WEIGHT" value="4" />
|
||||
<option name="SEE_WEIGHT" value="8" />
|
||||
<option name="SINCE_WEIGHT" value="6" />
|
||||
<option name="TODO_WEIGHT" value="10" />
|
||||
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
|
||||
<option name="LOWER_CASE_NULL_CONST" value="true" />
|
||||
<option name="ELSE_IF_STYLE" value="SEPARATE" />
|
||||
<option name="SPACE_BEFORE_SHORT_CLOSURE_LEFT_PARENTHESIS" value="true" />
|
||||
<option name="FORCE_SHORT_DECLARATION_ARRAY_STYLE" value="true" />
|
||||
<option name="SPACE_AROUND_ASSIGNMENT_IN_DECLARE" value="true" />
|
||||
<option name="FORCE_EMPTY_CLASSES_IN_ONE_LINE" value="true" />
|
||||
<option name="MULTILINE_CLOSURE_LAMBDA_ON_NEW_LINE" value="true" />
|
||||
<option name="ATTRIBUTES_WRAP" value="1" />
|
||||
<option name="PARAMETERS_ATTRIBUTES_WRAP" value="1" />
|
||||
</PHPCodeStyleSettings>
|
||||
<codeStyleSettings language="PHP">
|
||||
<option name="LAMBDA_BRACE_STYLE" value="5" />
|
||||
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||
<option name="WHILE_ON_NEW_LINE" value="true" />
|
||||
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||
<option name="SPECIAL_ELSE_IF_TREATMENT" value="true" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
|
||||
<option name="SPACE_BEFORE_METHOD_PARENTHESES" value="true" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
|
||||
<option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
|
||||
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||
<option name="WRAP_ON_TYPING" value="1" />
|
||||
<indentOptions>
|
||||
<option name="KEEP_INDENTS_ON_EMPTY_LINES" value="true" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<groups>
|
||||
<group>
|
||||
<type>GETTERS_AND_SETTERS</type>
|
||||
<order>KEEP</order>
|
||||
</group>
|
||||
<group>
|
||||
<type>OVERRIDDEN_METHODS</type>
|
||||
<order>KEEP</order>
|
||||
</group>
|
||||
</groups>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
File diff suppressed because it is too large
Load Diff
32
sources/interfaces/IDBItem.php
Normal file
32
sources/interfaces/IDBItem.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace goodboyalex\php_db_components_pack\interfaces;
|
||||
|
||||
/**
|
||||
* Интерфейс моделей и классов, хранящие свойства в SQL базе данных.
|
||||
*
|
||||
* @author Александр Бабаев
|
||||
* @package php_db_components_pack
|
||||
* @version 1.0.0
|
||||
* @since 1.0
|
||||
*/
|
||||
interface IDBItem
|
||||
{
|
||||
/**
|
||||
* Вывод параметров добавления/обновления данных в базу данных.
|
||||
*
|
||||
* @param bool $withId Нужно ли добавлять Id в массив
|
||||
*
|
||||
* @return array Массив параметров
|
||||
*/
|
||||
public function ToSQL (bool $withId = true): array;
|
||||
|
||||
/**
|
||||
* Преобразование данных из базы данных в модель, класс.
|
||||
*
|
||||
* @param array $sqlData Данные из базы данных
|
||||
*
|
||||
* @return self Класс модели с заполненными данными из базы данных
|
||||
*/
|
||||
public function FromSQL (array $sqlData): self;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace goodboyalex\php_db_components_pack\interfaces;
|
||||
|
||||
/**
|
||||
* Интерфейс поддержки моделей и классов, реализующих хранение свойств в SQL базе данных.
|
||||
*
|
||||
* @author Александр Бабаев
|
||||
* @package php_db_components_pack
|
||||
* @version 1.0.0
|
||||
* @since 1.0
|
||||
*/
|
||||
interface IStoredAtSQL
|
||||
{
|
||||
/**
|
||||
* Вывод параметров добавления/обновления данных в базу данных.
|
||||
*
|
||||
* @param bool $withId Нужно ли добавлять Id в массив
|
||||
*
|
||||
* @return array Массив параметров
|
||||
*/
|
||||
public function ToSQL (bool $withId = true): array;
|
||||
|
||||
/**
|
||||
* Преобразование данных из базы данных в модель, класс.
|
||||
*
|
||||
* @param array $sqlData Данные из базы данных
|
||||
*
|
||||
* @return self Класс модели с заполненными данными из базы данных
|
||||
*/
|
||||
public function FromSQL (array $sqlData): self;
|
||||
}
|
153
sources/traits/Database/DatabaseInsert.php
Normal file
153
sources/traits/Database/DatabaseInsert.php
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @noinspection SqlNoDataSourceInspection
|
||||
*/
|
||||
|
||||
namespace goodboyalex\php_db_components_pack\traits\Database;
|
||||
|
||||
use Exception;
|
||||
use goodboyalex\php_components_pack\classes\Tuple;
|
||||
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
|
||||
use PDO;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* Трейт для работы со вставкой строк в базу данных.
|
||||
*
|
||||
* @author Александр Бабаев
|
||||
* @package php_components_pack
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @see PDO
|
||||
*/
|
||||
trait DatabaseInsert
|
||||
{
|
||||
/**
|
||||
* Вставляет строку в базу данных.
|
||||
*
|
||||
* @param string $table Имя таблицы.
|
||||
* @param IDBItem $row Модель или класс, реализующий интерфейс IDBItem, для вставки.
|
||||
* @param array $options Массив дополнительных параметров. Может содержать следующие ключи:
|
||||
*
|
||||
* - <code>ignore: array</code> - игнорировать перечисленные поля. Когда массив пуст, то ничего
|
||||
* игнорироваться не будет. По умолчанию - пустой массив.
|
||||
* - <code>allow: array</code> - включать только перечисленные поля. Когда массив пуст, то все поля будут
|
||||
* включены. По умолчанию - пустой массив.
|
||||
*
|
||||
* @return string|false В случае успеха выведет: id созданной записи, -1, если запись создана, но id не получен
|
||||
* (глюк?) и false, если ошибка
|
||||
*/
|
||||
public function Insert (string $table, IDBItem $row, array $options = []): string|false
|
||||
{
|
||||
// Подготавливаю запрос
|
||||
[$sql, $params] = $this->PrepareInsertSQL($table, $row, $options);
|
||||
|
||||
// Выполняю запрос
|
||||
$count = $this->Execute($sql, $params);
|
||||
|
||||
// Если результат - false или добавлена не одна запись
|
||||
if (($count === false) || ($count < 1) || ($count > 1))
|
||||
// - то и общий результат - false
|
||||
return false;
|
||||
|
||||
$lastId = -1;
|
||||
|
||||
try {
|
||||
// Получаю последний id этой записи
|
||||
$lastIdResult = $this->DataBaseHandle->lastInsertId();
|
||||
|
||||
// Если получение неудачное
|
||||
if ($lastIdResult === false)
|
||||
// - то вывожу -1
|
||||
return $lastId;
|
||||
|
||||
// Устанавливаю последний id
|
||||
$lastId = $lastIdResult;
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$this->HandleException($e);
|
||||
}
|
||||
|
||||
// Вывожу последний id
|
||||
return $lastId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Вставляет несколько строк в базу данных.
|
||||
*
|
||||
* @param string $table Имя таблицы.
|
||||
* @param array $options Параметры.
|
||||
* @param IDBItem ...$sources Модели или классы, реализующие интерфейс IDBItem, для вставки.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function InsertMany (string $table, array $options, IDBItem ...$sources): void
|
||||
{
|
||||
// Инициализирую транзакцию
|
||||
$this->InitTransaction();
|
||||
|
||||
try {
|
||||
|
||||
// Для каждого источника
|
||||
foreach ($sources as $source)
|
||||
// - вставляю строку
|
||||
$this->Insert($table, $source, $options);
|
||||
|
||||
// Если вставка успешна, то подтверждаю транзакцию
|
||||
$this->Commit();
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
// - если ошибка, то откатываю транзакцию
|
||||
$this->RollBack();
|
||||
|
||||
// - и вывожу ошибку
|
||||
$this->HandleException($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Подготавливает запрос для вставки строки в базу данных.
|
||||
*
|
||||
* @param string $table Имя таблицы.
|
||||
* @param IDBItem $row Элемент.
|
||||
* @param array $options Параметры.
|
||||
*
|
||||
* @return Tuple Возвращает [запрос, параметры запроса].
|
||||
*/
|
||||
private function PrepareInsertSQL (string $table, IDBItem $row, array $options = []): Tuple
|
||||
{
|
||||
// Подготавливаю массив параметров
|
||||
$params = $this->PrepareParamsArray(source: $row, options: $options);
|
||||
|
||||
// Получаю ключи параметров
|
||||
$keys = array_keys($params);
|
||||
|
||||
// Создаю результирующий массив имён ключей параметров
|
||||
$keysReal = [];
|
||||
|
||||
// Для каждого ключа параметра
|
||||
foreach ($keys as $key) {
|
||||
// - получаю его имя
|
||||
$keyResult = $key[0] == ":" ? substr($key, 1) : $key;
|
||||
|
||||
// - заключаю в кавычки
|
||||
$keyResult = "$this->DBSignOpen$keyResult$this->DBSignClose";
|
||||
|
||||
// - добавляю в результирующий массив ключей
|
||||
$keysReal[] = $keyResult;
|
||||
}
|
||||
|
||||
// Ключи sql запроса
|
||||
$sql_keys = implode(', ', $keysReal);
|
||||
|
||||
// Значения sql запроса
|
||||
$sql_values = implode(', ', $keys);
|
||||
|
||||
// Создаю запрос
|
||||
$sql = "INSERT INTO $this->DBSignOpen$table$this->DBSignClose ($sql_keys) VALUES ($sql_values);";
|
||||
|
||||
// Возвращаю результат
|
||||
return new Tuple($sql, $params);
|
||||
}
|
||||
}
|
182
sources/traits/Database/DatabaseQueryExecute.php
Normal file
182
sources/traits/Database/DatabaseQueryExecute.php
Normal file
@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @noinspection SqlNoDataSourceInspection
|
||||
*/
|
||||
|
||||
namespace goodboyalex\php_db_components_pack\traits\Database;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* Трейт для работы с запросами к базе данных типа Query и Execute.
|
||||
*
|
||||
* @author Александр Бабаев
|
||||
* @package php_components_pack
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @see PDO
|
||||
*/
|
||||
trait DatabaseQueryExecute
|
||||
{
|
||||
/**
|
||||
* Запрос строк из базы данных.
|
||||
*
|
||||
* @param string $query Запрос
|
||||
* @param array $params Параметры запроса
|
||||
*
|
||||
* @return false|array Ассоциированный массив с результатом запроса или false в случае ошибки
|
||||
*/
|
||||
public function Query (string $query, array $params = []): false|array
|
||||
{
|
||||
// По умолчанию, результат пуст
|
||||
$result = false;
|
||||
|
||||
try {
|
||||
// Подготавливаю запрос
|
||||
$STH = $this->DataBaseHandle->prepare($query, [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);
|
||||
|
||||
// Выполняю запрос
|
||||
$STH->execute($params);
|
||||
|
||||
// Указываю, что данные, которые я хочу получить, должны быть в ассоциативном массиве
|
||||
$STH->setFetchMode(PDO::FETCH_ASSOC);
|
||||
|
||||
// Получаю все данные
|
||||
$result = $STH->fetchAll();
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$this->HandleException($e);
|
||||
}
|
||||
|
||||
// Вывожу результат
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Выполняем запрос на получение одной строки (аналог QueryFirst)
|
||||
*
|
||||
* @param string $query Запрос
|
||||
* @param array $params Параметры запроса
|
||||
*
|
||||
* @return false|array Строка в формате массива или false в случае ошибки
|
||||
*
|
||||
* @see Query
|
||||
* @see QueryFirst
|
||||
* @see QueryLast
|
||||
* @see GetRow
|
||||
*/
|
||||
public function QueryScalar (string $query, array $params = []): false|array
|
||||
{
|
||||
return $this->QueryFirst($query, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Выполняем запрос на получение первой строки
|
||||
*
|
||||
* @param string $query Запрос
|
||||
* @param array $params Параметры запроса
|
||||
*
|
||||
* @return false|array Строка в формате массива или false в случае ошибки
|
||||
*
|
||||
* @see Query
|
||||
* @see QueryLast
|
||||
* @see QueryScalar
|
||||
*/
|
||||
public function QueryFirst (string $query, array $params = []): false|array
|
||||
{
|
||||
// Выполняю запрос
|
||||
$result = $this->Query($query, $params);
|
||||
|
||||
// Если в результате запроса получили ошибку или количество строк = 0
|
||||
if ($result === false || count($result) == 0)
|
||||
// - то возвращаем ошибку
|
||||
return false;
|
||||
|
||||
// Получаю первый ключ массива
|
||||
$firstKey = array_key_first($result);
|
||||
|
||||
// Возвращаем первую строку
|
||||
return $result[$firstKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* Выполняем запрос на получение последней строки
|
||||
*
|
||||
* @param string $query Запрос
|
||||
* @param array $params Параметры запроса
|
||||
*
|
||||
* @return false|array Строка в формате массива или false в случае ошибки
|
||||
*
|
||||
* @see Query
|
||||
* @see QueryFirst
|
||||
* @see QueryScalar
|
||||
*/
|
||||
public function QueryLast (string $query, array $params = []): false|array
|
||||
{
|
||||
// Выполняю запрос
|
||||
$result = $this->Query($query, $params);
|
||||
|
||||
// Если в результате запроса получили ошибку или количество строк = 0
|
||||
if ($result === false || count($result) == 0)
|
||||
// - то возвращаем ошибку
|
||||
return false;
|
||||
|
||||
// Получаю последний ключ массива
|
||||
$lastKey = array_key_last($result);
|
||||
|
||||
// Возвращаем первую строку
|
||||
return $result[$lastKey];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Выполнение запроса. Обычно используется для операций,
|
||||
* которые не возвращают никаких данных, кроме количества
|
||||
* затронутых ими записей. Например,
|
||||
*
|
||||
* <code>$db->Execute('DELETE FROM table WHERE id=1');</code>
|
||||
*
|
||||
* @param string $query Запрос
|
||||
* @param array $params Параметры запроса
|
||||
*
|
||||
* @return int|false Количество затронутых строк или false в случае ошибки
|
||||
*/
|
||||
public function Execute (string $query, array $params = []): int|false
|
||||
{
|
||||
// По умолчанию результат false
|
||||
$result = false;
|
||||
try {
|
||||
// Если параметры не заданы
|
||||
if (count($params) == 0) {
|
||||
// - то выполняю запрос
|
||||
$result = $this->DataBaseHandle->exec($query);
|
||||
}
|
||||
else {
|
||||
// - в противном случае
|
||||
// -- подготавливаю запрос
|
||||
$STH = $this->DataBaseHandle->prepare($query, [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);
|
||||
|
||||
// -- выполняю запрос
|
||||
$opResult = $STH->execute($params);
|
||||
|
||||
// -- и если выполнение успешное,
|
||||
if ($opResult)
|
||||
// --- то в результат пойдёт количество строк
|
||||
$result = $STH->rowCount();
|
||||
}
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$this->HandleException($e);
|
||||
}
|
||||
|
||||
// Если в результате false
|
||||
if ($result === false)
|
||||
// - то возвращаю его
|
||||
return false;
|
||||
|
||||
// Возвращаю результат
|
||||
return $result;
|
||||
}
|
||||
}
|
248
sources/traits/Database/DatabaseSpecial.php
Normal file
248
sources/traits/Database/DatabaseSpecial.php
Normal file
@ -0,0 +1,248 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
98
sources/traits/Database/DatabaseTransactions.php
Normal file
98
sources/traits/Database/DatabaseTransactions.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @noinspection SqlNoDataSourceInspection
|
||||
*/
|
||||
|
||||
namespace goodboyalex\php_db_components_pack\traits\Database;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* Трейт для работы с транзакциями базы данных.
|
||||
*
|
||||
* @author Александр Бабаев
|
||||
* @package php_components_pack
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @see PDO
|
||||
*/
|
||||
trait DatabaseTransactions
|
||||
{
|
||||
/**
|
||||
* Начинает транзакцию.
|
||||
*
|
||||
* @return void
|
||||
* @throws PDOException Если транзакция уже начата или не удалось начать.
|
||||
*/
|
||||
public function InitTransaction (): void
|
||||
{
|
||||
// Проверка, не находится ли текущая транзакция в процессе.
|
||||
if ($this->InTransaction())
|
||||
// - если находится, то выбрасываем исключение.
|
||||
throw new PDOException("Транзакция уже начата! / Transaction already started!");
|
||||
|
||||
// Начинаем транзакцию
|
||||
$isSuccess = $this->DataBaseHandle->beginTransaction();
|
||||
|
||||
// Если транзакция не началась
|
||||
if (!$isSuccess)
|
||||
// - то выбрасываем исключение.
|
||||
throw new PDOException("Ошибка при начале транзакции! / Transaction start error!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет, находится ли текущая транзакция в процессе.
|
||||
*
|
||||
* @return bool Результат проверки: <code>true</code> - в процессе, <code>false</code> - нет.
|
||||
*/
|
||||
public function InTransaction (): bool
|
||||
{
|
||||
return $this->DataBaseHandle->inTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Отправляет транзакцию в базу данных.
|
||||
*
|
||||
* @return void
|
||||
* @throws PDOException Если транзакция не начата или не отправлена.
|
||||
*/
|
||||
public function Commit (): void
|
||||
{
|
||||
// Проверка, не находится ли текущая транзакция в процессе
|
||||
if (!$this->InTransaction())
|
||||
// - если нет, то выбрасываем исключение.
|
||||
throw new PDOException("Транзакция не начата! / Transaction not started!");
|
||||
|
||||
// Отправляем транзакцию в базу данных
|
||||
$isSuccess = $this->DataBaseHandle->commit();
|
||||
|
||||
// Если транзакция не отправлена
|
||||
if (!$isSuccess)
|
||||
// - то выбрасываем исключение.
|
||||
throw new PDOException("Ошибка при отправке транзакции в базу данных! / Transaction send error!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Откатывает транзакцию.
|
||||
*
|
||||
* @return void
|
||||
* @throws PDOException Если транзакция не начата или не откатана.
|
||||
*/
|
||||
public function RollBack (): void
|
||||
{
|
||||
// Проверка, не находится ли текущая транзакция в процессе
|
||||
if (!$this->InTransaction())
|
||||
// - если нет, то выбрасываем исключение.
|
||||
throw new PDOException("Транзакция не начата! / Transaction not started!");
|
||||
|
||||
// Откатываем транзакцию
|
||||
$isSuccess = $this->DataBaseHandle->rollBack();
|
||||
|
||||
// Если транзакция не откатана
|
||||
if (!$isSuccess)
|
||||
// - то выбрасываем исключение.
|
||||
throw new PDOException("Ошибка при откате транзакции! / Transaction rollback error!");
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user