diff options
author | Eduardo Morales <emoral435@gmail.com> | 2024-03-09 11:04:44 -0600 |
---|---|---|
committer | Eduardo Morales <emoral435@gmail.com> | 2024-03-11 15:57:12 -0500 |
commit | b2c855451c3131e6cb9d2e5e2a6a41ae0b661bb3 (patch) | |
tree | 97efda6b3aa64ebfa29040ad952a34238e3bd985 /apps | |
parent | 88b40bb392a2a35d84ef30b2fc7a893aac83fc7c (diff) | |
download | nextcloud-server-b2c855451c3131e6cb9d2e5e2a6a41ae0b661bb3.tar.gz nextcloud-server-b2c855451c3131e6cb9d2e5e2a6a41ae0b661bb3.zip |
feat: added backend metadata interface, allows JSON storage
Signed-off-by: Eduardo Morales <emoral435@gmail.com>
Diffstat (limited to 'apps')
6 files changed, 159 insertions, 4 deletions
diff --git a/apps/files_versions/lib/Db/VersionEntity.php b/apps/files_versions/lib/Db/VersionEntity.php index a37171ef93f..1e1eca86886 100644 --- a/apps/files_versions/lib/Db/VersionEntity.php +++ b/apps/files_versions/lib/Db/VersionEntity.php @@ -78,4 +78,23 @@ class VersionEntity extends Entity implements JsonSerializable { $this->metadata['label'] = $label; $this->markFieldUpdated('metadata'); } + + /** + * @abstract given a key, return the value associated with the key in the metadata column + * if nothing is found, we return an empty string + * @param string $key key associated with the value + */ + public function getMetadataValue(string $key): string { + return $this->metadata[$key] ?? ''; + } + + /** + * @abstract sets a key value pair in the metadata column + * @param string $key key associated with the value + * @param string $value value associated with the key + */ + public function setMetadataValue(string $key, $value): void { + $this->metadata[$key] = $value; + $this->markFieldUpdated('metadata'); + } } diff --git a/apps/files_versions/lib/Db/VersionsMapper.php b/apps/files_versions/lib/Db/VersionsMapper.php index f7f92c70f03..9dc15dd60ab 100644 --- a/apps/files_versions/lib/Db/VersionsMapper.php +++ b/apps/files_versions/lib/Db/VersionsMapper.php @@ -85,7 +85,7 @@ class VersionsMapper extends QBMapper { ->executeStatement(); } - public function deleteAllVersionsForUser(int $storageId, string $path = null): void { + public function deleteAllVersionsForUser(int $storageId, ?string $path = null): void { $fileIdsGenerator = $this->getFileIdsGenerator($storageId, $path); $versionEntitiesDeleteQuery = $this->db->getQueryBuilder(); diff --git a/apps/files_versions/lib/Versions/IMetadataVersion.php b/apps/files_versions/lib/Versions/IMetadataVersion.php new file mode 100644 index 00000000000..c11ec57f7d0 --- /dev/null +++ b/apps/files_versions/lib/Versions/IMetadataVersion.php @@ -0,0 +1,38 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Eduardo Morales <emoral435@gmail.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\Files_Versions\Versions; + +/** + * This interface allows for just direct accessing of the metadata column JSON + * @since 29.0.0 + */ +interface IMetadataVersion { + /** + * @abstract retrieves the metadata value from our $key param + * + * @param string $key the key for the json value of the metadata column + * @since 29.0.0 + */ + public function getMetadataValue(string $key): string; +} diff --git a/apps/files_versions/lib/Versions/IMetadataVersionBackend.php b/apps/files_versions/lib/Versions/IMetadataVersionBackend.php new file mode 100644 index 00000000000..b67ead12955 --- /dev/null +++ b/apps/files_versions/lib/Versions/IMetadataVersionBackend.php @@ -0,0 +1,52 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2024 Eduardo Morales <emoral435@gmail.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\Files_Versions\Versions; + +use OCP\Files\Node; + +/** + * This interface edits the metadata column of a node. + * Each column of the metadata has a key => value mapping. + * @since 29.0.0 + */ +interface IMetadataVersionBackend { + /** + * Sets a key value pair in the metadata column corresponding to the node's version. + * + * @param Node $node the node that triggered the Metadata event listener, aka, the file version + * @param string $key the key for the json value of the metadata column + * @param string $value the value that corresponds to the key in the metadata column + * @since 29.0.0 + */ + public function setMetadataValue(Node $node, string $key, string $value): void; + + /** + * Retrieves a corresponding value from the metadata column using the key. + * + * @param Node $node the node that triggered the Metadata event listener, aka, the file version + * @param string $key the key for the json value of the metadata column + * @since 29.0.0 + */ + public function getMetadataValue(Node $node, string $key): ?string; +} diff --git a/apps/files_versions/lib/Versions/LegacyVersionsBackend.php b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php index 676a9d5a964..6c052b30591 100644 --- a/apps/files_versions/lib/Versions/LegacyVersionsBackend.php +++ b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php @@ -39,13 +39,14 @@ use OCP\Files\FileInfo; use OCP\Files\Folder; use OCP\Files\IMimeTypeLoader; use OCP\Files\IRootFolder; +use OCP\Files\Node; use OCP\Files\NotFoundException; use OCP\Files\Storage\IStorage; use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; -class LegacyVersionsBackend implements IVersionBackend, INameableVersionBackend, IDeletableVersionBackend, INeedSyncVersionBackend { +class LegacyVersionsBackend implements IVersionBackend, INameableVersionBackend, IDeletableVersionBackend, INeedSyncVersionBackend, IMetadataVersionBackend { private IRootFolder $rootFolder; private IUserManager $userManager; private VersionsMapper $versionsMapper; @@ -312,4 +313,33 @@ class LegacyVersionsBackend implements IVersionBackend, INameableVersionBackend, return ($sourceFile->getPermissions() & $permissions) === $permissions; } + + public function setMetadataValue(Node $node, string $key, string $value): void { + // Do not handle folders. + if ($node instanceof File) { + + try { + $versionEntity = $this->versionsMapper->findVersionForFileId($node->getId(), $node->getMTime()); + } catch (\Exception $e) { + throw $e; // the version does not exist or too many versions exist + } + + $currentMetadata = $versionEntity->getMetadata() ?? []; + + $currentMetadata[$key] = $value; + $versionEntity->setMetadata($currentMetadata); + $this->versionsMapper->update($versionEntity); + } + + } + + public function getMetadataValue(Node $node, string $key): ?string { + try { + $versionEntity = $this->versionsMapper->findVersionForFileId($node->getId(), $node->getMTime()); + return $versionEntity->getMetadataValue($key); + } catch (\InvalidArgumentException $e) { + // we tried to find a version or key that doesn't exist + return null; + } + } } diff --git a/apps/files_versions/lib/Versions/VersionManager.php b/apps/files_versions/lib/Versions/VersionManager.php index 5fbfaae4a16..d884ffb0f7b 100644 --- a/apps/files_versions/lib/Versions/VersionManager.php +++ b/apps/files_versions/lib/Versions/VersionManager.php @@ -31,11 +31,12 @@ use OCP\Files\IRootFolder; use OCP\Files\Lock\ILock; use OCP\Files\Lock\ILockManager; use OCP\Files\Lock\LockContext; +use OCP\Files\Node; use OCP\Files\Storage\IStorage; use OCP\IUser; use OCP\Lock\ManuallyLockedException; -class VersionManager implements IVersionManager, INameableVersionBackend, IDeletableVersionBackend, INeedSyncVersionBackend { +class VersionManager implements IVersionManager, INameableVersionBackend, IDeletableVersionBackend, INeedSyncVersionBackend, IMetadataVersionBackend { /** @var (IVersionBackend[])[] */ private $backends = []; @@ -160,6 +161,21 @@ class VersionManager implements IVersionManager, INameableVersionBackend, IDelet } } + public function setMetadataValue(Node $node, string $key, string $value): void { + $backend = $this->getBackendForStorage($node->getStorage()); + if ($backend instanceof IMetadataVersionBackend) { + $backend->setMetadataValue($node, $key, $value); + } + } + + public function getMetadataValue(Node $node, string $key): ?string { + $backend = $this->getBackendForStorage($node->getStorage()); + if ($backend instanceof IMetadataVersionBackend) { + return $backend->getMetadataValue($node, $key); + } + return null; + } + /** * Catch ManuallyLockedException and retry in app context if possible. * @@ -184,7 +200,7 @@ class VersionManager implements IVersionManager, INameableVersionBackend, IDelet return $callback(); } catch (ManuallyLockedException $e) { $owner = (string) $e->getOwner(); - $appsThatHandleUpdates = array("text", "richdocuments"); + $appsThatHandleUpdates = ["text", "richdocuments"]; if (!in_array($owner, $appsThatHandleUpdates)) { throw $e; } |