Skip to content

Commit 44eba1c

Browse files
authored
Merge pull request #45850 from nextcloud/backport/43531/stable28
[stable28] get child ids for folder in a separate query during move
2 parents c23002b + 4314997 commit 44eba1c

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

lib/private/Files/Cache/Cache.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,11 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
702702
if ($sourceData['mimetype'] === 'httpd/unix-directory') {
703703
//update all child entries
704704
$sourceLength = mb_strlen($sourcePath);
705+
706+
$childIds = $this->getChildIds($sourceStorageId, $sourcePath);
707+
708+
$childChunks = array_chunk($childIds, 1000);
709+
705710
$query = $this->connection->getQueryBuilder();
706711

707712
$fun = $query->func();
@@ -714,7 +719,7 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
714719
->set('path_hash', $fun->md5($newPathFunction))
715720
->set('path', $newPathFunction)
716721
->where($query->expr()->eq('storage', $query->createNamedParameter($sourceStorageId, IQueryBuilder::PARAM_INT)))
717-
->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($sourcePath) . '/%')));
722+
->andWhere($query->expr()->in('fileid', $query->createParameter('files')));
718723

719724
// when moving from an encrypted storage to a non-encrypted storage remove the `encrypted` mark
720725
if ($sourceCache->hasEncryptionWrapper() && !$this->hasEncryptionWrapper()) {
@@ -727,12 +732,17 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
727732
for ($i = 1; $i <= $retryLimit; $i++) {
728733
try {
729734
$this->connection->beginTransaction();
730-
$query->executeStatement();
735+
foreach ($childChunks as $chunk) {
736+
$query->setParameter('files', $chunk, IQueryBuilder::PARAM_INT_ARRAY);
737+
$query->executeStatement();
738+
}
731739
break;
732740
} catch (\OC\DatabaseException $e) {
733741
$this->connection->rollBack();
734742
throw $e;
735743
} catch (DbalException $e) {
744+
$this->connection->rollBack();
745+
736746
if (!$e->isRetryable()) {
737747
throw $e;
738748
}
@@ -742,8 +752,6 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
742752
throw $e;
743753
}
744754

745-
$this->connection->rollBack();
746-
747755
// Sleep a bit to give some time to the other transaction to finish.
748756
usleep(100 * 1000 * $i);
749757
}
@@ -785,6 +793,15 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
785793
}
786794
}
787795

796+
private function getChildIds(int $storageId, string $path): array {
797+
$query = $this->connection->getQueryBuilder();
798+
$query->select('fileid')
799+
->from('filecache')
800+
->where($query->expr()->eq('storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
801+
->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($path) . '/%')));
802+
return $query->executeQuery()->fetchAll(\PDO::FETCH_COLUMN);
803+
}
804+
788805
/**
789806
* remove all entries for files that are stored on the storage from the cache
790807
*/

0 commit comments

Comments
 (0)