Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/Database/Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -701,11 +701,12 @@ abstract public function deleteDocument(string $collection, string $id): bool;
* Delete Documents
*
* @param string $collection
* @param array<string> $ids
* @param array<string> $internalIds
* @param array<string> $permissionIds
*
* @return int
*/
abstract public function deleteDocuments(string $collection, array $ids): int;
abstract public function deleteDocuments(string $collection, array $internalIds, array $permissionIds): int;

/**
* Find Documents
Expand Down
51 changes: 27 additions & 24 deletions src/Database/Adapter/MariaDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -1947,13 +1947,14 @@ public function deleteDocument(string $collection, string $id): bool
* Delete Documents
*
* @param string $collection
* @param array<string> $ids
* @param array<string> $internalIds
* @param array<string> $permissionIds
*
* @return int
*/
public function deleteDocuments(string $collection, array $ids): int
public function deleteDocuments(string $collection, array $internalIds, array $permissionIds): int
{
if (empty($ids)) {
if (empty($internalIds)) {
return 0;
}

Expand All @@ -1965,49 +1966,51 @@ public function deleteDocuments(string $collection, array $ids): int
$where[] = "_tenant = :_tenant";
}

$where[] = "_uid IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($ids))) . ")";
$where[] = "_id IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($internalIds))) . ")";

$sql = "DELETE FROM {$this->getSQLTable($name)} WHERE " . \implode(' AND ', $where);

$sql = $this->trigger(Database::EVENT_DOCUMENTS_DELETE, $sql);

$stmt = $this->getPDO()->prepare($sql);

foreach ($ids as $id => $value) {
foreach ($internalIds as $id => $value) {
$stmt->bindValue(":_id_{$id}", $value);
}

if ($this->sharedTables) {
$stmt->bindValue(':_tenant', $this->tenant);
}

$sql = "
if (!$stmt->execute()) {
throw new DatabaseException('Failed to delete documents');
}

if (!empty($permissionIds)) {
$sql = "
DELETE FROM {$this->getSQLTable($name . '_perms')}
WHERE _document IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($ids))) . ")
WHERE _document IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($permissionIds))) . ")
";

if ($this->sharedTables) {
$sql .= ' AND _tenant = :_tenant';
}

$sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql);
if ($this->sharedTables) {
$sql .= ' AND _tenant = :_tenant';
Comment thread
abnegate marked this conversation as resolved.
Outdated
}

$stmtPermissions = $this->getPDO()->prepare($sql);
$sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql);

foreach ($ids as $id => $value) {
$stmtPermissions->bindValue(":_id_{$id}", $value);
}
$stmtPermissions = $this->getPDO()->prepare($sql);

if ($this->sharedTables) {
$stmtPermissions->bindValue(':_tenant', $this->tenant);
}
foreach ($permissionIds as $id => $value) {
$stmtPermissions->bindValue(":_id_{$id}", $value);
}

if (!$stmt->execute()) {
throw new DatabaseException('Failed to delete documents');
}
if ($this->sharedTables) {
$stmtPermissions->bindValue(':_tenant', $this->tenant);
}

if (!$stmtPermissions->execute()) {
throw new DatabaseException('Failed to delete permissions');
if (!$stmtPermissions->execute()) {
throw new DatabaseException('Failed to delete permissions');
}
}
} catch (\Throwable $e) {
throw new DatabaseException($e->getMessage(), $e->getCode(), $e);
Expand Down
51 changes: 27 additions & 24 deletions src/Database/Adapter/Postgres.php
Original file line number Diff line number Diff line change
Expand Up @@ -1754,13 +1754,14 @@ public function deleteDocument(string $collection, string $id): bool
* Delete Documents
*
* @param string $collection
* @param array<string> $ids
* @param array<string> $internalIds
* @param array<string> $permissionIds
*
* @return int
*/
public function deleteDocuments(string $collection, array $ids): int
public function deleteDocuments(string $collection, array $internalIds, array $permissionIds): int
{
if (empty($ids)) {
if (empty($internalIds)) {
return 0;
}

Expand All @@ -1772,49 +1773,51 @@ public function deleteDocuments(string $collection, array $ids): int
$where[] = "_tenant = :_tenant";
}

$where[] = "_uid IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($ids))) . ")";
$where[] = "_id IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($internalIds))) . ")";

$sql = "DELETE FROM {$this->getSQLTable($name)} WHERE " . \implode(' AND ', $where);

$sql = $this->trigger(Database::EVENT_DOCUMENTS_DELETE, $sql);

$stmt = $this->getPDO()->prepare($sql);

