Skip to content

Commit dddf6ca

Browse files
committed
fix: get child ids for folder in a separate query during move
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent 221883f commit dddf6ca

1 file changed

Lines changed: 21 additions & 4 deletions

File tree

lib/private/Files/Cache/Cache.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,11 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
699699
if ($sourceData['mimetype'] === 'httpd/unix-directory') {
700700
//update all child entries
701701
$sourceLength = mb_strlen($sourcePath);
702+
703+
$childIds = $this->getChildIds($sourceStorageId, $sourcePath);
704+
705+
$childChunks = array_chunk($childIds, 1000);
706+
702707
$query = $this->connection->getQueryBuilder();
703708

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

716721
// when moving from an encrypted storage to a non-encrypted storage remove the `encrypted` mark
717722
if ($sourceCache->hasEncryptionWrapper() && !$this->hasEncryptionWrapper()) {
@@ -724,19 +729,22 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
724729
for ($i = 1; $i <= $retryLimit; $i++) {
725730
try {
726731
$this->connection->beginTransaction();
727-
$query->executeStatement();
732+
foreach ($childChunks as $chunk) {
733+
$query->setParameter('files', $chunk, IQueryBuilder::PARAM_INT_ARRAY);
734+
$query->executeStatement();
735+
}
728736
break;
729737
} catch (\OC\DatabaseException $e) {
730738
$this->connection->rollBack();
731739
throw $e;
732740
} catch (RetryableException $e) {
741+
$this->connection->rollBack();
742+
733743
// Simply throw if we already retried 4 times.
734744
if ($i === $retryLimit) {
735745
throw $e;
736746
}
737747

738-
$this->connection->rollBack();
739-
740748
// Sleep a bit to give some time to the other transaction to finish.
741749
usleep(100 * 1000 * $i);
742750
}
@@ -778,6 +786,15 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
778786
}
779787
}
780788

789+
private function getChildIds(int $storageId, string $path): array {
790+
$query = $this->connection->getQueryBuilder();
791+
$query->select('fileid')
792+
->from('filecache')
793+
->where($query->expr()->eq('storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
794+
->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($path) . '/%')));
795+
return $query->executeQuery()->fetchAll(\PDO::FETCH_COLUMN);
796+
}
797+
781798
/**
782799
* remove all entries for files that are stored on the storage from the cache
783800
*/

0 commit comments

Comments
 (0)