108 lines
3.6 KiB
PHP
108 lines
3.6 KiB
PHP
<?php
|
||
|
||
namespace dominion\db;
|
||
|
||
use Yii;
|
||
|
||
/**
|
||
* Обертка над стандартным классом \yii\db\Query
|
||
* Описывает общие методы для работы, которые могут понадобиться при запросах
|
||
*/
|
||
class Query extends \yii\db\Query
|
||
{
|
||
|
||
/**
|
||
* Множественное обновление записей в таблице по первичному ключу id
|
||
* @param string $table Название таблицы бд
|
||
* @param array $data Массив данных для обновления
|
||
* Например:
|
||
* [
|
||
* 23 => ['name' => 'обновленное название 23', 'description' => 'обновленное описание 23'],
|
||
* 24 => ['name' => 'обновленное название 24', 'description' => 'обновленное описание 24'],
|
||
* ]
|
||
* Обновит поля name и description у полей с id=23 и id=24 одним запросом
|
||
* @return int Количество обновленных записей
|
||
*/
|
||
public function batchUpdate($table, $data)
|
||
{
|
||
$fields = [];
|
||
$columns = [];
|
||
$rows = [];
|
||
foreach ($data as $id => $values)
|
||
{
|
||
if (empty($columns))
|
||
{
|
||
$fields = array_keys($values);
|
||
$columns = array_merge(['id'], $fields);
|
||
}
|
||
|
||
$row = [$id];
|
||
foreach ($values as $value)
|
||
{
|
||
$row[] = $value;
|
||
}
|
||
|
||
$rows[] = $row;
|
||
}
|
||
|
||
$sql = Yii::$app->db->getQueryBuilder()->batchInsert($table, $columns, $rows);
|
||
$update = [];
|
||
foreach ($fields as $field)
|
||
{
|
||
$field = Yii::$app->db->quoteColumnName($field);
|
||
$update[] = $field . ' = VALUES(' . $field . ')';
|
||
}
|
||
|
||
if (!empty($update))
|
||
{
|
||
$sql .= ' ON DUPLICATE KEY UPDATE ' . implode(',', $update);
|
||
}
|
||
\Yii::beginProfile('batchUpdate_' . $table);
|
||
$result = Yii::$app->db->createCommand($sql)->execute();
|
||
\Yii::endProfile('batchUpdate_' . $table);
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Множественное добавление записей в таблицу
|
||
* @param string $table Название таблицы бд
|
||
* @param array $data Массив данных для добавления
|
||
* Например:
|
||
* [
|
||
* ['name' => 'Название 1', 'description' => 'Описание 1'],
|
||
* ['name' => 'Название 2', 'description' => 'Описание 2'],
|
||
* ]
|
||
* Добавит две записи с заполненными полями name и description одним запросом
|
||
* Если в массиве больще 5000 элементов, то будет несколько запросов с добавлением по 5000 элементов в одном запросе
|
||
*/
|
||
public function batchInsert($table, $data)
|
||
{
|
||
$columns = [];
|
||
$rows = [];
|
||
foreach ($data as $values)
|
||
{
|
||
if (empty($columns))
|
||
{
|
||
$columns = array_keys($values);
|
||
}
|
||
|
||
$row = [];
|
||
foreach ($values as $value)
|
||
{
|
||
$row[] = $value;
|
||
}
|
||
|
||
$rows[] = $row;
|
||
}
|
||
|
||
$limit = 5000;
|
||
$count = (int) floor(count($rows) / $limit);
|
||
for ($i = 0; $i <= $count; $i++)
|
||
{
|
||
$partRows = array_slice($rows, $i * $limit, $limit);
|
||
Yii::$app->db->createCommand()->batchInsert($table, $columns, $partRows)->execute();
|
||
}
|
||
}
|
||
|
||
}
|