foreach ($ids as $id => $value) {
foreach ($internalIds as $id => $value) {
$stmt->bindValue(":_id_{$id}", $value);
}

if ($this->sharedTables) {
$stmt->bindValue(':_tenant', $this->tenant);
}

$sql = "
if (!$stmt->execute()) {
throw new DatabaseException('Failed to delete documents');
}

if (!empty($permissionIds)) {
$sql = "
DELETE FROM {$this->getSQLTable($name . '_perms')}
WHERE _document IN (" . \implode(', ', \array_map(fn ($id) => ":_id_{$id}", \array_keys($ids))) . ")
WHERE _document IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($permissionIds))) . ")
";

if ($this->sharedTables) {
$sql .= ' AND _tenant = :_tenant';
}

$sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql);
if ($this->sharedTables) {
$sql .= ' AND _tenant = :_tenant';
}

$stmtPermissions = $this->getPDO()->prepare($sql);
$sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql);

foreach ($ids as $id => $value) {
$stmtPermissions->bindValue(":_id_{$id}", $value);
}
$stmtPermissions = $this->getPDO()->prepare($sql);

if ($this->sharedTables) {
$stmtPermissions->bindValue(':_tenant', $this->tenant);
}
foreach ($permissionIds as $id => $value) {
$stmtPermissions->bindValue(":_id_{$id}", $value);
}

if (!$stmt->execute()) {
throw new DatabaseException('Failed to delete documents');
}
if ($this->sharedTables) {
$stmtPermissions->bindValue(':_tenant', $this->tenant);
}

if (!$stmtPermissions->execute()) {
throw new DatabaseException('Failed to delete permissions');
if (!$stmtPermissions->execute()) {
throw new DatabaseException('Failed to delete permissions');
}
}
} catch (\Throwable $e) {
throw new DatabaseException($e->getMessage(), $e->getCode(), $e);
Expand Down
44 changes: 26 additions & 18 deletions src/Database/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -5495,6 +5495,9 @@ public function deleteDocuments(string $collection, array $queries = [], int $ba
$new[] = Query::cursorAfter($lastDocument);
}

/**
* @var array<Document> $affectedDocuments
*/
Comment thread
abnegate marked this conversation as resolved.
$affectedDocuments = $this->silent(fn () => $this->find(
$collection->getId(),
array_merge($new, $queries),
Expand All @@ -5505,9 +5508,15 @@ public function deleteDocuments(string $collection, array $queries = [], int $ba
break;
}

$documents = \array_merge($affectedDocuments, $documents);

$internalId = [];
$permIds = [];
Comment thread
abnegate marked this conversation as resolved.
Outdated
foreach ($affectedDocuments as $document) {
$documents[] = $document;
$internalId[] = $document->getInternalId();
if (!empty($document->getPermissions())) {
$permIds[] = $document->getId();
}

if ($this->resolveRelationships) {
$document = $this->silent(fn () => $this->deleteDocumentRelationships(
$collection,
Expand All @@ -5527,9 +5536,23 @@ public function deleteDocuments(string $collection, array $queries = [], int $ba
}
}

$this->withTransaction(function () use ($collection, $skipAuth, $authorization, $internalId, $permIds) {
$getResults = fn () => $this->adapter->deleteDocuments(
$collection->getId(),
$internalId,
$permIds
);

$skipAuth ? $authorization->skip($getResults) : $getResults();
});

foreach ($affectedDocuments as $affectedDocument) {
$this->purgeCachedDocument($collection->getId(), $affectedDocument->getId());
}

if (count($affectedDocuments) < $batchSize) {
break;
} elseif ($originalLimit && count($documents) == $originalLimit) {
} elseif ($originalLimit && count($documents) >= $originalLimit) {
break;
}

Expand All @@ -5540,21 +5563,6 @@ public function deleteDocuments(string $collection, array $queries = [], int $ba
return [];
}

$this->withTransaction(function () use ($documents, $collection, $batchSize, $skipAuth, $authorization) {
foreach (\array_chunk($documents, $batchSize) as $chunk) {
$getResults = fn () => $this->adapter->deleteDocuments(
$collection->getId(),
array_map(fn ($document) => $document->getId(), $chunk)
);

$skipAuth ? $authorization->skip($getResults) : $getResults();
}
});

foreach ($documents as $document) {
$this->purgeCachedDocument($collection->getId(), $document->getId());
}

$this->trigger(self::EVENT_DOCUMENTS_DELETE, new Document([
'$collection' => $collection->getId(),
'modified' => count($documents)
Expand Down