1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
merge.php
См. документацию.
1<?php
2
3namespace Bitrix\Main\ORM\Data\AddStrategy;
4
5use Bitrix\Main\NotSupportedException;
6use Bitrix\Main\ORM\Data\AddStrategy\Contract\AddStrategy;
7use Bitrix\Main\ORM\Data\AddStrategy\Internal\Helper;
8use Bitrix\Main\ORM\Entity;
9use Bitrix\Main\ORM\Fields\ScalarField;
10
11final class Merge implements AddStrategy
12{
13 private readonly array $uniqueFieldNames;
14 private readonly array $uniqueDbColumns;
15
16 public function __construct(
17 private readonly Entity $entity,
18 ?array $uniqueFieldNames = null,
19 )
20 {
21 $uniqueFieldNames ??= $this->entity->getPrimaryArray();
22
23 if (!Helper::isEntitySupportedByUniqueValidatingStrategies($this->entity, $uniqueFieldNames))
24 {
25 throw new NotSupportedException('Entity is not supported by the ' . self::class);
26 }
27
28 sort($uniqueFieldNames, SORT_STRING);
29 $this->uniqueFieldNames = $uniqueFieldNames;
30
31 $uniqueDbColumns = $this->replaceFieldNames($this->uniqueFieldNames);
32 sort($uniqueDbColumns, SORT_STRING);
33 $this->uniqueDbColumns = $uniqueDbColumns;
34 }
35
36 public function add(array $dbFields): AddedData
37 {
38 $updateDbFields = $this->getUpdateDbFields($dbFields, $this->uniqueDbColumns);
39
40 $insertedId = $this->merge(
41 $dbFields,
42 $updateDbFields,
43 $this->uniqueDbColumns,
44 );
45
46 $isDBChanged = $this->isDBChanged();
47
48 if ($insertedId !== 0)
49 {
50 return new AddedData($insertedId, $isDBChanged);
51 }
52 else
53 {
54 return new AddedData(
55 Helper::guessInsertedId($this->entity, $dbFields, $this->uniqueFieldNames),
56 $isDBChanged,
57 );
58 }
59 }
60
61 public function addMulti(array $multiDbFields): AddedMultiData
62 {
63 foreach ($multiDbFields as &$dbFields)
64 {
65 // prepareMergeValues looks on key *order* in fields, not key *name*
66 ksort($dbFields, SORT_STRING);
67 }
68
69 $firstDbFields = reset($multiDbFields);
70 $updateDbColumns = array_keys(
71 $this->getUpdateDbFields($firstDbFields, $this->uniqueDbColumns),
72 );
73
74 $connection = $this->entity->getConnection();
75
76 // never force separate queries, since events are always ignored
77 $sql = $connection->getSqlHelper()->prepareMergeValues(
78 $this->entity->getDBTableName(),
79 $this->uniqueDbColumns,
80 $multiDbFields,
81 $updateDbColumns,
82 );
83
84 $connection->queryExecute($sql);
85
86 return new AddedMultiData($this->isDBChanged());
87 }
88
89 private function merge(array $insertFields, array $updateFields, array $uniqueFieldNames): int
90 {
91 $sqlHelper = $this->entity->getConnection()->getSqlHelper();
92
93 $sql = $sqlHelper->prepareMerge(
94 $this->entity->getDBTableName(),
95 $uniqueFieldNames,
96 $insertFields,
97 $updateFields
98 );
99
100 return Helper::executeAndGetInsertedId($this->entity, current($sql));
101 }
102
103 private function replaceFieldNames(array $fieldNames): array
104 {
105 $result = [];
106 foreach ($fieldNames as $fieldName)
107 {
108 $field = $this->entity->getField($fieldName);
109
110 $result[] = $field instanceof ScalarField ? $field->getColumnName() : $fieldName;
111 }
112
113 return $result;
114 }
115
121 private function getUpdateDbFields(array $dbFields, array $uniqueColumns): array
122 {
123 $update = [];
124 foreach ($dbFields as $column => $value)
125 {
126 if (!in_array($column, $uniqueColumns, true))
127 {
128 $update[$column] = $value;
129 }
130 }
131
132 return $update;
133 }
134
135 private function isDBChanged(): bool
136 {
137 // on mysql count will be 0 if no changes, 1 if inserted, 2 if a row was updated
138 // pgsql will always return 1 on merge
139 return $this->entity->getConnection()->getAffectedRowsCount() > 0;
140 }
141}
$connection
Определения actionsdefinitions.php:38
__construct(private readonly Entity $entity, ?array $uniqueFieldNames=null,)
Определения merge.php:16
add(array $dbFields)
Определения merge.php:36
addMulti(array $multiDbFields)
Определения merge.php:61
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$entity
Определения ufield.php:9