From 1a01b3ead88ac0ed520b888dd67aed53a1172b13 Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Tue, 10 Jun 2025 17:41:57 +0200 Subject: [PATCH] feat: Implement custom Updater for object store storage Signed-off-by: Louis Chemineau fix: fix incorrect filesize for object store touch Signed-off-by: Robin Appelman test: improve version storage test Signed-off-by: Robin Appelman --- apps/files_versions/tests/StorageTest.php | 4 +- lib/composer/composer/autoload_classmap.php | 1 + lib/composer/composer/autoload_static.php | 1 + lib/private/Files/Cache/Updater.php | 2 +- .../Files/ObjectStore/ObjectStoreStorage.php | 21 +++++++++- .../Files/ObjectStore/ObjectStoreUpdater.php | 41 +++++++++++++++++++ lib/public/Files/Cache/IUpdater.php | 4 ++ 7 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 lib/private/Files/ObjectStore/ObjectStoreUpdater.php diff --git a/apps/files_versions/tests/StorageTest.php b/apps/files_versions/tests/StorageTest.php index 592f03f5e63..443cff3ee06 100644 --- a/apps/files_versions/tests/StorageTest.php +++ b/apps/files_versions/tests/StorageTest.php @@ -49,10 +49,10 @@ class StorageTest extends TestCase { protected function createPastFile(string $path, int $mtime): void { try { $file = $this->userFolder->get($path); + $file->putContent((string)$mtime); } catch (NotFoundException $e) { - $file = $this->userFolder->newFile($path); + $file = $this->userFolder->newFile($path, (string)$mtime); } - $file->putContent((string)$mtime); $file->touch($mtime); } diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index e0d86d084dd..456acbb2cb1 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -1648,6 +1648,7 @@ return array( 'OC\\Files\\ObjectStore\\Mapper' => $baseDir . '/lib/private/Files/ObjectStore/Mapper.php', 'OC\\Files\\ObjectStore\\ObjectStoreScanner' => $baseDir . '/lib/private/Files/ObjectStore/ObjectStoreScanner.php', 'OC\\Files\\ObjectStore\\ObjectStoreStorage' => $baseDir . '/lib/private/Files/ObjectStore/ObjectStoreStorage.php', + 'OC\\Files\\ObjectStore\\ObjectStoreUpdater' => $baseDir . '/lib/private/Files/ObjectStore/ObjectStoreUpdater.php', 'OC\\Files\\ObjectStore\\PrimaryObjectStoreConfig' => $baseDir . '/lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php', 'OC\\Files\\ObjectStore\\S3' => $baseDir . '/lib/private/Files/ObjectStore/S3.php', 'OC\\Files\\ObjectStore\\S3ConfigTrait' => $baseDir . '/lib/private/Files/ObjectStore/S3ConfigTrait.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 0bf675a77be..3ba8f20089c 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -1689,6 +1689,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Files\\ObjectStore\\Mapper' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/Mapper.php', 'OC\\Files\\ObjectStore\\ObjectStoreScanner' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/ObjectStoreScanner.php', 'OC\\Files\\ObjectStore\\ObjectStoreStorage' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/ObjectStoreStorage.php', + 'OC\\Files\\ObjectStore\\ObjectStoreUpdater' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/ObjectStoreUpdater.php', 'OC\\Files\\ObjectStore\\PrimaryObjectStoreConfig' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php', 'OC\\Files\\ObjectStore\\S3' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/S3.php', 'OC\\Files\\ObjectStore\\S3ConfigTrait' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/S3ConfigTrait.php', diff --git a/lib/private/Files/Cache/Updater.php b/lib/private/Files/Cache/Updater.php index 03681036aa2..17d4062bd69 100644 --- a/lib/private/Files/Cache/Updater.php +++ b/lib/private/Files/Cache/Updater.php @@ -272,7 +272,7 @@ class Updater implements IUpdater { * * @param string $internalPath */ - private function correctParentStorageMtime($internalPath) { + public function correctParentStorageMtime($internalPath) { $parentId = $this->cache->getParentId($internalPath); $parent = dirname($internalPath); if ($parentId != -1) { diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php index 36b1a7a1c95..81ec688434b 100644 --- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php @@ -14,6 +14,7 @@ use Icewind\Streams\CountWrapper; use Icewind\Streams\IteratorDirectory; use OC\Files\Cache\Cache; use OC\Files\Cache\CacheEntry; +use OC\Files\Cache\Updater; use OC\Files\Storage\PolyFill\CopyDirectory; use OCP\Files\Cache\ICache; use OCP\Files\Cache\ICacheEntry; @@ -417,7 +418,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil $stat = [ 'etag' => $this->getETag($path), 'mimetype' => $mimeType, - 'size' => 0, + 'size' => 1, 'mtime' => $mtime, 'storage_mtime' => $mtime, 'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE, @@ -474,6 +475,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil } // update stat with new data $mTime = time(); + $oldSize = $stat['size'] ?? 0; $stat['size'] = (int)$size; $stat['mtime'] = $mTime; $stat['storage_mtime'] = $mTime; @@ -571,6 +573,9 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil } } + $this->getUpdater()->correctParentStorageMtime($path); + $this->propagator->propagateChange($path, $mTime, $stat['size'] - $oldSize); + return $size; } @@ -824,4 +829,18 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil public function setPreserveCacheOnDelete(bool $preserve) { $this->preserveCacheItemsOnDelete = $preserve; } + + public function getUpdater(?IStorage $storage = null): Updater { + if (!$storage) { + $storage = $this; + } + if (!$storage->instanceOfStorage(self::class)) { + throw new \InvalidArgumentException('Storage is not of the correct class'); + } + /** @var self $storage */ + if (!isset($storage->updater)) { + $storage->updater = new ObjectStoreUpdater($storage); + } + return $storage->updater; + } } diff --git a/lib/private/Files/ObjectStore/ObjectStoreUpdater.php b/lib/private/Files/ObjectStore/ObjectStoreUpdater.php new file mode 100644 index 00000000000..04bc1b018bc --- /dev/null +++ b/lib/private/Files/ObjectStore/ObjectStoreUpdater.php @@ -0,0 +1,41 @@ +