Skip to content

Commit 103a573

Browse files
committed
Update Oracle Forge::_updateBatch()
1 parent 57c6b23 commit 103a573

File tree

1 file changed

+66
-31
lines changed

1 file changed

+66
-31
lines changed

system/Database/OCI8/Builder.php

Lines changed: 66 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -233,46 +233,81 @@ protected function resetSelect()
233233
*/
234234
protected function _updateBatch(string $table, array $values, string $index): string
235235
{
236-
$keys = array_keys(current($values));
236+
// this is a work around until the rest of the platform is refactored
237+
$this->QBOptions['constraints'] = [$index];
238+
$keys = array_keys(current($values));
237239

238-
// make array for future use with composite keys - `field`
239-
// future: $this->QBOptions['constraints']
240-
$constraints = [$index];
240+
$sql = $this->QBOptions['sql'] ?? '';
241241

242-
// future: $this->QBOptions['updateFields']
243-
$updateFields = array_filter($keys, static fn ($index) => ! in_array($index, $constraints, true));
242+
// if this is the first iteration of batch then we need to build skeleton sql
243+
if ($sql === '') {
244+
$constraints = $this->QBOptions['constraints'] ?? [];
244245

245-
// Oracle doesn't support ignore on updates so we will use MERGE
246-
$sql = 'MERGE INTO ' . $table . " \"t\"\n";
246+
if ($constraints === []) {
247+
if ($this->db->DBDebug) {
248+
throw new DatabaseException('You must specify a constraint to match on for batch updates.');
249+
}
250+
251+
return ''; // @codeCoverageIgnore
252+
}
253+
254+
$updateFields = $this->QBOptions['updateFields'] ??
255+
$this->updateFields($keys, false, $constraints)->QBOptions['updateFields'] ??
256+
[];
257+
258+
$alias = $this->QBOptions['alias'] ?? '"_u"';
247259

248-
$sql .= 'USING (' . "\n";
260+
// Oracle doesn't support ignore on updates so we will use MERGE
261+
$sql = 'MERGE INTO ' . $table . "\n";
249262

250-
$sql .= implode(
251-
" UNION ALL\n",
252-
array_map(
253-
static fn ($value) => 'SELECT ' . implode(', ', array_map(
254-
static fn ($key, $index) => $index . ' ' . $key,
255-
$keys,
256-
$value
257-
)) . ' FROM DUAL',
258-
$values
259-
)
260-
) . "\n";
263+
$sql .= 'USING (' . "\n%s";
261264

262-
$sql .= ') "u"' . "\n";
265+
$sql .= ') ' . $alias . "\n";
263266

264-
$sql .= 'ON (' . implode(
265-
' AND ',
266-
array_map(static fn ($key) => '"t".' . $key . ' = "u".' . $key, $constraints)
267-
) . ")\n";
267+
$sql .= 'ON (' . implode(
268+
' AND ',
269+
array_map(
270+
static fn ($key) => ($key instanceof RawSql ?
271+
$key :
272+
$table . '.' . $key . ' = ' . $alias . '.' . $key),
273+
$constraints
274+
)
275+
) . ")\n";
268276

269-
$sql .= "WHEN MATCHED THEN UPDATE\n";
277+
$sql .= "WHEN MATCHED THEN UPDATE\n";
270278

271-
$sql .= 'SET' . "\n";
279+
$sql .= 'SET' . "\n";
280+
281+
$sql .= implode(
282+
",\n",
283+
array_map(
284+
static fn ($key, $value) => $table . '.' . $key . ($value instanceof RawSql ?
285+
' = ' . $value :
286+
' = ' . $alias . '.' . $value),
287+
array_keys($updateFields),
288+
$updateFields
289+
)
290+
);
291+
292+
$this->QBOptions['sql'] = $sql;
293+
}
294+
295+
if (isset($this->QBOptions['fromQuery'])) {
296+
$data = $this->QBOptions['fromQuery'];
297+
} else {
298+
$data = implode(
299+
" UNION ALL\n",
300+
array_map(
301+
static fn ($value) => 'SELECT ' . implode(', ', array_map(
302+
static fn ($key, $index) => $index . ' ' . $key,
303+
$keys,
304+
$value
305+
)) . ' FROM DUAL',
306+
$values
307+
)
308+
) . "\n";
309+
}
272310

273-
return $sql .= implode(
274-
",\n",
275-
array_map(static fn ($key) => '"t".' . $key . ' = "u".' . $key, $updateFields)
276-
);
311+
return sprintf($sql, $data);
277312
}
278313
}

0 commit comments

Comments
 (0)