diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index de807421d2..77289e674b 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -553,25 +553,35 @@ class Cache implements ICache { * @throws \OC\DatabaseException */ private function removeChildren(ICacheEntry $entry) { - $children = $this->getFolderContentsById($entry->getId()); - $childIds = array_map(function (ICacheEntry $cacheEntry) { - return $cacheEntry->getId(); - }, $children); - $childFolders = array_filter($children, function ($child) { - return $child->getMimeType() == FileInfo::MIMETYPE_FOLDER; - }); - foreach ($childFolders as $folder) { - $this->removeChildren($folder); + $parentIds = [$entry->getId()]; + $queue = [$entry->getId()]; + + // we walk depth first trough the file tree, removing all filecache_extended attributes while we walk + // and collecting all folder ids to later use to delete the filecache entries + while ($entryId = array_pop($queue)) { + $children = $this->getFolderContentsById($entryId); + $childIds = array_map(function (ICacheEntry $cacheEntry) { + return $cacheEntry->getId(); + }, $children); + + $query = $this->getQueryBuilder(); + $query->delete('filecache_extended') + ->where($query->expr()->in('fileid', $query->createNamedParameter($childIds, IQueryBuilder::PARAM_INT_ARRAY))); + $query->execute(); + + /** @var ICacheEntry[] $childFolders */ + $childFolders = array_filter($children, function ($child) { + return $child->getMimeType() == FileInfo::MIMETYPE_FOLDER; + }); + foreach ($childFolders as $folder) { + $parentIds[] = $folder->getId(); + $queue[] = $folder->getId(); + } } $query = $this->getQueryBuilder(); $query->delete('filecache') - ->whereParent($entry->getId()); - $query->execute(); - - $query = $this->getQueryBuilder(); - $query->delete('filecache_extended') - ->where($query->expr()->in('fileid', $query->createNamedParameter($childIds, IQueryBuilder::PARAM_INT_ARRAY))); + ->whereParentIn($parentIds); $query->execute(); } diff --git a/lib/private/Files/Cache/CacheQueryBuilder.php b/lib/private/Files/Cache/CacheQueryBuilder.php index 332274eda2..ac17cfaffb 100644 --- a/lib/private/Files/Cache/CacheQueryBuilder.php +++ b/lib/private/Files/Cache/CacheQueryBuilder.php @@ -94,4 +94,17 @@ class CacheQueryBuilder extends QueryBuilder { return $this; } + + public function whereParentIn(array $parents) { + $alias = $this->alias; + if ($alias) { + $alias .= '.'; + } else { + $alias = ''; + } + + $this->andWhere($this->expr()->in("{$alias}parent", $this->createNamedParameter($parents, IQueryBuilder::PARAM_INT_ARRAY))); + + return $this; + } }