Skip to content

Commit 288ff93

Browse files
committed
Add deleteBatch() and _deleteBatch()
1 parent 603239c commit 288ff93

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

system/Database/BaseBuilder.php

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2623,6 +2623,102 @@ public function delete($where = '', ?int $limit = null, bool $resetData = true)
26232623
return $this->testMode ? $sql : $this->db->query($sql, $this->binds, false);
26242624
}
26252625

2626+
/**
2627+
* Sets data and calls batchExecute to run queries
2628+
*
2629+
* @param array|object|null $set a dataset or select query
2630+
* @param array|RawSql|string|null $constraints
2631+
*
2632+
* @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode
2633+
*/
2634+
public function deleteBatch($set = null, $constraints = null, int $batchSize = 100)
2635+
{
2636+
$this->onConstraint($constraints);
2637+
2638+
if ($set !== null && $set !== []) {
2639+
$this->setData($set, true);
2640+
}
2641+
2642+
return $this->batchExecute('_deleteBatch', $batchSize);
2643+
}
2644+
2645+
/**
2646+
* Generates a platform-specific batch update string from the supplied data
2647+
*/
2648+
protected function _deleteBatch(string $table, array $keys, array $values): string
2649+
{
2650+
$sql = $this->QBOptions['sql'] ?? '';
2651+
2652+
// if this is the first iteration of batch then we need to build skeleton sql
2653+
if ($sql === '') {
2654+
$constraints = $this->QBOptions['constraints'] ?? [];
2655+
2656+
if ($constraints === []) {
2657+
if ($this->db->DBDebug) {
2658+
throw new DatabaseException('You must specify a constraint to match on for batch deletes.'); // @codeCoverageIgnore
2659+
}
2660+
2661+
return ''; // @codeCoverageIgnore
2662+
}
2663+
2664+
$updateFields = $this->QBOptions['updateFields'] ??
2665+
$this->updateFields($keys, false, $constraints)->QBOptions['updateFields'] ??
2666+
[];
2667+
2668+
$alias = $this->QBOptions['alias'] ?? '_u';
2669+
2670+
$sql = 'DELETE ' . $table . ' FROM ' . $table . "\n";
2671+
2672+
$sql .= "INNER JOIN (\n{:_table_:}";
2673+
2674+
$sql .= ') ' . $alias . "\n";
2675+
2676+
$sql .= 'ON ' . implode(
2677+
' AND ',
2678+
array_map(
2679+
static fn ($key) => ($key instanceof RawSql ?
2680+
$key :
2681+
$table . '.' . $key . ' = ' . $alias . '.' . $key),
2682+
$constraints
2683+
)
2684+
);
2685+
2686+
// convert binds in where
2687+
foreach ($this->QBWhere as $key => $where) {
2688+
foreach ($this->binds as $field => $bind) {
2689+
$this->QBWhere[$key]['condition'] = str_replace(':' . $field . ':', $bind[0], $where['condition']);
2690+
}
2691+
}
2692+
2693+
// remove database prefix from alias in where
2694+
$sql .= ' ' . str_replace(
2695+
$this->db->DBPrefix . trim($alias, $this->db->escapeChar),
2696+
trim($alias, $this->db->escapeChar),
2697+
$this->compileWhereHaving('QBWhere')
2698+
);
2699+
2700+
$this->QBOptions['sql'] = $sql;
2701+
}
2702+
2703+
if (isset($this->QBOptions['fromQuery'])) {
2704+
$data = $this->QBOptions['fromQuery'];
2705+
} else {
2706+
$data = implode(
2707+
" UNION ALL\n",
2708+
array_map(
2709+
static fn ($value) => 'SELECT ' . implode(', ', array_map(
2710+
static fn ($key, $index) => $index . ' ' . $key,
2711+
$keys,
2712+
$value
2713+
)),
2714+
$values
2715+
)
2716+
) . "\n";
2717+
}
2718+
2719+
return str_replace('{:_table_:}', $data, $sql);
2720+
}
2721+
26262722
/**
26272723
* Increments a numeric column by the specified value.
26282724
*

0 commit comments

Comments
 (0)