diff options
author | Robin Appelman <robin@icewind.nl> | 2024-02-12 15:52:07 +0100 |
---|---|---|
committer | Arthur Schiwon <blizzz@arthur-schiwon.de> | 2024-06-13 10:38:57 +0200 |
commit | 082c6c6e1d238c283ab951108a6f0930e6327cc6 (patch) | |
tree | fafb35ed030708c79c6612021512275c649524e2 /lib/private/Files/Cache | |
parent | 59c181b4cbc47821d0a7d35df747a8b1d012dfc7 (diff) | |
download | nextcloud-server-082c6c6e1d238c283ab951108a6f0930e6327cc6.tar.gz nextcloud-server-082c6c6e1d238c283ab951108a6f0930e6327cc6.zip |
fix: get child ids for folder in a separate query during move
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib/private/Files/Cache')
-rw-r--r-- | lib/private/Files/Cache/Cache.php | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index 96e840e4806..3c871fdf4dc 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -666,6 +666,11 @@ class Cache implements ICache { if ($sourceData['mimetype'] === 'httpd/unix-directory') { //update all child entries $sourceLength = mb_strlen($sourcePath); + + $childIds = $this->getChildIds($sourceStorageId, $sourcePath); + + $childChunks = array_chunk($childIds, 1000); + $query = $this->connection->getQueryBuilder(); $fun = $query->func(); @@ -678,7 +683,7 @@ class Cache implements ICache { ->set('path_hash', $fun->md5($newPathFunction)) ->set('path', $newPathFunction) ->where($query->expr()->eq('storage', $query->createNamedParameter($sourceStorageId, IQueryBuilder::PARAM_INT))) - ->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($sourcePath) . '/%'))); + ->andWhere($query->expr()->in('fileid', $query->createParameter('files'))); // when moving from an encrypted storage to a non-encrypted storage remove the `encrypted` mark if ($sourceCache->hasEncryptionWrapper() && !$this->hasEncryptionWrapper()) { @@ -691,12 +696,17 @@ class Cache implements ICache { for ($i = 1; $i <= $retryLimit; $i++) { try { $this->connection->beginTransaction(); - $query->executeStatement(); + foreach ($childChunks as $chunk) { + $query->setParameter('files', $chunk, IQueryBuilder::PARAM_INT_ARRAY); + $query->executeStatement(); + } break; } catch (\OC\DatabaseException $e) { $this->connection->rollBack(); throw $e; } catch (DbalException $e) { + $this->connection->rollBack(); + if (!$e->isRetryable()) { throw $e; } @@ -706,8 +716,6 @@ class Cache implements ICache { throw $e; } - $this->connection->rollBack(); - // Sleep a bit to give some time to the other transaction to finish. usleep(100 * 1000 * $i); } @@ -749,6 +757,15 @@ class Cache implements ICache { } } + private function getChildIds(int $storageId, string $path): array { + $query = $this->connection->getQueryBuilder(); + $query->select('fileid') + ->from('filecache') + ->where($query->expr()->eq('storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))) + ->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($path) . '/%'))); + return $query->executeQuery()->fetchAll(\PDO::FETCH_COLUMN); + } + /** * remove all entries for files that are stored on the storage from the cache */ |