From 42078ac69f543f844040a491f33ea2d0509569a5 Mon Sep 17 00:00:00 2001 From: tsurkanovm Date: Thu, 29 Oct 2015 11:06:24 +0200 Subject: [PATCH] add manual insert func to margin grup model --- backend/controllers/RgGrupController.php | 65 +++++++++++++++++++++++++++++------------------------------------ common/models/MarginsGroups.php | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 36 deletions(-) diff --git a/backend/controllers/RgGrupController.php b/backend/controllers/RgGrupController.php index 9bd647e..d380eb1 100644 --- a/backend/controllers/RgGrupController.php +++ b/backend/controllers/RgGrupController.php @@ -20,7 +20,8 @@ use yii\data\ArrayDataProvider; use yii\multiparser\DynamicFormHelper; use common\components\CustomArrayHelper; -class RgGrupController extends BaseController { +class RgGrupController extends BaseController +{ public $layout = "/column"; /** @@ -79,9 +80,9 @@ class RgGrupController extends BaseController { // не прошла валидация форма загрузки файлов $errors_str = ''; foreach ($model->getErrors() as $error) { - $errors_str .= implode( array_values($error) ); + $errors_str .= implode(array_values($error)); } - throw new \ErrorException( $errors_str ); + throw new \ErrorException($errors_str); } // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные } else if (Yii::$app->getCache()->get('parser_data')) { @@ -95,11 +96,10 @@ class RgGrupController extends BaseController { 'pageSize' => 10, ], ]); - // создадим модель на столько реквизитов сколько колонок в отпарсенном файле - $last_index = end( array_flip( $data[0] ) ); + $last_index = end(array_flip($data[0])); $header_counts = $last_index + 1; - $header_model = DynamicFormHelper::CreateDynamicModel( $header_counts ); + $header_model = DynamicFormHelper::CreateDynamicModel($header_counts); // соберем массив данных из которых будет пользователь выбирать значения в конструкторе (выпадающий список) $header_array = Margins::getHeader(); @@ -137,18 +137,18 @@ class RgGrupController extends BaseController { throw new \ErrorException('Ошибка кеша'); } - array_walk($arr, function(&$val){ - $val = '!'.$val; + array_walk($arr, function (&$val) { + $val = '!' . $val; }); // соотнесем отпарсенные данные с соответсивем полученным от пользователя // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию - $data = CustomArrayHelper::createAssocArray( $data, $arr , 'attr_' ); + $data = CustomArrayHelper::createAssocArray($data, $arr, 'attr_'); // в первой строке у нас заголовки - уберем unset($data[0]); // подготовим данные для записи в таблицу w_margins_groups - //$arr_values = []; + $arr_values = []; $group = ''; $importer_id = $configuration['importer_id']; foreach ($data as $row_data) { @@ -162,39 +162,32 @@ class RgGrupController extends BaseController { } foreach ($row_data as $key => $value) { - if($group) - $row['group'] = trim( $group ); - - $row['importer_id'] = trim( $importer_id ); - $row['margin_id'] = ltrim($key,'!'); - $row['koef'] = \Yii::$app->converter->convertTo( 'float', $value ); - - // сохраним подготовленные данные - $margins_groups = new MarginsGroups(); - $margins_groups->attributes = $row; - - if ( !$margins_groups->save() ) { - $errors_str = ''; - foreach ($margins_groups->getErrors() as $error) { - $errors_str .= implode( array_values($error) ); - } - throw new \ErrorException( $errors_str ); + if ($group) + $row['group'] = trim($group); + + $row['importer_id'] = trim($importer_id); + $row['margin_id'] = ltrim($key, '!'); + $row['koef'] = \Yii::$app->converter->convertTo('float', $value); + + $arr_values[] = $row; + } - } - Yii::$app->session->setFlash('success'); - // все прошло успешно - очищаем кеш - Yii::$app->getCache()->delete('parser_data'); - Yii::$app->getCache()->delete('parser_configuration'); + } + // сохраним подготовленные данные + MarginsGroups::ManualInsertWithUpdate( $arr_values, [ 'group','importer_id','margin_id' ] ); - if( file_exists($configuration['file_path']) ) - unlink($configuration['file_path']); - return $this->render('index', ['model' => $configuration]); + Yii::$app->session->setFlash('success', "Файл {$configuration['file']} успешно загружен"); + // все прошло успешно - очищаем кеш + Yii::$app->getCache()->delete('parser_data'); + Yii::$app->getCache()->delete('parser_configuration'); + if (file_exists($configuration['file_path'])) + unlink($configuration['file_path']); + return $this->render('index', ['model' => $configuration]); - } } diff --git a/common/models/MarginsGroups.php b/common/models/MarginsGroups.php index b08a04b..498ad97 100644 --- a/common/models/MarginsGroups.php +++ b/common/models/MarginsGroups.php @@ -74,4 +74,42 @@ class MarginsGroups extends \yii\db\ActiveRecord { return $this->hasOne(Margins::className(), ['id' => 'margin_id']); } + + /** + * вставка данных с апдейтом прямым запросом SQL + * @param $data - массив вставляемых данный, вставка будет прозводится пакетами размером указанным в константе BATCH + * @throws \yii\db\Exception + */ + //@todo - вынести все ручные инсерты в отдельный класс + public static function ManualInsertWithUpdate($data, $keys) + { + // \common\components\CustomVarDamp::dumpAndDie($data); + $table_name = self::tableName(); + $keys_arr = array_keys($data[0]); + // найдем те поля которые не являются ключами. Их нужно будет при дубляже апдейтить + $fields_arr_to_update = array_diff( $keys_arr, $keys ); + + $query_update = ' on duplicate key update '; + foreach ($fields_arr_to_update as $field) { + $query_update .= "[[{$field}]] = values([[{$field}]]),"; + } + // удалим последнюю запятую + $query_update = substr($query_update, 0, strlen($query_update) - 1); + + // запросы будем выполнять пакетами + // размер пакета установлен в константе + // разобъем массив на пакеты и будем их проходить + $data = array_chunk($data, 20); + foreach ($data as $current_batch_array) { + + //воспользуемся пакетной вставкой от фреймворка + $query_insert = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $current_batch_array)->sql; + + // добавим фрагмент с апдейтом при дубляже + $query = "{$query_insert} {$query_update}"; + // \common\components\CustomVarDamp::dumpAndDie($query); + Yii::$app->db->createCommand($query)->execute(); + + } + } } -- libgit2 0.21.4