Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
bulkoperation.php
1<?php
2
4
6
7
9{
11 private static $tableFields;
12
21 public static function bulkAdd(array $rows, $primary = null): void
22 {
23 if (empty($rows))
24 {
25 return;
26 }
27 $tableName = static::getTableName();
28 $connection = Main\Application::getConnection();
29 $sqlHelper = $connection->getSqlHelper();
30
31 if (empty(static::$tableFields))
32 {
33 static::$tableFields = $connection->getTableFields($tableName);
34 }
35
36 $columns0 = \array_keys($rows[0]);
37 $columns = [];
38 foreach ($columns0 as $c)
39 {
40 $columns[$c] = $sqlHelper->quote(\mb_strtoupper($c));
41 }
42
43 $sqlValues = [];
44 foreach ($rows as $data)
45 {
46 foreach ($data as $columnName => $value)
47 {
48 $data[$columnName] = $sqlHelper->convertToDb($value, static::$tableFields[$columnName]);
49 }
50 $sqlValues[] = '('.\implode(', ', $data).')';
51 }
52 unset($data);
53
54 $tableName = $sqlHelper->quote($tableName);
55 $sql = "INSERT INTO {$tableName} (".\implode(', ', $columns).") VALUES ".\implode(', ', $sqlValues);
56
57 $checkPrimary = false;
58 if (!empty($primary))
59 {
60 if (!\is_array($primary))
61 {
62 $primary = array($primary);
63 }
64 if (\count(\array_intersect($primary, $columns0)) > 0)
65 {
66 $checkPrimary = true;
67 }
68 }
69 if ($checkPrimary)
70 {
71 $sqlUpdate = array();
72 foreach (\array_diff($columns0, $primary) as $columnName)
73 {
74 $sqlUpdate[] = "{$columns[$columnName]} = VALUES({$columns[$columnName]})";
75 }
76 $sql .= " ON DUPLICATE KEY UPDATE ".\implode(', ', $sqlUpdate);
77 }
78
79 $connection->queryExecute($sql);
80 }
81
90 public static function bulkUpdate(array $fields, array $filter = []): void
91 {
92 if (empty($fields))
93 {
94 return;
95 }
96 $tableName = static::getTableName();
97 $connection = Main\Application::getConnection();
98 $helper = $connection->getSqlHelper();
99
100 $update = $helper->prepareUpdate($tableName, $fields);
101 $valuesSql = $update[0];
102
103 if (!empty($valuesSql))
104 {
105 $tableName = $helper->quote($tableName);
106 if (!empty($filter))
107 {
108 $hasSubQuery = false;
109 foreach ($filter as $field => $value)
110 {
111 if (\mb_strpos($field, '.') !== false)
112 {
113 $hasSubQuery = true;
114 break;
115 }
116 }
117 if ($hasSubQuery)
118 {
119 $whereSql = (static::query())
120 ->setSelect(['ID' => 'ID'])
121 ->setFilter($filter)
122 ->getQuery();
123
124 $querySql = "UPDATE {$tableName} target INNER JOIN ({$whereSql}) source ON target.ID = source.ID SET {$valuesSql} ";
125 }
126 else
127 {
128 $whereSql = Main\ORM\Query\Query::buildFilterSql(static::getEntity(), $filter);
129 $querySql = "UPDATE {$tableName} SET {$valuesSql} WHERE {$whereSql}";
130 }
131 }
132 else
133 {
134 $querySql = "UPDATE {$tableName} SET {$valuesSql}";
135 }
136
137 $connection->queryExecute($querySql);
138 }
139 }
140
148 public static function bulkDelete(array $filter = []): void
149 {
150 $connection = Main\Application::getConnection();
151 $tableName = $connection->getSqlHelper()->quote(static::getTableName());
152
153 if (!empty($filter))
154 {
155 $hasSubQuery = false;
156 foreach ($filter as $field => $value)
157 {
158 if (\mb_strpos($field, '.') !== false)
159 {
160 $hasSubQuery = true;
161 break;
162 }
163 }
164 if ($hasSubQuery)
165 {
166 $whereSql = (static::query())
167 ->setSelect(['ID' => 'ID'])
168 ->setFilter($filter)
169 ->getQuery();
170
171 $querySql = "DELETE target FROM {$tableName} target INNER JOIN ({$whereSql}) source ON target.ID = source.ID";
172 }
173 else
174 {
175 $whereSql = Main\ORM\Query\Query::buildFilterSql(static::getEntity(), $filter);
176 $querySql = "DELETE FROM {$tableName} WHERE {$whereSql}";
177 }
178 }
179 else
180 {
181 $querySql = "TRUNCATE TABLE {$tableName}";
182 }
183
184 $connection->queryExecute($querySql);
185 }
186
187
196 private static function prepareWhere(array $filterFields, array $filterAlias = []): string
197 {
198 $sqlHelper = Main\Application::getConnection()->getSqlHelper();
199
200 $where = array();
201 $logic = 'AND';
202 foreach ($filterFields as $key => $val)
203 {
204 if ($key === 'LOGIC')
205 {
206 $logic = $val;
207 continue;
208 }
209 $operator = '=';
210 if (!\is_numeric($key))
211 {
212 if (\preg_match("/^([=<>!@%]+)([^=<>!@%]+)$/", $key, $parts))
213 {
214 [, $operator, $key] = $parts;
215 }
216 if (\is_array($val) && !isset($val['LOGIC']))
217 {
218 if ($operator === '=')
219 {
220 $operator = '@';
221 }
222 elseif ($operator === '!')
223 {
224 $operator = '!@';
225 }
226 }
227 if (isset($filterAlias[$key]))
228 {
229 $key = $filterAlias[$key];
230 }
231 }
232 switch ($operator)
233 {
234 case '!':
235 $where[] = "$key != '". $sqlHelper->forSql($val). "'";
236 break;
237
238 case '%':
239 $where[] = "$key LIKE '%". $sqlHelper->forSql($val). "%'";
240 break;
241
242 case '!%':
243 $where[] = "$key NOT LIKE '%". $sqlHelper->forSql($val). "%'";
244 break;
245
246 case '@':
247 {
248 if (\is_array($val) && \count($val) > 0)
249 {
250 $val = \array_map(array($sqlHelper, 'forSql'), $val);
251 $where[] = "$key IN('".\implode("', '", $val)."')";
252 }
253 elseif (\is_string($val) && $val <> '')
254 {
255 $where[] = "$key IN(".$val.')';
256 }
257 break;
258 }
259
260 case '!@':
261 {
262 if (\is_array($val) && \count($val) > 0)
263 {
264 $val = \array_map(array($sqlHelper, 'forSql'), $val);
265 $where[] = "$key NOT IN('".\implode("', '", $val)."')";
266 }
267 elseif (\is_string($val) && $val <> '')
268 {
269 $where[] = "$key NOT IN(".$val.')';
270 }
271 break;
272 }
273
274 default:
275 {
276 if (\is_array($val))
277 {
278 $subLogic = 'AND';
279 if (isset($val['LOGIC']) && $val['LOGIC'] === 'OR')
280 {
281 $subLogic = 'OR';
282 unset($val['LOGIC']);
283 }
284
285 $condition = array();
286 foreach ($val as $k => $v)
287 {
288 $subOperator = '=';
289 if (\preg_match("/^([=<>!@%]+)([^=<>!@%]+)$/", $k, $parts))
290 {
291 [, $subOperator, $k] = $parts;
292 }
293 if (isset($filterAlias[$k]))
294 {
295 $k = $filterAlias[$k];
296 }
297 switch ($subOperator)
298 {
299 case '!':
300 $condition[] = "$k != '".$sqlHelper->forSql($v)."'";
301 break;
302 case '%':
303 $condition[] = "$k LIKE '%".$sqlHelper->forSql($v)."%'";
304 break;
305 case '!%':
306 $condition[] = "$k NOT LIKE '%".$sqlHelper->forSql($v)."%'";
307 break;
308 default:
309 $condition[] = "$k $subOperator '".$sqlHelper->forSql($v)."'";
310 }
311 }
312 $where[] = '('.\implode(" $subLogic ", $condition).')';
313 }
314 else
315 {
316 $where[] = "$key $operator '".$sqlHelper->forSql($val)."'";
317 }
318 break;
319 }
320 }
321 }
322
323 $whereSql = '';
324 if (\count($where))
325 {
326 $whereSql = ' AND '. \implode(" $logic ", $where);
327 }
328
329 return $whereSql;
330 }
331}