Skip to content

Commit f9547eb

Browse files
committed
Add deleteBatch() and _deleteBatch()
1 parent ef8646a commit f9547eb

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
@@ -2653,6 +2653,102 @@ public function delete($where = '', ?int $limit = null, bool $resetData = true)
26532653
return $this->testMode ? $sql : $this->db->query($sql, $this->binds, false);
26542654
}
26552655

2656+
/**
2657+
* Sets data and calls batchExecute to run queries
2658+
*
2659+
* @param array|object|null $set a dataset or select query
2660+
* @param array|RawSql|string|null $constraints
2661+
*
2662+
* @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode
2663+
*/
2664+
public function deleteBatch($set = null, $constraints = null, int $batchSize = 100)
2665+
{
2666+
$this->onConstraint($constraints);
2667+
2668+
if ($set !== null && $set !== []) {
2669+
$this->setData($set, true);
2670+
}
2671+
2672+
return $this->batchExecute('_deleteBatch', $batchSize);
2673+
}
2674+
2675+
/**
2676+
* Generates a platform-specific batch update string from the supplied data
2677+
*/
2678+
protected function _deleteBatch(string $table, array $keys, array $values): string
2679+
{
2680+
$sql = $this->QBOptions['sql'] ?? '';
2681+
2682+
// if this is the first iteration of batch then we need to build skeleton sql
2683+
if ($sql === '') {
2684+
$constraints = $this->QBOptions['constraints'] ?? [];
2685+
2686+
if ($constraints === []) {
2687+
if ($this->db->DBDebug) {
2688+
throw new DatabaseException('You must specify a constraint to match on for batch deletes.'); // @codeCoverageIgnore
2689+
}
2690+
2691+
return ''; // @codeCoverageIgnore
2692+
}
2693+
2694+
$updateFields = $this->QBOptions['updateFields'] ??
2695+
$this->updateFields($keys, false, $constraints)->QBOptions['updateFields'] ??
2696+
[];
2697+
2698+
$alias = $this->QBOptions['alias'] ?? '_u';
2699+
2700+
$sql = 'DELETE ' . $table . ' FROM ' . $table . "\n";
2701+
2702+
$sql .= "INNER JOIN (\n{:_table_:}";
2703+
2704+
$sql .= ') ' . $alias . "\n";
2705+
2706+
$sql .= 'ON ' . implode(
2707+
' AND ',
2708+
array_map(
2709+
static fn ($key) => ($key instanceof RawSql ?
2710+
$key :
2711+
$table . '.' . $key . ' = ' . $alias . '.' . $key),
2712+
$constraints
2713+
)
2714+
);
2715+
2716+
// convert binds in where
2717+
foreach ($this->QBWhere as $key => $where) {
2718+
foreach ($this->binds as $field => $bind) {
2719+
$this->QBWhere[$key]['condition'] = str_replace(':' . $field . ':', $bind[0], $where['condition']);
2720+
}
2721+
}
2722+
2723+
// remove database prefix from alias in where
2724+
$sql .= ' ' . str_replace(
2725+
$this->db->DBPrefix . trim($alias, $this->db->escapeChar),
2726+
trim($alias, $this->db->escapeChar),
2727+
$this->compileWhereHaving('QBWhere')
2728+
);
2729+
2730+
$this->QBOptions['sql'] = $sql;
2731+
}
2732+
2733+
if (isset($this->QBOptions['fromQuery'])) {
2734+
$data = $this->QBOptions['fromQuery'];
2735+
} else {
2736+
$data = implode(
2737+
" UNION ALL\n",
2738+
array_map(
2739+
static fn ($value) => 'SELECT ' . implode(', ', array_map(
2740+
static fn ($key, $index) => $index . ' ' . $key,
2741+
$keys,
2742+
$value
2743+
)),
2744+
$values
2745+
)
2746+
) . "\n";
2747+
}
2748+
2749+
return str_replace('{:_table_:}', $data, $sql);
2750+
}
2751+
26562752
/**
26572753
* Increments a numeric column by the specified value.
26582754
*

0 commit comments

Comments
 (0)