diff --git a/apps/files_trashbin/lib/Trash/TrashItem.php b/apps/files_trashbin/lib/Trash/TrashItem.php index 119cb9a82e41a..3830108f2448a 100644 --- a/apps/files_trashbin/lib/Trash/TrashItem.php +++ b/apps/files_trashbin/lib/Trash/TrashItem.php @@ -23,6 +23,7 @@ namespace OCA\Files_Trashbin\Trash; use OCP\Files\FileInfo; +use OCP\FilesMetadata\Model\IFilesMetadata; use OCP\IUser; class TrashItem implements ITrashItem { @@ -191,6 +192,10 @@ public function getParentId(): int { return $this->fileInfo->getParentId(); } + /** + * @inheritDoc + * @return IFilesMetadata[] + */ public function getMetadata(): array { return $this->fileInfo->getMetadata(); } diff --git a/core/Command/FilesMetadata/Get.php b/core/Command/FilesMetadata/Get.php index cb99fbc818d61..aebabe63e359f 100644 --- a/core/Command/FilesMetadata/Get.php +++ b/core/Command/FilesMetadata/Get.php @@ -26,8 +26,11 @@ namespace OC\Core\Command\FilesMetadata; +use OC\User\NoUserException; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; +use OCP\FilesMetadata\Exceptions\FilesMetadataNotFoundException; use OCP\FilesMetadata\IFilesMetadataManager; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -43,52 +46,63 @@ public function __construct( parent::__construct(); } - protected function configure() { + protected function configure(): void { $this->setName('metadata:get') ->setDescription('get stored metadata about a file, by its id') ->addArgument( - 'fileId', - InputArgument::REQUIRED, - 'id of the file document' + 'fileId', + InputArgument::REQUIRED, + 'id of the file document' ) ->addArgument( - 'userId', - InputArgument::OPTIONAL, - 'file owner' + 'userId', + InputArgument::OPTIONAL, + 'file owner' ) ->addOption( - 'as-array', - '', - InputOption::VALUE_NONE, - 'display metadata as a simple key=>value array' + 'as-array', + '', + InputOption::VALUE_NONE, + 'display metadata as a simple key=>value array' ) ->addOption( - 'refresh', - '', - InputOption::VALUE_NONE, - 'refresh metadata' - ) + 'refresh', + '', + InputOption::VALUE_NONE, + 'refresh metadata' + ) ->addOption( - 'reset', - '', - InputOption::VALUE_NONE, - 'refresh metadata from scratch' + 'reset', + '', + InputOption::VALUE_NONE, + 'refresh metadata from scratch' ); } + /** + * @throws NotPermittedException + * @throws FilesMetadataNotFoundException + * @throws NoUserException + * @throws NotFoundException + */ protected function execute(InputInterface $input, OutputInterface $output): int { $fileId = (int)$input->getArgument('fileId'); + + if ($input->getOption('reset')) { + $this->filesMetadataManager->deleteMetadata($fileId); + if (!$input->getOption('refresh')) { + return 0; + } + } + if ($input->getOption('refresh')) { $node = $this->rootFolder->getUserFolder($input->getArgument('userId'))->getById($fileId); - $file = $node[0]; - if (null === $file) { + if (count($node) === 0) { throw new NotFoundException(); } - $metadata = $this->filesMetadataManager->refreshMetadata( - $file, - IFilesMetadataManager::PROCESS_LIVE | IFilesMetadataManager::PROCESS_BACKGROUND, - $input->getOption('reset') + $node[0], + IFilesMetadataManager::PROCESS_LIVE | IFilesMetadataManager::PROCESS_BACKGROUND ); } else { $metadata = $this->filesMetadataManager->getMetadata($fileId); diff --git a/core/Migrations/Version28000Date20231004103301.php b/core/Migrations/Version28000Date20231004103301.php index c6a24d770f096..3266bf3a4407b 100644 --- a/core/Migrations/Version28000Date20231004103301.php +++ b/core/Migrations/Version28000Date20231004103301.php @@ -1,9 +1,8 @@ + * @copyright 2023 Maxence Lange * * @author Maxence Lange * @@ -33,10 +32,10 @@ use OCP\Migration\SimpleMigrationStep; class Version28000Date20231004103301 extends SimpleMigrationStep { - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { /** @var ISchemaWrapper $schema */ $schema = $schemaClosure(); + $updated = false; if (!$schema->hasTable('files_metadata')) { $table = $schema->createTable('files_metadata'); @@ -53,6 +52,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt $table->setPrimaryKey(['id']); $table->addUniqueIndex(['file_id'], 'files_meta_fileid'); + $updated = true; } if (!$schema->hasTable('files_metadata_index')) { @@ -65,14 +65,17 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt ]); $table->addColumn('file_id', Types::BIGINT, ['notnull' => false, 'length' => 15]); $table->addColumn('meta_key', Types::STRING, ['notnull' => false, 'length' => 31]); - $table->addColumn('meta_value', Types::STRING, ['notnull' => false, 'length' => 63]); + $table->addColumn('meta_value_string', Types::STRING, ['notnull' => false, 'length' => 63]); $table->addColumn('meta_value_int', Types::BIGINT, ['notnull' => false, 'length' => 11]); -// $table->addColumn('meta_value_float', Types::FLOAT, ['notnull' => false, 'length' => 11,5]); $table->setPrimaryKey(['id']); - $table->addIndex(['file_id', 'meta_key', 'meta_value'], 'f_meta_index'); + $table->addIndex(['file_id', 'meta_key', 'meta_value_string'], 'f_meta_index'); $table->addIndex(['file_id', 'meta_key', 'meta_value_int'], 'f_meta_index_i'); -// $table->addIndex(['file_id', 'meta_key', 'meta_value_float'], 'f_meta_index_f'); + $updated = true; + } + + if (!$updated) { + return null; } return $schema; diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index a1a42dd595d79..5f45df24bdfbb 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -284,6 +284,17 @@ 'OCP\\Federation\\ICloudId' => $baseDir . '/lib/public/Federation/ICloudId.php', 'OCP\\Federation\\ICloudIdManager' => $baseDir . '/lib/public/Federation/ICloudIdManager.php', 'OCP\\Files' => $baseDir . '/lib/public/Files.php', + 'OCP\\FilesMetadata\\AMetadataEvent' => $baseDir . '/lib/public/FilesMetadata/AMetadataEvent.php', + 'OCP\\FilesMetadata\\Event\\MetadataBackgroundEvent' => $baseDir . '/lib/public/FilesMetadata/Event/MetadataBackgroundEvent.php', + 'OCP\\FilesMetadata\\Event\\MetadataLiveEvent' => $baseDir . '/lib/public/FilesMetadata/Event/MetadataLiveEvent.php', + 'OCP\\FilesMetadata\\Exceptions\\FilesMetadataException' => $baseDir . '/lib/public/FilesMetadata/Exceptions/FilesMetadataException.php', + 'OCP\\FilesMetadata\\Exceptions\\FilesMetadataKeyFormatException' => $baseDir . '/lib/public/FilesMetadata/Exceptions/FilesMetadataKeyFormatException.php', + 'OCP\\FilesMetadata\\Exceptions\\FilesMetadataNotFoundException' => $baseDir . '/lib/public/FilesMetadata/Exceptions/FilesMetadataNotFoundException.php', + 'OCP\\FilesMetadata\\Exceptions\\FilesMetadataTypeException' => $baseDir . '/lib/public/FilesMetadata/Exceptions/FilesMetadataTypeException.php', + 'OCP\\FilesMetadata\\IFilesMetadataManager' => $baseDir . '/lib/public/FilesMetadata/IFilesMetadataManager.php', + 'OCP\\FilesMetadata\\Model\\IFilesMetadata' => $baseDir . '/lib/public/FilesMetadata/Model/IFilesMetadata.php', + 'OCP\\FilesMetadata\\Model\\IMetadataQuery' => $baseDir . '/lib/public/FilesMetadata/Model/IMetadataQuery.php', + 'OCP\\FilesMetadata\\Model\\IMetadataValueWrapper' => $baseDir . '/lib/public/FilesMetadata/Model/IMetadataValueWrapper.php', 'OCP\\Files\\AlreadyExistsException' => $baseDir . '/lib/public/Files/AlreadyExistsException.php', 'OCP\\Files\\AppData\\IAppDataFactory' => $baseDir . '/lib/public/Files/AppData/IAppDataFactory.php', 'OCP\\Files\\Cache\\AbstractCacheEvent' => $baseDir . '/lib/public/Files/Cache/AbstractCacheEvent.php', @@ -1022,6 +1033,7 @@ 'OC\\Core\\Command\\Encryption\\SetDefaultModule' => $baseDir . '/core/Command/Encryption/SetDefaultModule.php', 'OC\\Core\\Command\\Encryption\\ShowKeyStorageRoot' => $baseDir . '/core/Command/Encryption/ShowKeyStorageRoot.php', 'OC\\Core\\Command\\Encryption\\Status' => $baseDir . '/core/Command/Encryption/Status.php', + 'OC\\Core\\Command\\FilesMetadata\\Get' => $baseDir . '/core/Command/FilesMetadata/Get.php', 'OC\\Core\\Command\\Group\\Add' => $baseDir . '/core/Command/Group/Add.php', 'OC\\Core\\Command\\Group\\AddUser' => $baseDir . '/core/Command/Group/AddUser.php', 'OC\\Core\\Command\\Group\\Delete' => $baseDir . '/core/Command/Group/Delete.php', @@ -1194,6 +1206,7 @@ 'OC\\Core\\Migrations\\Version28000Date20230728104802' => $baseDir . '/core/Migrations/Version28000Date20230728104802.php', 'OC\\Core\\Migrations\\Version28000Date20230803221055' => $baseDir . '/core/Migrations/Version28000Date20230803221055.php', 'OC\\Core\\Migrations\\Version28000Date20230906104802' => $baseDir . '/core/Migrations/Version28000Date20230906104802.php', + 'OC\\Core\\Migrations\\Version28000Date20231004103301' => $baseDir . '/core/Migrations/Version28000Date20231004103301.php', 'OC\\Core\\Notification\\CoreNotifier' => $baseDir . '/core/Notification/CoreNotifier.php', 'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php', 'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php', @@ -1278,6 +1291,15 @@ 'OC\\Federation\\CloudFederationShare' => $baseDir . '/lib/private/Federation/CloudFederationShare.php', 'OC\\Federation\\CloudId' => $baseDir . '/lib/private/Federation/CloudId.php', 'OC\\Federation\\CloudIdManager' => $baseDir . '/lib/private/Federation/CloudIdManager.php', + 'OC\\FilesMetadata\\FilesMetadataManager' => $baseDir . '/lib/private/FilesMetadata/FilesMetadataManager.php', + 'OC\\FilesMetadata\\Job\\UpdateSingleMetadata' => $baseDir . '/lib/private/FilesMetadata/Job/UpdateSingleMetadata.php', + 'OC\\FilesMetadata\\Listener\\MetadataDelete' => $baseDir . '/lib/private/FilesMetadata/Listener/MetadataDelete.php', + 'OC\\FilesMetadata\\Listener\\MetadataUpdate' => $baseDir . '/lib/private/FilesMetadata/Listener/MetadataUpdate.php', + 'OC\\FilesMetadata\\Model\\FilesMetadata' => $baseDir . '/lib/private/FilesMetadata/Model/FilesMetadata.php', + 'OC\\FilesMetadata\\Model\\MetadataQuery' => $baseDir . '/lib/private/FilesMetadata/Model/MetadataQuery.php', + 'OC\\FilesMetadata\\Model\\MetadataValueWrapper' => $baseDir . '/lib/private/FilesMetadata/Model/MetadataValueWrapper.php', + 'OC\\FilesMetadata\\Service\\IndexRequestService' => $baseDir . '/lib/private/FilesMetadata/Service/IndexRequestService.php', + 'OC\\FilesMetadata\\Service\\MetadataRequestService' => $baseDir . '/lib/private/FilesMetadata/Service/MetadataRequestService.php', 'OC\\Files\\AppData\\AppData' => $baseDir . '/lib/private/Files/AppData/AppData.php', 'OC\\Files\\AppData\\Factory' => $baseDir . '/lib/private/Files/AppData/Factory.php', 'OC\\Files\\Cache\\Cache' => $baseDir . '/lib/private/Files/Cache/Cache.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 421e9b775b581..6f0eaa0ffd06b 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -317,6 +317,17 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\Federation\\ICloudId' => __DIR__ . '/../../..' . '/lib/public/Federation/ICloudId.php', 'OCP\\Federation\\ICloudIdManager' => __DIR__ . '/../../..' . '/lib/public/Federation/ICloudIdManager.php', 'OCP\\Files' => __DIR__ . '/../../..' . '/lib/public/Files.php', + 'OCP\\FilesMetadata\\AMetadataEvent' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/AMetadataEvent.php', + 'OCP\\FilesMetadata\\Event\\MetadataBackgroundEvent' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Event/MetadataBackgroundEvent.php', + 'OCP\\FilesMetadata\\Event\\MetadataLiveEvent' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Event/MetadataLiveEvent.php', + 'OCP\\FilesMetadata\\Exceptions\\FilesMetadataException' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Exceptions/FilesMetadataException.php', + 'OCP\\FilesMetadata\\Exceptions\\FilesMetadataKeyFormatException' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Exceptions/FilesMetadataKeyFormatException.php', + 'OCP\\FilesMetadata\\Exceptions\\FilesMetadataNotFoundException' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Exceptions/FilesMetadataNotFoundException.php', + 'OCP\\FilesMetadata\\Exceptions\\FilesMetadataTypeException' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Exceptions/FilesMetadataTypeException.php', + 'OCP\\FilesMetadata\\IFilesMetadataManager' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/IFilesMetadataManager.php', + 'OCP\\FilesMetadata\\Model\\IFilesMetadata' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Model/IFilesMetadata.php', + 'OCP\\FilesMetadata\\Model\\IMetadataQuery' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Model/IMetadataQuery.php', + 'OCP\\FilesMetadata\\Model\\IMetadataValueWrapper' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Model/IMetadataValueWrapper.php', 'OCP\\Files\\AlreadyExistsException' => __DIR__ . '/../../..' . '/lib/public/Files/AlreadyExistsException.php', 'OCP\\Files\\AppData\\IAppDataFactory' => __DIR__ . '/../../..' . '/lib/public/Files/AppData/IAppDataFactory.php', 'OCP\\Files\\Cache\\AbstractCacheEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/AbstractCacheEvent.php', @@ -1055,6 +1066,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Core\\Command\\Encryption\\SetDefaultModule' => __DIR__ . '/../../..' . '/core/Command/Encryption/SetDefaultModule.php', 'OC\\Core\\Command\\Encryption\\ShowKeyStorageRoot' => __DIR__ . '/../../..' . '/core/Command/Encryption/ShowKeyStorageRoot.php', 'OC\\Core\\Command\\Encryption\\Status' => __DIR__ . '/../../..' . '/core/Command/Encryption/Status.php', + 'OC\\Core\\Command\\FilesMetadata\\Get' => __DIR__ . '/../../..' . '/core/Command/FilesMetadata/Get.php', 'OC\\Core\\Command\\Group\\Add' => __DIR__ . '/../../..' . '/core/Command/Group/Add.php', 'OC\\Core\\Command\\Group\\AddUser' => __DIR__ . '/../../..' . '/core/Command/Group/AddUser.php', 'OC\\Core\\Command\\Group\\Delete' => __DIR__ . '/../../..' . '/core/Command/Group/Delete.php', @@ -1227,6 +1239,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Core\\Migrations\\Version28000Date20230728104802' => __DIR__ . '/../../..' . '/core/Migrations/Version28000Date20230728104802.php', 'OC\\Core\\Migrations\\Version28000Date20230803221055' => __DIR__ . '/../../..' . '/core/Migrations/Version28000Date20230803221055.php', 'OC\\Core\\Migrations\\Version28000Date20230906104802' => __DIR__ . '/../../..' . '/core/Migrations/Version28000Date20230906104802.php', + 'OC\\Core\\Migrations\\Version28000Date20231004103301' => __DIR__ . '/../../..' . '/core/Migrations/Version28000Date20231004103301.php', 'OC\\Core\\Notification\\CoreNotifier' => __DIR__ . '/../../..' . '/core/Notification/CoreNotifier.php', 'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php', 'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php', @@ -1311,6 +1324,15 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Federation\\CloudFederationShare' => __DIR__ . '/../../..' . '/lib/private/Federation/CloudFederationShare.php', 'OC\\Federation\\CloudId' => __DIR__ . '/../../..' . '/lib/private/Federation/CloudId.php', 'OC\\Federation\\CloudIdManager' => __DIR__ . '/../../..' . '/lib/private/Federation/CloudIdManager.php', + 'OC\\FilesMetadata\\FilesMetadataManager' => __DIR__ . '/../../..' . '/lib/private/FilesMetadata/FilesMetadataManager.php', + 'OC\\FilesMetadata\\Job\\UpdateSingleMetadata' => __DIR__ . '/../../..' . '/lib/private/FilesMetadata/Job/UpdateSingleMetadata.php', + 'OC\\FilesMetadata\\Listener\\MetadataDelete' => __DIR__ . '/../../..' . '/lib/private/FilesMetadata/Listener/MetadataDelete.php', + 'OC\\FilesMetadata\\Listener\\MetadataUpdate' => __DIR__ . '/../../..' . '/lib/private/FilesMetadata/Listener/MetadataUpdate.php', + 'OC\\FilesMetadata\\Model\\FilesMetadata' => __DIR__ . '/../../..' . '/lib/private/FilesMetadata/Model/FilesMetadata.php', + 'OC\\FilesMetadata\\Model\\MetadataQuery' => __DIR__ . '/../../..' . '/lib/private/FilesMetadata/Model/MetadataQuery.php', + 'OC\\FilesMetadata\\Model\\MetadataValueWrapper' => __DIR__ . '/../../..' . '/lib/private/FilesMetadata/Model/MetadataValueWrapper.php', + 'OC\\FilesMetadata\\Service\\IndexRequestService' => __DIR__ . '/../../..' . '/lib/private/FilesMetadata/Service/IndexRequestService.php', + 'OC\\FilesMetadata\\Service\\MetadataRequestService' => __DIR__ . '/../../..' . '/lib/private/FilesMetadata/Service/MetadataRequestService.php', 'OC\\Files\\AppData\\AppData' => __DIR__ . '/../../..' . '/lib/private/Files/AppData/AppData.php', 'OC\\Files\\AppData\\Factory' => __DIR__ . '/../../..' . '/lib/private/Files/AppData/Factory.php', 'OC\\Files\\Cache\\Cache' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Cache.php', diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index 49e4c25c450f0..67d01bb699907 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -169,9 +169,6 @@ public function get($file) { $data = $result->fetch(); $result->closeCursor(); - // @Louis: use asArray() -// $data['metadata'] = $metadataQuery?->extractMetadata($data)?->asArray() ?? []; - //merge partial data if (!$data && is_string($file) && isset($this->partial[$file])) { return $this->partial[$file]; diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php index 22c923f4b69f3..5d0422d6efdd3 100644 --- a/lib/private/Files/Cache/QuerySearchHelper.php +++ b/lib/private/Files/Cache/QuerySearchHelper.php @@ -143,7 +143,11 @@ protected function equipQueryForMetadata(CacheQueryBuilder $query, ISearchQuery $order = $searchQuery->getOrder(); if ($order) { foreach ($order as $orderField) { - $metadataQuery->joinIndex($orderField->getField()); + $field = $orderField->getField(); + if (!str_starts_with($field, 'metakey_')) { + continue; + } + $metadataQuery->joinIndex(substr($field, 8)); $query->orderBy($metadataQuery->getMetadataValueIntField(), $orderField->getDirection()); } } diff --git a/lib/private/Files/FileInfo.php b/lib/private/Files/FileInfo.php index 3fe9ba7d974c0..6718c481d84e6 100644 --- a/lib/private/Files/FileInfo.php +++ b/lib/private/Files/FileInfo.php @@ -32,11 +32,11 @@ */ namespace OC\Files; -use OC\FilesMetadata\Model\FilesMetadata; use OCA\Files_Sharing\ISharedStorage; use OCP\Files\Cache\ICacheEntry; use OCP\Files\IHomeStorage; use OCP\Files\Mount\IMountPoint; +use OCP\FilesMetadata\Model\IFilesMetadata; use OCP\IUser; class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { @@ -418,6 +418,10 @@ public function getParentId(): int { return $this->data['parent'] ?? -1; } + /** + * @inheritDoc + * @return IFilesMetadata[] + */ public function getMetadata(): array { return $this->data['metadata'] ?? []; } diff --git a/lib/private/Files/Node/LazyFolder.php b/lib/private/Files/Node/LazyFolder.php index ee0d1cfd3cfd9..48ca7ff6a37e3 100644 --- a/lib/private/Files/Node/LazyFolder.php +++ b/lib/private/Files/Node/LazyFolder.php @@ -33,6 +33,7 @@ use OCP\Files\IRootFolder; use OCP\Files\Mount\IMountPoint; use OCP\Files\NotPermittedException; +use OCP\FilesMetadata\Model\IFilesMetadata; /** * Class LazyFolder @@ -575,6 +576,10 @@ public function getParentId(): int { return $this->__call(__FUNCTION__, func_get_args()); } + /** + * @inheritDoc + * @return IFilesMetadata[] + */ public function getMetadata(): array { return $this->data['metadata'] ?? $this->__call(__FUNCTION__, func_get_args()); } diff --git a/lib/private/Files/Node/Node.php b/lib/private/Files/Node/Node.php index b376f1de19a15..ce61f42251c19 100644 --- a/lib/private/Files/Node/Node.php +++ b/lib/private/Files/Node/Node.php @@ -40,6 +40,7 @@ use OCP\Files\Node as INode; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCP\FilesMetadata\Model\IFilesMetadata; use OCP\Lock\LockedException; use OCP\PreConditionNotMetException; @@ -491,6 +492,10 @@ public function getParentId(): int { return $this->fileInfo->getParentId(); } + /** + * @inheritDoc + * @return IFilesMetadata[] + */ public function getMetadata(): array { return $this->fileInfo->getMetadata(); } diff --git a/lib/private/FilesMetadata/FilesMetadataManager.php b/lib/private/FilesMetadata/FilesMetadataManager.php index 6bd6e8aa099d6..7b3a5681110a3 100644 --- a/lib/private/FilesMetadata/FilesMetadataManager.php +++ b/lib/private/FilesMetadata/FilesMetadataManager.php @@ -73,7 +73,6 @@ public function __construct( * * @param Node $node related node * @param int $process type of process - * @param bool $fromScratch reset known metadata first * * @return IFilesMetadata * @throws FilesMetadataException if metadata are invalid @@ -85,13 +84,8 @@ public function __construct( */ public function refreshMetadata( Node $node, - int $process = self::PROCESS_LIVE, - bool $fromScratch = false, + int $process = self::PROCESS_LIVE ): IFilesMetadata { - if ($fromScratch) { - $this->deleteMetadata($node->getId()); - } - try { $metadata = $this->metadataRequestService->getMetadataFromFileId($node->getId()); } catch (FilesMetadataNotFoundException) { @@ -134,7 +128,7 @@ public function getMetadata(int $fileId): IFilesMetadata { } /** - * @param IFilesMetadata $filesMetadata + * @param IFilesMetadata $filesMetadata metadata * * @inheritDoc * @throws FilesMetadataException if metadata seems malformed @@ -169,7 +163,11 @@ public function saveMetadata(IFilesMetadata $filesMetadata): void { } foreach ($filesMetadata->getIndexes() as $index) { - $this->indexRequestService->updateIndex($filesMetadata, $index); + try { + $this->indexRequestService->updateIndex($filesMetadata, $index); + } catch (DBException $e) { + $this->logger->warning('issue while updateIndex', ['exception' => $e]); + } } } @@ -193,7 +191,6 @@ public function deleteMetadata(int $fileId): void { } } - /** * @param IQueryBuilder $qb * @param string $fileTableAlias alias of the table that contains data about files diff --git a/lib/private/FilesMetadata/Listener/MetadataDelete.php b/lib/private/FilesMetadata/Listener/MetadataDelete.php index 75a08fbb34bf9..7f8fd03573503 100644 --- a/lib/private/FilesMetadata/Listener/MetadataDelete.php +++ b/lib/private/FilesMetadata/Listener/MetadataDelete.php @@ -33,6 +33,8 @@ /** * Handle file deletion event and remove stored metadata related to the deleted file + * + * @template-implements IEventListener */ class MetadataDelete implements IEventListener { public function __construct( diff --git a/lib/private/FilesMetadata/Listener/MetadataUpdate.php b/lib/private/FilesMetadata/Listener/MetadataUpdate.php index 9f544fbe34fc6..64c8bb474b15f 100644 --- a/lib/private/FilesMetadata/Listener/MetadataUpdate.php +++ b/lib/private/FilesMetadata/Listener/MetadataUpdate.php @@ -36,6 +36,8 @@ * Handle file creation/modification events and initiate a new event related to the created/edited file. * The generated new event is broadcast in order to obtain file related metadata from other apps. * metadata will be stored in database. + * + * @template-implements IEventListener */ class MetadataUpdate implements IEventListener { public function __construct( diff --git a/lib/private/FilesMetadata/Model/FilesMetadata.php b/lib/private/FilesMetadata/Model/FilesMetadata.php index 4187166617465..24e9c355e1263 100644 --- a/lib/private/FilesMetadata/Model/FilesMetadata.php +++ b/lib/private/FilesMetadata/Model/FilesMetadata.php @@ -39,7 +39,6 @@ * @since 28.0.0 */ class FilesMetadata implements IFilesMetadata { - /** @var array */ private array $metadata = []; private bool $updated = false; diff --git a/lib/private/FilesMetadata/Model/MetadataQuery.php b/lib/private/FilesMetadata/Model/MetadataQuery.php index d20a77bb51926..11904b8329993 100644 --- a/lib/private/FilesMetadata/Model/MetadataQuery.php +++ b/lib/private/FilesMetadata/Model/MetadataQuery.php @@ -69,10 +69,11 @@ public function retrieveMetadata(): void { */ public function extractMetadata(array $row): IFilesMetadata { $fileId = (array_key_exists($this->fileIdField, $row)) ? $row[$this->fileIdField] : 0; - $metadata = new FilesMetadata($fileId); + $metadata = new FilesMetadata((int)$fileId); try { $metadata->importFromDatabase($row, $this->alias . '_'); - } catch (FilesMetadataNotFoundException $e) { + } catch (FilesMetadataNotFoundException) { + // can be ignored as files' metadata are optional and might not exist in database } return $metadata; @@ -85,7 +86,7 @@ public function extractMetadata(array $row): IFilesMetadata { * @inheritDoc * @since 28.0.0 */ - public function joinIndex(string $metadataKey = '', bool $enforce = false): void { + public function joinIndex(string $metadataKey, bool $enforce = false): void { $expr = $this->queryBuilder->expr(); $andX = $expr->andX($expr->eq($this->aliasIndex . '.file_id', $this->fileTableAlias . '.' . $this->fileIdField)); $andX->add($expr->eq($this->getMetadataKeyField(), $this->queryBuilder->createNamedParameter($metadataKey))); @@ -107,22 +108,6 @@ public function joinIndex(string $metadataKey = '', bool $enforce = false): void } } - /** - * @param string $metadataKey metadata key - * - * @inheritDoc - * @since 28.0.0 - */ - public function enforceMetadataKey(string $metadataKey): void { - $expr = $this->queryBuilder->expr(); - $this->queryBuilder->andWhere( - $expr->eq( - $this->getMetadataKeyField(), - $this->queryBuilder->createNamedParameter($metadataKey) - ) - ); - } - /** * @param string $value metadata value * @inheritDoc @@ -132,7 +117,7 @@ public function enforceMetadataValue(string $value): void { $expr = $this->queryBuilder->expr(); $this->queryBuilder->andWhere( $expr->eq( - $this->getMetadataKeyField(), + $this->getMetadataValueField(), $this->queryBuilder->createNamedParameter($value) ) ); @@ -168,7 +153,7 @@ public function getMetadataKeyField(): string { * @since 28.0.0 */ public function getMetadataValueField(): string { - return $this->aliasIndex . '.meta_value'; + return $this->aliasIndex . '.meta_value_string'; } /** diff --git a/lib/private/FilesMetadata/Model/MetadataValueWrapper.php b/lib/private/FilesMetadata/Model/MetadataValueWrapper.php index 7c39d2e7d2a1e..d3c4cd321413e 100644 --- a/lib/private/FilesMetadata/Model/MetadataValueWrapper.php +++ b/lib/private/FilesMetadata/Model/MetadataValueWrapper.php @@ -106,11 +106,9 @@ public function isType(string $type): bool { * @see self::TYPE_FLOAT * @since 28.0.0 */ - public function confirmType(string $type): self { + public function assertType(string $type): self { if (!$this->isType($type)) { - throw new FilesMetadataTypeException( - 'type is \'' . $this->getType() . '\', expecting \'' . $type . '\'' - ); + throw new FilesMetadataTypeException('type is \'' . $this->getType() . '\', expecting \'' . $type . '\''); } return $this; @@ -125,7 +123,7 @@ public function confirmType(string $type): self { * @since 28.0.0 */ public function setValueString(string $value): self { - $this->confirmType(self::TYPE_STRING); + $this->assertType(self::TYPE_STRING); $this->value = $value; return $this; @@ -140,7 +138,7 @@ public function setValueString(string $value): self { * @since 28.0.0 */ public function setValueInt(int $value): self { - $this->confirmType(self::TYPE_INT); + $this->assertType(self::TYPE_INT); $this->value = $value; @@ -156,7 +154,7 @@ public function setValueInt(int $value): self { * @since 28.0.0 */ public function setValueFloat(float $value): self { - $this->confirmType(self::TYPE_FLOAT); + $this->assertType(self::TYPE_FLOAT); $this->value = $value; @@ -172,7 +170,7 @@ public function setValueFloat(float $value): self { * @since 28.0.0 */ public function setValueBool(bool $value): self { - $this->confirmType(self::TYPE_BOOL); + $this->assertType(self::TYPE_BOOL); $this->value = $value; @@ -188,7 +186,7 @@ public function setValueBool(bool $value): self { * @since 28.0.0 */ public function setValueArray(array $value): self { - $this->confirmType(self::TYPE_ARRAY); + $this->assertType(self::TYPE_ARRAY); $this->value = $value; @@ -204,7 +202,7 @@ public function setValueArray(array $value): self { * @since 28.0.0 */ public function setValueStringList(array $value): self { - $this->confirmType(self::TYPE_STRING_LIST); + $this->assertType(self::TYPE_STRING_LIST); // TODO confirm value is an array or string ? $this->value = $value; @@ -220,7 +218,7 @@ public function setValueStringList(array $value): self { * @since 28.0.0 */ public function setValueIntList(array $value): self { - $this->confirmType(self::TYPE_INT_LIST); + $this->assertType(self::TYPE_INT_LIST); // TODO confirm value is an array of int ? $this->value = $value; @@ -236,7 +234,7 @@ public function setValueIntList(array $value): self { * @since 28.0.0 */ public function getValueString(): string { - $this->confirmType(self::TYPE_STRING); + $this->assertType(self::TYPE_STRING); if (null === $this->value) { throw new FilesMetadataNotFoundException('value is not set'); } @@ -252,7 +250,7 @@ public function getValueString(): string { * @since 28.0.0 */ public function getValueInt(): int { - $this->confirmType(self::TYPE_INT); + $this->assertType(self::TYPE_INT); if (null === $this->value) { throw new FilesMetadataNotFoundException('value is not set'); } @@ -268,7 +266,7 @@ public function getValueInt(): int { * @since 28.0.0 */ public function getValueFloat(): float { - $this->confirmType(self::TYPE_FLOAT); + $this->assertType(self::TYPE_FLOAT); if (null === $this->value) { throw new FilesMetadataNotFoundException('value is not set'); } @@ -284,7 +282,7 @@ public function getValueFloat(): float { * @since 28.0.0 */ public function getValueBool(): bool { - $this->confirmType(self::TYPE_BOOL); + $this->assertType(self::TYPE_BOOL); if (null === $this->value) { throw new FilesMetadataNotFoundException('value is not set'); } @@ -300,7 +298,7 @@ public function getValueBool(): bool { * @since 28.0.0 */ public function getValueArray(): array { - $this->confirmType(self::TYPE_ARRAY); + $this->assertType(self::TYPE_ARRAY); if (null === $this->value) { throw new FilesMetadataNotFoundException('value is not set'); } @@ -316,7 +314,7 @@ public function getValueArray(): array { * @since 28.0.0 */ public function getValueStringList(): array { - $this->confirmType(self::TYPE_STRING_LIST); + $this->assertType(self::TYPE_STRING_LIST); if (null === $this->value) { throw new FilesMetadataNotFoundException('value is not set'); } @@ -332,7 +330,7 @@ public function getValueStringList(): array { * @since 28.0.0 */ public function getValueIntList(): array { - $this->confirmType(self::TYPE_INT_LIST); + $this->assertType(self::TYPE_INT_LIST); if (null === $this->value) { throw new FilesMetadataNotFoundException('value is not set'); } diff --git a/lib/private/FilesMetadata/Service/IndexRequestService.php b/lib/private/FilesMetadata/Service/IndexRequestService.php index 90fc6d089154e..6530dabd1c3d9 100644 --- a/lib/private/FilesMetadata/Service/IndexRequestService.php +++ b/lib/private/FilesMetadata/Service/IndexRequestService.php @@ -52,40 +52,40 @@ public function __construct( * @param IFilesMetadata $filesMetadata metadata * @param string $key metadata key to update * - * @return void + * @throws DbException */ public function updateIndex(IFilesMetadata $filesMetadata, string $key): void { $fileId = $filesMetadata->getFileId(); + try { + $metadataType = $filesMetadata->getType($key); + } catch (FilesMetadataNotFoundException $e) { + return; + } /** * might look harsh, but a lot simpler than comparing current indexed data, as we can expect * conflict with a change of types. * We assume that each time one random metadata were modified we can drop all index for this - * key and recreate them + * key and recreate them. + * To make it slightly cleaner, we'll use transaction */ + $this->dbConnection->beginTransaction(); try { $this->dropIndex($fileId, $key); - } catch (DbException $e) { - $this->logger->warning('issue while dropIndex', ['exception' => $e, 'fileId' => $fileId, 'key' => $key]); - return; - } - - try { - match ($filesMetadata->getType($key)) { - IMetadataValueWrapper::TYPE_STRING - => $this->insertIndexString($fileId, $key, $filesMetadata->get($key)), - IMetadataValueWrapper::TYPE_INT - => $this->insertIndexInt($fileId, $key, $filesMetadata->getInt($key)), - IMetadataValueWrapper::TYPE_STRING_LIST - => $this->insertIndexStringList($fileId, $key, $filesMetadata->getStringList($key)), - IMetadataValueWrapper::TYPE_INT_LIST - => $this->insertIndexIntList($fileId, $key, $filesMetadata->getIntList($key)) + match ($metadataType) { + IMetadataValueWrapper::TYPE_STRING => $this->insertIndexString($fileId, $key, $filesMetadata->get($key)), + IMetadataValueWrapper::TYPE_INT => $this->insertIndexInt($fileId, $key, $filesMetadata->getInt($key)), + IMetadataValueWrapper::TYPE_BOOL => $this->insertIndexBool($fileId, $key, $filesMetadata->getBool($key)), + IMetadataValueWrapper::TYPE_STRING_LIST => $this->insertIndexStringList($fileId, $key, $filesMetadata->getStringList($key)), + IMetadataValueWrapper::TYPE_INT_LIST => $this->insertIndexIntList($fileId, $key, $filesMetadata->getIntList($key)) }; - } catch (DbException|FilesMetadataNotFoundException|FilesMetadataTypeException $e) { - $this->logger->warning('issue while insertIndex', ['exception' => $e, 'fileId' => $fileId, 'key' => $key, 'metadata' => $filesMetadata]); + } catch (FilesMetadataNotFoundException|FilesMetadataTypeException|DbException $e) { + $this->dbConnection->rollBack(); + $this->logger->warning('issue while updateIndex', ['exception' => $e, 'fileId' => $fileId, 'key' => $key]); } - } + $this->dbConnection->commit(); + } /** * insert a new entry in the metadata_index table for a string value @@ -100,7 +100,7 @@ private function insertIndexString(int $fileId, string $key, string $value): voi $qb = $this->dbConnection->getQueryBuilder(); $qb->insert(self::TABLE_METADATA_INDEX) ->setValue('meta_key', $qb->createNamedParameter($key)) - ->setValue('meta_value', $qb->createNamedParameter($value)) + ->setValue('meta_value_string', $qb->createNamedParameter($value)) ->setValue('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)); $qb->executeStatement(); } @@ -123,6 +123,24 @@ public function insertIndexInt(int $fileId, string $key, int $value): void { $qb->executeStatement(); } + /** + * insert a new entry in the metadata_index table for a bool value + * + * @param int $fileId file id + * @param string $key metadata key + * @param bool $value metadata value + * + * @throws DbException + */ + public function insertIndexBool(int $fileId, string $key, bool $value): void { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->insert(self::TABLE_METADATA_INDEX) + ->setValue('meta_key', $qb->createNamedParameter($key)) + ->setValue('meta_value_int', $qb->createNamedParameter(($value) ? '1' : '0', IQueryBuilder::PARAM_INT)) + ->setValue('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)); + $qb->executeStatement(); + } + /** * insert entries in the metadata_index table for list of string * diff --git a/lib/private/FilesMetadata/Service/MetadataRequestService.php b/lib/private/FilesMetadata/Service/MetadataRequestService.php index 09135618c1aba..0a20e93487e89 100644 --- a/lib/private/FilesMetadata/Service/MetadataRequestService.php +++ b/lib/private/FilesMetadata/Service/MetadataRequestService.php @@ -58,7 +58,7 @@ public function store(IFilesMetadata $filesMetadata): void { ->setValue('file_id', $qb->createNamedParameter($filesMetadata->getFileId(), IQueryBuilder::PARAM_INT)) ->setValue('json', $qb->createNamedParameter(json_encode($filesMetadata->jsonSerialize()))) ->setValue('sync_token', $qb->createNamedParameter($this->generateSyncToken())) - ->setValue('last_update', $qb->createFunction('NOW()')); + ->setValue('last_update', $qb->createNamedParameter($qb->createFunction('NOW()'))); $qb->executeStatement(); } @@ -141,7 +141,6 @@ public function updateMetadata(IFilesMetadata $filesMetadata): int { /** * generate a random token * @return string - * @throws \Exception */ private function generateSyncToken(): string { $chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890'; @@ -151,7 +150,8 @@ private function generateSyncToken(): string { for ($i = 0; $i < 7; $i++) { try { $str .= $chars[random_int(0, $max - 2)]; - } catch (Exception $e) { + } catch (\Exception $e) { + $this->logger->warning('exception during generateSyncToken', ['exception' => $e]); } } diff --git a/lib/public/Files/FileInfo.php b/lib/public/Files/FileInfo.php index 5088458ef2d63..d448799ee82d7 100644 --- a/lib/public/Files/FileInfo.php +++ b/lib/public/Files/FileInfo.php @@ -29,6 +29,7 @@ namespace OCP\Files; use OCP\Files\Storage\IStorage; +use OCP\FilesMetadata\Model\IFilesMetadata; /** * Interface FileInfo @@ -312,7 +313,7 @@ public function getParentId(): int; /** * Get the metadata, if available * - * @return array + * @return IFilesMetadata[] * @since 28.0.0 */ public function getMetadata(): array; diff --git a/lib/private/FilesMetadata/Event/MetadataEventBase.php b/lib/public/FilesMetadata/AMetadataEvent.php similarity index 87% rename from lib/private/FilesMetadata/Event/MetadataEventBase.php rename to lib/public/FilesMetadata/AMetadataEvent.php index 2b97a813678eb..87abc60a983db 100644 --- a/lib/private/FilesMetadata/Event/MetadataEventBase.php +++ b/lib/public/FilesMetadata/AMetadataEvent.php @@ -23,20 +23,24 @@ * */ -namespace OC\FilesMetadata\Event; +namespace OCP\FilesMetadata; -use OCP\Files\Node; use OCP\EventDispatcher\Event; +use OCP\Files\Node; use OCP\FilesMetadata\Model\IFilesMetadata; /** * @since 28.0.0 */ -class MetadataEventBase extends Event { - +abstract class AMetadataEvent extends Event { + /** + * @param Node $node + * @param IFilesMetadata $metadata + * @since 28.0.0 + */ public function __construct( - protected Node $node, - protected IFilesMetadata $metadata + private Node $node, + private IFilesMetadata $metadata ) { parent::__construct(); } diff --git a/lib/public/FilesMetadata/Event/MetadataBackgroundEvent.php b/lib/public/FilesMetadata/Event/MetadataBackgroundEvent.php index c255e2105d1cc..3d175994c3213 100644 --- a/lib/public/FilesMetadata/Event/MetadataBackgroundEvent.php +++ b/lib/public/FilesMetadata/Event/MetadataBackgroundEvent.php @@ -25,24 +25,16 @@ namespace OCP\FilesMetadata\Event; -use OC\FilesMetadata\Event\MetadataEventBase; -use OCP\Files\Node; -use OCP\FilesMetadata\Model\IFilesMetadata; +use OCP\FilesMetadata\AMetadataEvent; /** * MetadataBackgroundEvent is an event similar to MetadataLiveEvent but dispatched * on a background thread instead of live thread. Meaning there is no limit to * the time required for the generation of your metadata. * - * @see MetadataEventBase::getMetadata() - * @see MetadataEventBase::getNode() + * @see AMetadataEvent::getMetadata() + * @see AMetadataEvent::getNode() * @since 28.0.0 */ -class MetadataBackgroundEvent extends MetadataEventBase { - public function __construct( - Node $node, - IFilesMetadata $metadata - ) { - parent::__construct($node, $metadata); - } +class MetadataBackgroundEvent extends AMetadataEvent { } diff --git a/lib/public/FilesMetadata/Event/MetadataLiveEvent.php b/lib/public/FilesMetadata/Event/MetadataLiveEvent.php index 3c02bb9692684..a89692fde9271 100644 --- a/lib/public/FilesMetadata/Event/MetadataLiveEvent.php +++ b/lib/public/FilesMetadata/Event/MetadataLiveEvent.php @@ -25,9 +25,7 @@ namespace OCP\FilesMetadata\Event; -use OC\FilesMetadata\Event\MetadataEventBase; -use OCP\Files\Node; -use OCP\FilesMetadata\Model\IFilesMetadata; +use OCP\FilesMetadata\AMetadataEvent; /** * MetadataLiveEvent is an event initiated when a file is created or updated. @@ -35,23 +33,16 @@ * contains the currently known metadata. * * Setting new metadata, or modifying already existing metadata with different value, will trigger - * the save of the metadata in the databas. + * the save of the metadata in the database. * - * @see MetadataEventBase::getMetadata() - * @see MetadataEventBase::getNode() + * @see AMetadataEvent::getMetadata() + * @see AMetadataEvent::getNode() * @see MetadataLiveEvent::requestBackgroundJob() * @since 28.0.0 */ -class MetadataLiveEvent extends MetadataEventBase { +class MetadataLiveEvent extends AMetadataEvent { private bool $runAsBackgroundJob = false; - public function __construct( - Node $node, - IFilesMetadata $metadata - ) { - parent::__construct($node, $metadata); - } - /** * For heavy process, call this method if your app prefers to update metadata on a * background/cron job, instead of the live process. diff --git a/lib/public/FilesMetadata/IFilesMetadataManager.php b/lib/public/FilesMetadata/IFilesMetadataManager.php index 229ddd2fa2ed0..a03ab868fdeca 100644 --- a/lib/public/FilesMetadata/IFilesMetadataManager.php +++ b/lib/public/FilesMetadata/IFilesMetadataManager.php @@ -38,6 +38,9 @@ * @since 28.0.0 */ interface IFilesMetadataManager { + /** + * @since 28.0.0 + */ public const PROCESS_LIVE = 1; public const PROCESS_BACKGROUND = 2; @@ -52,7 +55,6 @@ interface IFilesMetadataManager { * * @param Node $node related node * @param int $process type of process - * @param bool $fromScratch reset known metadata first * * @return IFilesMetadata * @see self::PROCESS_BACKGROUND @@ -61,8 +63,7 @@ interface IFilesMetadataManager { */ public function refreshMetadata( Node $node, - int $process = self::PROCESS_LIVE, - bool $fromScratch = false + int $process = self::PROCESS_LIVE ): IFilesMetadata; /** diff --git a/lib/public/FilesMetadata/Model/IFilesMetadata.php b/lib/public/FilesMetadata/Model/IFilesMetadata.php index e7963eda39a14..bb2e54a32528c 100644 --- a/lib/public/FilesMetadata/Model/IFilesMetadata.php +++ b/lib/public/FilesMetadata/Model/IFilesMetadata.php @@ -26,7 +26,6 @@ namespace OCP\FilesMetadata\Model; use JsonSerializable; -use OC\FilesMetadata\Model\MetadataValueWrapper; use OCP\FilesMetadata\Exceptions\FilesMetadataNotFoundException; use OCP\FilesMetadata\Exceptions\FilesMetadataTypeException; @@ -234,6 +233,7 @@ public function setInt(string $key, int $value, bool $index = false): self; * @param float $value metadata value * * @return self + * @since 28.0.0 */ public function setFloat(string $key, float $value): self; @@ -300,6 +300,7 @@ public function unset(string $key): self; * @param string $keyPrefix metadata key prefix * * @return self + * @since 28.0.0 */ public function removeStartsWith(string $keyPrefix): self; diff --git a/lib/public/FilesMetadata/Model/IMetadataQuery.php b/lib/public/FilesMetadata/Model/IMetadataQuery.php index 41db26e3bc95d..dc58ae359b59d 100644 --- a/lib/public/FilesMetadata/Model/IMetadataQuery.php +++ b/lib/public/FilesMetadata/Model/IMetadataQuery.php @@ -31,7 +31,6 @@ * @since 28.0.0 */ interface IMetadataQuery { - /** * Add metadata linked to file id to the query * @@ -62,15 +61,6 @@ public function extractMetadata(array $row): IFilesMetadata; */ public function joinIndex(string $metadataKey, bool $enforce = false): void; - /** - * entry must have a specific metadata set - * - * @param string $metadataKey metadata key - * - * @since 28.0.0 - */ - public function enforceMetadataKey(string $metadataKey): void; - /** * entry must have a specific value (string) for linked metadata * diff --git a/lib/public/FilesMetadata/Model/IMetadataValueWrapper.php b/lib/public/FilesMetadata/Model/IMetadataValueWrapper.php index af02db7409287..577ff87433002 100644 --- a/lib/public/FilesMetadata/Model/IMetadataValueWrapper.php +++ b/lib/public/FilesMetadata/Model/IMetadataValueWrapper.php @@ -37,6 +37,9 @@ * @since 28.0.0 */ interface IMetadataValueWrapper extends JsonSerializable { + /** + * @since 28.0.0 + */ public const TYPE_STRING = 'string'; public const TYPE_INT = 'int'; public const TYPE_FLOAT = 'float'; @@ -109,7 +112,7 @@ public function isType(string $type): bool; * @see self::TYPE_FLOAT * @since 28.0.0 */ - public function confirmType(string $type): self; + public function assertType(string $type): self; /** * set a string value