Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/sender/lib/internals/ |
Upload File : |
<?php /** * Bitrix Framework * @package bitrix * @subpackage sender * @copyright 2001-2012 Bitrix */ namespace Bitrix\Sender\Internals; use Bitrix\Main\DB\SqlExpression; use Bitrix\Main\Localization\Loc; use Bitrix\Main\Application; use Bitrix\Main\Type\DateTime; Loc::loadMessages(__FILE__); /** * Class SqlBatch * @package Bitrix\Sender\Internals */ class SqlBatch { private const KEY_FIELDS_SEPARATOR = '#kvA3[56U?OWz16l#'; /** * Return true if batch fulled. * * @param array $list List. * @param integer $limit Batch limit. * @return array */ public static function divide(array $list, $limit = 300) { $length = count($list); if ($length < $limit) { return array($list); } $result = array(); $partsCount = ceil($length / $limit); for ($index = 0; $index < $partsCount; $index++) { $result[$index] = array_slice($list, $limit * $index, $limit); } return $result; } /** * Get string for sql-IN. * * @param array $values Values. * @return string */ public static function getInString(array $values) { $conHelper = Application::getConnection()->getSqlHelper(); foreach($values as $index => $value) { $values[$index] = $conHelper->forSql($value); } return "'" . implode("', '", $values) . "'"; } /** * Update. * * @param string $tableName Table name. * @param array $fields Fields. * @return void */ public static function update($tableName, array $fields) { $ids = []; $sets = []; foreach ($fields as $item) { if (!isset($item['ID']) || !$item['ID']) { continue; } $id = (int) $item['ID']; if ($id <= 0) { continue; } $ids[] = $id; unset($item['ID']); foreach ($item as $key => $value) { if (!isset($sets[$key])) { $sets[$key] = []; } $sets[$key][$id] = $value; } } if (count($ids) <= 0 || count($sets) <= 0) { return; } $conHelper = Application::getConnection()->getSqlHelper(); $ids = implode(',', $ids); $stringSets = []; foreach ($sets as $key => $values) { $stringSet = ""; foreach ($values as $id => $value) { $value = $conHelper->forSql($value); $stringSet .= "\nWHEN ID = $id THEN '$value'"; } $stringSet = "\n$key = CASE $stringSet ELSE $key END"; $stringSets[] = $stringSet; } $stringSets = implode(', ', $stringSets) . "\n"; $sql = "UPDATE $tableName SET $stringSets WHERE ID in ($ids)"; Application::getConnection()->query($sql); } /** * Insert. * * @param string $tableName Table name. * @param array $fields Fields. * @param array $onDuplicateUpdateFields Duplicate update fields. * @param array $primaryFields Flat array of column with unique index * * @return void */ public static function insert( string $tableName, array $fields, array $onDuplicateUpdateFields = [], array $primaryFields = [] ): void { $columnNames = self::getFieldNames($fields); if (count($columnNames) == 0) { return; } $sqlHelper = Application::getConnection()->getSqlHelper(); if (!empty($onDuplicateUpdateFields)) { $sqlUpdateFields = []; foreach ($onDuplicateUpdateFields as $field) { if (is_array($field)) { $sqlUpdateFields[$field['NAME']] = $field['VALUE']; } else { $sqlUpdateFields[$field] = new SqlExpression( 'case when ?v is null then ?#.?# else ?v end', $field, $tableName, $field, $field, ); } } $fields = self::getUniqueRowsByPrimaryFields($fields, $primaryFields); $sql = self::prepareMergeValues($tableName, $primaryFields, $fields, $sqlUpdateFields); } else { $columnNamesString = implode(", ", $columnNames); $valuesStrings = []; foreach ($fields as $row) { [$columnNamesString, $valuesString] = $sqlHelper->prepareInsert($tableName, $row); $valuesStrings[] = $valuesString; } $dataListString = implode('),(', $valuesStrings); $sql = $sqlHelper->getInsertIgnore($tableName, "($columnNamesString)", " VALUES($dataListString)"); } Application::getConnection()->query($sql); } private static function getUniqueRowsByPrimaryFields(array $rows, array $primaryFields): array { $unique = []; foreach($rows as $row) { $primaryValues = array_intersect_key($row, array_flip($primaryFields)); $key = implode(self::KEY_FIELDS_SEPARATOR, $primaryValues); $unique[$key] = $row; } return array_values($unique); } private static function getFieldNames(array &$fields) { foreach ($fields as $items) { return array_keys($items); } return array(); } /** * Returns prepared sql string for upsert multiple rows * (temporal replacement for main module method) * * @param string $tableName Table name * @param array $primaryFields Fields that can be conflicting keys (primary, unique keys) * @param array $insertRows Rows to insert [['FIELD_NAME' =>'value',...],...], Attention! use same columns in each row * @param array $updateFields Fields to update, if empty - update all fields, can be only field names, or fieldname => expression or fieldname => value * * @return string * @throws \Bitrix\Main\ArgumentException */ private static function prepareMergeValues(string $tableName, array $primaryFields, array $insertRows, array $updateFields = []): string { $sqlHelper = Application::getConnection()->getSqlHelper(); $insertColumns = array_keys($insertRows[array_key_first($insertRows)] ?? []); $insertValuesStrings = []; foreach ($insertRows as $row) { [, $rowValues] = $sqlHelper->prepareInsert($tableName, $row); $insertValuesStrings[] = $rowValues; } if (empty($updateFields)) { $notPrimaryFields = array_diff($insertColumns, $primaryFields); if (empty($notPrimaryFields)) { trigger_error("Only primary fields to update, use getInsertIgnore() or specify fields", E_USER_WARNING); } $updateFields = $notPrimaryFields; } $compatibleUpdateFields = []; foreach ($updateFields as $key => $value) { if (is_numeric($key) && is_string($value)) { $compatibleUpdateFields[$value] = new SqlExpression('?v', $value); } else { $compatibleUpdateFields[$key] = $value; } } $insertValueString = 'values (' . implode('),(', $insertValuesStrings) . ')'; return $sqlHelper->prepareMergeSelect($tableName, $primaryFields, $insertColumns, $insertValueString, $compatibleUpdateFields); } }