enh(metadata): store current file etagtags/v29.0.0beta2
@@ -611,14 +611,10 @@ class FilesPlugin extends ServerPlugin { | |||
$metadata->setArray($metadataKey, $value); | |||
break; | |||
case IMetadataValueWrapper::TYPE_STRING_LIST: | |||
$metadata->setStringList( | |||
$metadataKey, $value, $knownMetadata->isIndex($metadataKey) | |||
); | |||
$metadata->setStringList($metadataKey, $value, $knownMetadata->isIndex($metadataKey)); | |||
break; | |||
case IMetadataValueWrapper::TYPE_INT_LIST: | |||
$metadata->setIntList( | |||
$metadataKey, $value, $knownMetadata->isIndex($metadataKey) | |||
); | |||
$metadata->setIntList($metadataKey, $value, $knownMetadata->isIndex($metadataKey)); | |||
break; | |||
} | |||
@@ -72,6 +72,12 @@ class GenerateBlurhashMetadata implements IEventListener { | |||
return; | |||
} | |||
$currentEtag = $file->getEtag(); | |||
$metadata = $event->getMetadata(); | |||
if ($metadata->getEtag('blurhash') === $currentEtag) { | |||
return; | |||
} | |||
// too heavy to run on the live thread, request a rerun as a background job | |||
if ($event instanceof MetadataLiveEvent) { | |||
$event->requestBackgroundJob(); | |||
@@ -95,8 +101,8 @@ class GenerateBlurhashMetadata implements IEventListener { | |||
return; | |||
} | |||
$metadata = $event->getMetadata(); | |||
$metadata->setString('blurhash', $this->generateBlurHash($image)); | |||
$metadata->setString('blurhash', $this->generateBlurHash($image)) | |||
->setEtag('blurhash', $currentEtag); | |||
} | |||
/** |
@@ -156,6 +156,23 @@ class FilesMetadata implements IFilesMetadata { | |||
$this->metadata[$key]->setEditPermission($permission); | |||
} | |||
public function getEtag(string $key): string { | |||
if (!array_key_exists($key, $this->metadata)) { | |||
throw new FilesMetadataNotFoundException(); | |||
} | |||
return $this->metadata[$key]->getEtag(); | |||
} | |||
public function setEtag(string $key, string $etag): void { | |||
if (!array_key_exists($key, $this->metadata)) { | |||
throw new FilesMetadataNotFoundException(); | |||
} | |||
$this->metadata[$key]->setEtag($etag); | |||
} | |||
/** | |||
* @param string $key metadata key | |||
* |
@@ -38,6 +38,7 @@ class MetadataValueWrapper implements IMetadataValueWrapper { | |||
private string $type; | |||
/** @var string|int|float|bool|array|string[]|int[] */ | |||
private mixed $value = null; | |||
private string $etag = ''; | |||
private bool $indexed = false; | |||
private int $editPermission = self::EDIT_FORBIDDEN; | |||
@@ -350,6 +351,27 @@ class MetadataValueWrapper implements IMetadataValueWrapper { | |||
return $this->value; | |||
} | |||
/** | |||
* @inheritDoc | |||
* @return string stored etag | |||
* @since 29.0.0 | |||
*/ | |||
public function getEtag(): string { | |||
return $this->etag; | |||
} | |||
/** | |||
* @param string $etag etag value | |||
* | |||
* @inheritDoc | |||
* @return self | |||
* @since 29.0.0 | |||
*/ | |||
public function setEtag(string $etag): self { | |||
$this->etag = $etag; | |||
return $this; | |||
} | |||
/** | |||
* @param bool $indexed TRUE to set the stored value as an indexed value | |||
* | |||
@@ -405,6 +427,7 @@ class MetadataValueWrapper implements IMetadataValueWrapper { | |||
public function import(array $data): self { | |||
$this->value = $data['value'] ?? null; | |||
$this->type = $data['type'] ?? ''; | |||
$this->setEtag($data['etag'] ?? ''); | |||
$this->setIndexed($data['indexed'] ?? false); | |||
$this->setEditPermission($data['editPermission'] ?? self::EDIT_FORBIDDEN); | |||
return $this; | |||
@@ -414,6 +437,7 @@ class MetadataValueWrapper implements IMetadataValueWrapper { | |||
return [ | |||
'value' => ($emptyValues) ? null : $this->value, | |||
'type' => $this->getType(), | |||
'etag' => $this->getEtag(), | |||
'indexed' => $this->isIndexed(), | |||
'editPermission' => $this->getEditPermission() | |||
]; |
@@ -74,16 +74,12 @@ class MetadataRequestService { | |||
try { | |||
$qb = $this->dbConnection->getQueryBuilder(); | |||
$qb->select('json', 'sync_token')->from(self::TABLE_METADATA); | |||
$qb->where( | |||
$qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)) | |||
); | |||
$qb->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))); | |||
$result = $qb->executeQuery(); | |||
$data = $result->fetch(); | |||
$result->closeCursor(); | |||
} catch (Exception $e) { | |||
$this->logger->warning( | |||
'exception while getMetadataFromDatabase()', ['exception' => $e, 'fileId' => $fileId] | |||
); | |||
$this->logger->warning('exception while getMetadataFromDatabase()', ['exception' => $e, 'fileId' => $fileId]); | |||
throw new FilesMetadataNotFoundException(); | |||
} | |||
@@ -100,8 +96,6 @@ class MetadataRequestService { | |||
/** | |||
* returns metadata for multiple file ids | |||
* | |||
* If | |||
* | |||
* @param array $fileIds file ids | |||
* | |||
* @return array File ID is the array key, files without metadata are not returned in the array | |||
@@ -110,9 +104,7 @@ class MetadataRequestService { | |||
public function getMetadataFromFileIds(array $fileIds): array { | |||
$qb = $this->dbConnection->getQueryBuilder(); | |||
$qb->select('file_id', 'json', 'sync_token')->from(self::TABLE_METADATA); | |||
$qb->where( | |||
$qb->expr()->in('file_id', $qb->createNamedParameter($fileIds, IQueryBuilder::PARAM_INT_ARRAY)) | |||
); | |||
$qb->where($qb->expr()->in('file_id', $qb->createNamedParameter($fileIds, IQueryBuilder::PARAM_INT_ARRAY))); | |||
$list = []; | |||
$result = $qb->executeQuery(); |
@@ -37,12 +37,14 @@ use OCP\FilesMetadata\Exceptions\FilesMetadataTypeException; | |||
* "mymeta": { | |||
* "value": "this is a test", | |||
* "type": "string", | |||
* "etag": "abcd1234", | |||
* "indexed": false, | |||
* "editPermission": 1 | |||
* }, | |||
* "myapp-anothermeta": { | |||
* "value": 42, | |||
* "type": "int", | |||
* "etag": "0987zyxw", | |||
* "indexed": true, | |||
* "editPermission": 0 | |||
* } | |||
@@ -112,6 +114,23 @@ interface IFilesMetadata extends JsonSerializable { | |||
*/ | |||
public function isIndex(string $key): bool; | |||
/** | |||
* returns file etag stored during the last update of the metadata key | |||
* | |||
* @param string $key metadata key | |||
* @return string | |||
* @since 29.0.0 | |||
*/ | |||
public function getEtag(string $key): string; | |||
/** | |||
* set file etag | |||
* | |||
* @param string $key metadata key | |||
* @since 29.0.0 | |||
*/ | |||
public function setEtag(string $key, string $etag): void; | |||
/** | |||
* set remote edit permission | |||
* (Webdav PROPPATCH) |
@@ -285,6 +285,24 @@ interface IMetadataValueWrapper extends JsonSerializable { | |||
*/ | |||
public function getValueAny(): mixed; | |||
/** | |||
* get stored etag value | |||
* | |||
* @return string stored etag | |||
* @since 29.0.0 | |||
*/ | |||
public function getEtag(): string; | |||
/** | |||
* set etag value | |||
* | |||
* @param string $etag etag value | |||
* | |||
* @return self | |||
* @since 29.0.0 | |||
*/ | |||
public function setEtag(string $etag): self; | |||
/** | |||
* @param bool $indexed TRUE to set the stored value as an indexed value | |||
* |