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/files_versions/lib/Versions | |
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/files_versions/lib/Versions')
4 files changed, 139 insertions, 3 deletions
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; } |