Conditions | 13 |
Paths | 109 |
Total Lines | 98 |
Code Lines | 52 |
Lines | 0 |
Ratio | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
102 | public function upsert( |
||
103 | string $table, |
||
104 | QueryInterface|array $insertColumns, |
||
105 | array|bool $updateColumns, |
||
106 | array &$params = [] |
||
107 | ): string { |
||
108 | $usingValues = null; |
||
109 | $constraints = []; |
||
110 | |||
111 | [$uniqueNames, $insertNames, $updateNames] = $this->prepareUpsertColumns( |
||
112 | $table, |
||
113 | $insertColumns, |
||
114 | $updateColumns, |
||
115 | $constraints |
||
116 | ); |
||
117 | |||
118 | if (empty($uniqueNames)) { |
||
119 | return $this->insert($table, $insertColumns, $params); |
||
120 | } |
||
121 | |||
122 | if ($updateNames === []) { |
||
123 | /** there are no columns to update */ |
||
124 | $updateColumns = false; |
||
125 | } |
||
126 | |||
127 | $onCondition = ['or']; |
||
128 | $quotedTableName = $this->quoter->quoteTableName($table); |
||
129 | |||
130 | foreach ($constraints as $constraint) { |
||
131 | $columnNames = $constraint->getColumnNames() ?? []; |
||
132 | $constraintCondition = ['and']; |
||
133 | /** @psalm-var string[] $columnNames */ |
||
134 | foreach ($columnNames as $name) { |
||
135 | $quotedName = $this->quoter->quoteColumnName($name); |
||
136 | $constraintCondition[] = "$quotedTableName.$quotedName=\"EXCLUDED\".$quotedName"; |
||
137 | } |
||
138 | |||
139 | $onCondition[] = $constraintCondition; |
||
140 | } |
||
141 | |||
142 | $on = $this->queryBuilder->buildCondition($onCondition, $params); |
||
143 | /** @psalm-var string[] $placeholders */ |
||
144 | [, $placeholders, $values, $params] = $this->prepareInsertValues($table, $insertColumns, $params); |
||
145 | |||
146 | if (!empty($placeholders)) { |
||
147 | $usingSelectValues = []; |
||
148 | /** @psalm-var string[] $insertNames */ |
||
149 | foreach ($insertNames as $index => $name) { |
||
150 | $usingSelectValues[$name] = new Expression($placeholders[$index]); |
||
151 | } |
||
152 | |||
153 | /** @psalm-var array $params */ |
||
154 | $usingValues = $this->queryBuilder->buildSelect($usingSelectValues, $params) . ' ' . $this->queryBuilder->buildFrom(['DUAL'], $params); |
||
155 | } |
||
156 | |||
157 | $insertValues = []; |
||
158 | $mergeSql = 'MERGE INTO ' |
||
159 | . $this->quoter->quoteTableName($table) |
||
160 | . ' ' |
||
161 | . 'USING (' . ($usingValues ?? ltrim((string) $values, ' ')) |
||
162 | . ') "EXCLUDED" ' |
||
163 | . "ON ($on)"; |
||
164 | |||
165 | /** @psalm-var string[] $insertNames */ |
||
166 | foreach ($insertNames as $name) { |
||
167 | $quotedName = $this->quoter->quoteColumnName($name); |
||
168 | |||
169 | if (strrpos($quotedName, '.') === false) { |
||
170 | $quotedName = '"EXCLUDED".' . $quotedName; |
||
171 | } |
||
172 | |||
173 | $insertValues[] = $quotedName; |
||
174 | } |
||
175 | |||
176 | $insertSql = 'INSERT (' . implode(', ', $insertNames) . ')' . ' VALUES (' . implode(', ', $insertValues) . ')'; |
||
177 | |||
178 | if ($updateColumns === false) { |
||
179 | return "$mergeSql WHEN NOT MATCHED THEN $insertSql"; |
||
180 | } |
||
181 | |||
182 | if ($updateColumns === true) { |
||
183 | $updateColumns = []; |
||
184 | /** @psalm-var string[] $updateNames */ |
||
185 | foreach ($updateNames as $name) { |
||
186 | $quotedName = $this->quoter->quoteColumnName($name); |
||
187 | |||
188 | if (strrpos($quotedName, '.') === false) { |
||
189 | $quotedName = '"EXCLUDED".' . $quotedName; |
||
190 | } |
||
191 | $updateColumns[$name] = new Expression($quotedName); |
||
192 | } |
||
193 | } |
||
194 | |||
195 | /** @psalm-var string[] $updates */ |
||
196 | [$updates, $params] = $this->prepareUpdateSets($table, $updateColumns, (array) $params); |
||
197 | $updateSql = 'UPDATE SET ' . implode(', ', $updates); |
||
198 | |||
199 | return "$mergeSql WHEN MATCHED THEN $updateSql WHEN NOT MATCHED THEN $insertSql"; |
||
200 | } |
||
260 |