20250802-1
This commit is contained in:
@@ -5,7 +5,9 @@
|
||||
|
||||
namespace goodboyalex\php_db_components_pack\traits\Database;
|
||||
|
||||
use Exception;
|
||||
use goodboyalex\php_db_components_pack\classes\ConditionBuilder;
|
||||
use goodboyalex\php_db_components_pack\classes\DBItemProperty;
|
||||
use goodboyalex\php_db_components_pack\enums\DBOperation;
|
||||
use goodboyalex\php_db_components_pack\interfaces\IDBItem;
|
||||
use PDO;
|
||||
@@ -25,48 +27,128 @@
|
||||
* Заменяет данные в строке базы данных.
|
||||
*
|
||||
* @param string $table Имя таблицы.
|
||||
* @param array $set Массив данных для замены
|
||||
* @param array $where Массив условий
|
||||
* @param IDBItem $item Обновляемый объект.
|
||||
*
|
||||
* @return bool Результат выполнения
|
||||
* @return bool Результат выполнения.
|
||||
*/
|
||||
public function UpdateOld (string $table, array $set, array $where = []): bool
|
||||
public function Update (string $table, IDBItem $item): bool
|
||||
{
|
||||
// Создаю массив параметров
|
||||
$params_set = [];
|
||||
// Получаю свойства объекта
|
||||
$properties = self::GetProperties($item, DBOperation::Update);
|
||||
|
||||
// Строковая интерпретация массива для изменения
|
||||
$sql_set = "";
|
||||
// Получаю первичные ключи объекта
|
||||
$primaryKeys = $properties->GetRows(fn (DBItemProperty $property): bool => $property->IsPrimaryKey);
|
||||
|
||||
// Для каждых данных для изменения
|
||||
foreach ($set as $key => $value) {
|
||||
// - получаю ключ 100%-но без ":" в начале
|
||||
$set_key = $key[0] == ":" ? substr($key, 1) : $key;
|
||||
// Создаю условие по первичным ключам (оно же и WHERE для обновления)
|
||||
$where = new ConditionBuilder();
|
||||
|
||||
// Для каждого первичного ключа
|
||||
for ($i = 0; $i < $primaryKeys->Count(); $i++) {
|
||||
// - если это не первая итерация
|
||||
if ($i > 0)
|
||||
// -- то добавляю AND
|
||||
$where = $where->And();
|
||||
|
||||
// - добавляю префикс для 2 или более итерации
|
||||
$prefix = $sql_set == "" ? "" : ", ";
|
||||
/**
|
||||
* Получаю свойство.
|
||||
*
|
||||
* @var DBItemProperty $property Свойство.
|
||||
*/
|
||||
$property = $primaryKeys[$i];
|
||||
|
||||
// - добавляю данные в sql_set
|
||||
$sql_set .= "$prefix$this->DBSignOpen$set_key$this->DBSignClose=:$set_key";
|
||||
// - получаю ключ
|
||||
$whereKey = $property->FieldName;
|
||||
|
||||
// - добавляю данные в параметры
|
||||
$params_set[":" . $set_key] = $value;
|
||||
// - получаю значение ключа, конвертируя его в БД
|
||||
$whereValue = call_user_func($property->ConvertToDB, $property->Value);
|
||||
|
||||
// - добавляю условие в WHERE
|
||||
$where = $where->WhereEquals($whereKey, $whereValue);
|
||||
}
|
||||
|
||||
// Обработанные параметры
|
||||
$params_where = [];
|
||||
// Получаю запись из базы данных
|
||||
$dbItem = $this->GetRow($table, $where, className: get_class($item));
|
||||
|
||||
// Строковая интерпретация массива условий
|
||||
$sql_where = $this->PrepareQueryWhere(where: $where, params: $params_where);
|
||||
// Если запись не найдена
|
||||
if ($dbItem === false)
|
||||
// - то и общий результат - false
|
||||
return false;
|
||||
|
||||
// Создаю параметры
|
||||
$params = array_merge($params_set, $params_where);
|
||||
// Создаю массив параметров для обновления
|
||||
$propertyToSet = [];
|
||||
|
||||
/**
|
||||
* Для каждого свойства...
|
||||
*
|
||||
* @var DBItemProperty $property Свойство.
|
||||
*/
|
||||
foreach ($properties as $property) {
|
||||
// ... если это первичный ключ
|
||||
if ($property->IsPrimaryKey)
|
||||
// - то пропускаю его
|
||||
continue;
|
||||
|
||||
// ... если свойство игнорируется
|
||||
if ($property->IsIgnored)
|
||||
// - то пропускаю его
|
||||
continue;
|
||||
|
||||
// - получаю значение из базы данных
|
||||
$inDBValue = $dbItem->{$property->Name};
|
||||
|
||||
/**
|
||||
* Получаю результат сравнения текущего значения и значения из базы данных.
|
||||
*
|
||||
* @var bool $compareResult Результат сравнения.
|
||||
*/
|
||||
$compareResult = call_user_func($property->Compare, $inDBValue, $property->Value);
|
||||
|
||||
// - если значения не изменилось
|
||||
if ($compareResult)
|
||||
// -- то и обновлять его не нужно
|
||||
continue;
|
||||
|
||||
// - конвертирую значение в БД
|
||||
$value = call_user_func($property->ConvertToDB, $property->Value);
|
||||
|
||||
// - добавляю его в массив параметров для обновления
|
||||
$propertyToSet[$property->FieldName] = $value;
|
||||
}
|
||||
|
||||
// Создаю массив set
|
||||
$set = [];
|
||||
|
||||
// Создаю массив параметров set для обновления
|
||||
$set_params = [];
|
||||
|
||||
// Для каждого свойства для обновления
|
||||
foreach ($propertyToSet as $key => $value) {
|
||||
// - добавляю его в массив set
|
||||
$set[] = "$this->DBSignOpen$key$this->DBSignClose=:$key";
|
||||
|
||||
// - добавляю его в массив параметров set для обновления
|
||||
$set_params[":$key"] = $value;
|
||||
}
|
||||
|
||||
// Строковая интерпретация массива set
|
||||
$sql_set = count($set) > 0 ? '(' . implode(", ", $set) . ')' : "";
|
||||
|
||||
/**
|
||||
* Получаю WHERE-запрос и параметры.
|
||||
*
|
||||
* @var string $sql_where WHERE-запрос.
|
||||
* @var array $where_params Параметры WHERE-запроса.
|
||||
*/
|
||||
[$sql_where, $where_params] = $where->Build();
|
||||
|
||||
// Объединяю все параметры в один массив
|
||||
$params = array_merge($set_params, $where_params);
|
||||
|
||||
// Создаю запрос
|
||||
$sql = "UPDATE $this->DBSignOpen$table$this->DBSignClose SET $sql_set";
|
||||
|
||||
// Если заданы where-параметры
|
||||
if (count($where) > 0)
|
||||
if ($where->Count() > 0)
|
||||
// - то добавляю их
|
||||
$sql .= " WHERE $sql_where";
|
||||
|
||||
@@ -87,79 +169,45 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
public function Update (string $table, IDBItem $item): bool
|
||||
/**
|
||||
* Обновляет несколько записей в таблице базы данных.
|
||||
*
|
||||
* @param string $table Имя таблицы.
|
||||
* @param IDBItem ...$items Массив обновляемых объектов.
|
||||
*
|
||||
* @return bool Результат выполнения.
|
||||
*/
|
||||
public function UpdateMany (string $table, IDBItem ...$items): bool
|
||||
{
|
||||
$primaryKeys = $this->FindPrimaryKeys($item, DBOperation::Update);
|
||||
// Инициализирую транзакцию
|
||||
$this->InitTransaction();
|
||||
|
||||
$pk_keys = array_keys($primaryKeys);
|
||||
// Подготавливаю массив последних id
|
||||
$resultArray = [];
|
||||
|
||||
$where = new ConditionBuilder();
|
||||
|
||||
for ($i = 0; $i < count($primaryKeys); $i++) {
|
||||
if ($i > 0)
|
||||
$where = $where->And();
|
||||
try {
|
||||
// Для каждого источника
|
||||
foreach ($items as $item)
|
||||
// - вставляю строку
|
||||
$resultArray[] = $this->Update($table, $item);
|
||||
|
||||
$whereKey = $pk_keys[$i];
|
||||
// Если вставка успешна, то подтверждаю транзакцию
|
||||
$this->Commit();
|
||||
}
|
||||
catch (Exception) {
|
||||
// - если ошибка, то откатываю транзакцию
|
||||
$this->RollBack();
|
||||
|
||||
$whereValue = $primaryKeys[$whereKey];
|
||||
|
||||
$where = $where->WhereEquals($whereKey, $whereValue);
|
||||
// - и вывожу ошибку
|
||||
return false;
|
||||
}
|
||||
|
||||
$dbItem = $this->GetRow($table, $where, className: get_class($item));
|
||||
|
||||
// Создаю массив параметров
|
||||
$params_set = [];
|
||||
|
||||
// Строковая интерпретация массива для изменения
|
||||
$sql_set = "";
|
||||
|
||||
// Для каждых данных для изменения
|
||||
foreach ($set as $key => $value) {
|
||||
// - получаю ключ 100%-но без ":" в начале
|
||||
$set_key = $key[0] == ":" ? substr($key, 1) : $key;
|
||||
|
||||
// - добавляю префикс для 2 или более итерации
|
||||
$prefix = $sql_set == "" ? "" : ", ";
|
||||
|
||||
// - добавляю данные в sql_set
|
||||
$sql_set .= "$prefix$this->DBSignOpen$set_key$this->DBSignClose=:$set_key";
|
||||
|
||||
// - добавляю данные в параметры
|
||||
$params_set[":" . $set_key] = $value;
|
||||
}
|
||||
|
||||
// Обработанные параметры
|
||||
$params_where = [];
|
||||
|
||||
// Строковая интерпретация массива условий
|
||||
$sql_where = $this->PrepareQueryWhere(where: $where, params: $params_where);
|
||||
|
||||
// Создаю параметры
|
||||
$params = array_merge($params_set, $params_where);
|
||||
|
||||
// Создаю запрос
|
||||
$sql = "UPDATE $this->DBSignOpen$table$this->DBSignClose SET $sql_set";
|
||||
|
||||
// Если заданы where-параметры
|
||||
if (count($where) > 0)
|
||||
// - то добавляю их
|
||||
$sql .= " WHERE $sql_where";
|
||||
|
||||
// Выполняю запрос
|
||||
$count = $this->Execute($sql, $params);
|
||||
|
||||
// Если результат - false
|
||||
if ($count === false)
|
||||
// - то и общий результат - false
|
||||
// Если есть ошибка
|
||||
if (array_any($resultArray, fn (bool $value): bool => $value === false))
|
||||
// - то вывожу ошибку
|
||||
return false;
|
||||
|
||||
// Если изменено 0 строк
|
||||
if ($count === 0)
|
||||
// - то и общий результат - false
|
||||
return false;
|
||||
|
||||
// Вывожу результат -- успех
|
||||
// Так как мы дошли до сюда, то это успех! Вывожу результат
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user