aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/private/FilesMetadata/FilesMetadataManager.php4
-rw-r--r--lib/private/FilesMetadata/Model/FilesMetadata.php9
-rw-r--r--lib/private/FilesMetadata/Service/MetadataRequestService.php7
-rw-r--r--tests/lib/FilesMetadata/FilesMetadataManagerTest.php98
4 files changed, 114 insertions, 4 deletions
diff --git a/lib/private/FilesMetadata/FilesMetadataManager.php b/lib/private/FilesMetadata/FilesMetadataManager.php
index ed8a1f935c1..04eec1c85a4 100644
--- a/lib/private/FilesMetadata/FilesMetadataManager.php
+++ b/lib/private/FilesMetadata/FilesMetadataManager.php
@@ -81,10 +81,10 @@ class FilesMetadataManager implements IFilesMetadataManager {
try {
/** @var FilesMetadata $metadata */
$metadata = $this->metadataRequestService->getMetadataFromFileId($node->getId());
- $metadata->setStorageId($storageId);
} catch (FilesMetadataNotFoundException) {
- $metadata = new FilesMetadata($node->getId(), $storageId);
+ $metadata = new FilesMetadata($node->getId());
}
+ $metadata->setStorageId($storageId);
// if $process is LIVE, we enforce LIVE
// if $process is NAMED, we go NAMED
diff --git a/lib/private/FilesMetadata/Model/FilesMetadata.php b/lib/private/FilesMetadata/Model/FilesMetadata.php
index 9bf1ca866ac..edcceb48ae7 100644
--- a/lib/private/FilesMetadata/Model/FilesMetadata.php
+++ b/lib/private/FilesMetadata/Model/FilesMetadata.php
@@ -27,6 +27,7 @@ class FilesMetadata implements IFilesMetadata {
private bool $updated = false;
private int $lastUpdate = 0;
private string $syncToken = '';
+ private ?int $storageId = null;
public function __construct(
private int $fileId = 0
@@ -46,6 +47,14 @@ class FilesMetadata implements IFilesMetadata {
return $this->storageId;
}
+ /**
+ * Set which storage the file this metadata belongs to.
+ *
+ * This helps with sharded filecache setups to know where to store the metadata
+ *
+ * @param int $storageId
+ * @return void
+ */
public function setStorageId(int $storageId): void {
$this->storageId = $storageId;
}
diff --git a/lib/private/FilesMetadata/Service/MetadataRequestService.php b/lib/private/FilesMetadata/Service/MetadataRequestService.php
index 49cd8886046..bb3833c2fb6 100644
--- a/lib/private/FilesMetadata/Service/MetadataRequestService.php
+++ b/lib/private/FilesMetadata/Service/MetadataRequestService.php
@@ -29,8 +29,11 @@ class MetadataRequestService {
}
private function getStorageId(IFilesMetadata $filesMetadata): int {
- if ($filesMetadata instanceof FilesMetadata && $filesMetadata->getStorageId()) {
- return $filesMetadata->getStorageId();
+ if ($filesMetadata instanceof FilesMetadata) {
+ $storage = $filesMetadata->getStorageId();
+ if ($storage) {
+ return $storage;
+ }
}
// all code paths that lead to saving metadata *should* have the storage id set
// this fallback is there just in case
diff --git a/tests/lib/FilesMetadata/FilesMetadataManagerTest.php b/tests/lib/FilesMetadata/FilesMetadataManagerTest.php
new file mode 100644
index 00000000000..2f9edba0015
--- /dev/null
+++ b/tests/lib/FilesMetadata/FilesMetadataManagerTest.php
@@ -0,0 +1,98 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Robin Appelman <robin@icewind.nl>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\FilesMetadata;
+
+use OC\BackgroundJob\JobList;
+use OC\Files\Storage\Temporary;
+use OC\FilesMetadata\FilesMetadataManager;
+use OC\FilesMetadata\Service\IndexRequestService;
+use OC\FilesMetadata\Service\MetadataRequestService;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\FilesMetadata\AMetadataEvent;
+use OCP\IAppConfig;
+use OCP\IDBConnection;
+use OCP\Server;
+use Psr\Log\LoggerInterface;
+use Test\TestCase;
+use Test\Traits\MountProviderTrait;
+use Test\Traits\UserTrait;
+
+/**
+ * @group DB
+ */
+class FilesMetadataManagerTest extends TestCase {
+ use UserTrait;
+ use MountProviderTrait;
+
+ private IEventDispatcher $eventDispatcher;
+ private JobList $jobList;
+ private IAppConfig $appConfig;
+ private LoggerInterface $logger;
+ private MetadataRequestService $metadataRequestService;
+ private IndexRequestService $indexRequestService;
+ private FilesMetadataManager $manager;
+ private IDBConnection $connection;
+ private Folder $userFolder;
+ private array $metadata = [];
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->jobList = $this->createMock(JobList::class);
+ $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+ $this->eventDispatcher->method('dispatchTyped')->willReturnCallback(function (Event $event) {
+ if ($event instanceof AMetadataEvent) {
+ $name = $event->getNode()->getName();
+ if (isset($this->metadata[$name])) {
+ $meta = $event->getMetadata();
+ foreach ($this->metadata[$name] as $key => $value) {
+ $meta->setString($key, $value);
+ }
+ }
+ }
+ });
+ $this->appConfig = $this->createMock(IAppConfig::class);
+ $this->logger = $this->createMock(LoggerInterface::class);
+
+ $this->connection = Server::get(IDBConnection::class);
+ $this->metadataRequestService = new MetadataRequestService($this->connection, $this->logger);
+ $this->indexRequestService = new IndexRequestService($this->connection, $this->logger);
+ $this->manager = new FilesMetadataManager(
+ $this->eventDispatcher,
+ $this->jobList,
+ $this->appConfig,
+ $this->logger,
+ $this->metadataRequestService,
+ $this->indexRequestService,
+ );
+
+ $this->createUser('metatest', '');
+ $this->registerMount('metatest', new Temporary([]), '/metatest');
+
+ $rootFolder = Server::get(IRootFolder::class);
+ $this->userFolder = $rootFolder->getUserFolder('metatest');
+ }
+
+ public function testRefreshMetadata(): void {
+ $this->metadata['test.txt'] = [
+ 'istest' => 'yes'
+ ];
+ $file = $this->userFolder->newFile('test.txt', 'test');
+ $stored = $this->manager->refreshMetadata($file);
+ $this->assertEquals($file->getId(), $stored->getFileId());
+ $this->assertEquals('yes', $stored->getString('istest'));
+
+ $retrieved = $this->manager->getMetadata($file->getId());
+ $this->assertEquals($file->getId(), $retrieved->getFileId());
+ $this->assertEquals('yes', $retrieved->getString('istest'));
+ }
+}