diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2020-11-25 16:09:26 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-25 16:09:26 +0100 |
commit | 2172432420a85abdd3f4acbc223fff4ef30d3d64 (patch) | |
tree | e393c9e1c785cbcf198463c4418ce82c0a51ea38 /lib | |
parent | e165dcbe35b68ddfab5ad07d5271c869a890825b (diff) | |
parent | 9d4848e86383afd1ec49aa81f606f2042def2133 (diff) | |
download | nextcloud-server-2172432420a85abdd3f4acbc223fff4ef30d3d64.tar.gz nextcloud-server-2172432420a85abdd3f4acbc223fff4ef30d3d64.zip |
Merge pull request #23912 from nextcloud/objectstore-copy
use in objectstore copy
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Files/ObjectStore/Azure.php | 4 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/ObjectStoreStorage.php | 64 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/S3ObjectTrait.php | 4 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/StorageObjectStore.php | 4 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/Swift.php | 12 | ||||
-rw-r--r-- | lib/public/Files/ObjectStore/IObjectStore.php | 8 |
6 files changed, 91 insertions, 5 deletions
diff --git a/lib/private/Files/ObjectStore/Azure.php b/lib/private/Files/ObjectStore/Azure.php index 0b65a6b80e5..2ef13d60c56 100644 --- a/lib/private/Files/ObjectStore/Azure.php +++ b/lib/private/Files/ObjectStore/Azure.php @@ -130,4 +130,8 @@ class Azure implements IObjectStore { } } } + + public function copyObject($from, $to) { + $this->getBlobClient()->copyBlob($this->containerName, $to, $this->containerName, $from); + } } diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php index e675064eb1f..e855c166612 100644 --- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php @@ -33,10 +33,15 @@ use Icewind\Streams\CallbackWrapper; use Icewind\Streams\CountWrapper; use Icewind\Streams\IteratorDirectory; use OC\Files\Cache\CacheEntry; +use OC\Files\Storage\PolyFill\CopyDirectory; +use OCP\Files\Cache\ICacheEntry; +use OCP\Files\FileInfo; use OCP\Files\NotFoundException; use OCP\Files\ObjectStore\IObjectStore; class ObjectStoreStorage extends \OC\Files\Storage\Common { + use CopyDirectory; + /** * @var \OCP\Files\ObjectStore\IObjectStore $objectStore */ @@ -319,7 +324,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { } else { return false; } - // no break + // no break case 'w': case 'wb': case 'w+': @@ -474,7 +479,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { if ($size === null) { $countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, &$size) { $this->getCache()->update($fileId, [ - 'size' => $writtenSize + 'size' => $writtenSize, ]); $size = $writtenSize; }); @@ -523,4 +528,59 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { public function getObjectStore(): IObjectStore { return $this->objectStore; } + + public function copy($path1, $path2) { + $path1 = $this->normalizePath($path1); + $path2 = $this->normalizePath($path2); + + $cache = $this->getCache(); + $sourceEntry = $cache->get($path1); + if (!$sourceEntry) { + throw new NotFoundException('Source object not found'); + } + + $this->copyInner($sourceEntry, $path2); + + return true; + } + + private function copyInner(ICacheEntry $sourceEntry, string $to) { + $cache = $this->getCache(); + + if ($sourceEntry->getMimeType() === FileInfo::MIMETYPE_FOLDER) { + if ($cache->inCache($to)) { + $cache->remove($to); + } + $this->mkdir($to); + + foreach ($cache->getFolderContentsById($sourceEntry->getId()) as $child) { + $this->copyInner($child, $to . '/' . $child->getName()); + } + } else { + $this->copyFile($sourceEntry, $to); + } + } + + private function copyFile(ICacheEntry $sourceEntry, string $to) { + $cache = $this->getCache(); + + $sourceUrn = $this->getURN($sourceEntry->getId()); + + $cache->copyFromCache($cache, $sourceEntry, $to); + $targetEntry = $cache->get($to); + + if (!$targetEntry) { + throw new \Exception('Target not in cache after copy'); + } + + $targetUrn = $this->getURN($targetEntry->getId()); + + try { + $this->objectStore->copyObject($sourceUrn, $targetUrn); + } catch (\Exception $e) { + $cache->remove($to); + + throw $e; + } + } } diff --git a/lib/private/Files/ObjectStore/S3ObjectTrait.php b/lib/private/Files/ObjectStore/S3ObjectTrait.php index a390c6b4c7d..80b8a6f132d 100644 --- a/lib/private/Files/ObjectStore/S3ObjectTrait.php +++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php @@ -124,4 +124,8 @@ trait S3ObjectTrait { public function objectExists($urn) { return $this->getConnection()->doesObjectExist($this->bucket, $urn); } + + public function copyObject($from, $to) { + $this->getConnection()->copy($this->getBucket(), $from, $this->getBucket(), $to); + } } diff --git a/lib/private/Files/ObjectStore/StorageObjectStore.php b/lib/private/Files/ObjectStore/StorageObjectStore.php index a7551385b34..acf46758956 100644 --- a/lib/private/Files/ObjectStore/StorageObjectStore.php +++ b/lib/private/Files/ObjectStore/StorageObjectStore.php @@ -93,4 +93,8 @@ class StorageObjectStore implements IObjectStore { public function objectExists($urn) { return $this->storage->file_exists($urn); } + + public function copyObject($from, $to) { + $this->storage->copy($from, $to); + } } diff --git a/lib/private/Files/ObjectStore/Swift.php b/lib/private/Files/ObjectStore/Swift.php index 5ee924c9de6..1b0888b0700 100644 --- a/lib/private/Files/ObjectStore/Swift.php +++ b/lib/private/Files/ObjectStore/Swift.php @@ -87,13 +87,13 @@ class Swift implements IObjectStore { if (filesize($tmpFile) < SWIFT_SEGMENT_SIZE) { $this->getContainer()->createObject([ 'name' => $urn, - 'stream' => stream_for($handle) + 'stream' => stream_for($handle), ]); } else { $this->getContainer()->createLargeObject([ 'name' => $urn, 'stream' => stream_for($handle), - 'segmentSize' => SWIFT_SEGMENT_SIZE + 'segmentSize' => SWIFT_SEGMENT_SIZE, ]); } } @@ -114,7 +114,7 @@ class Swift implements IObjectStore { 'stream' => true, 'headers' => [ 'X-Auth-Token' => $tokenId, - 'Cache-Control' => 'no-cache' + 'Cache-Control' => 'no-cache', ], ] ); @@ -149,4 +149,10 @@ class Swift implements IObjectStore { public function objectExists($urn) { return $this->getContainer()->objectExists($urn); } + + public function copyObject($from, $to) { + $this->getContainer()->getObject($from)->copy([ + 'destination' => $this->getContainer()->name . '/' . $to + ]); + } } diff --git a/lib/public/Files/ObjectStore/IObjectStore.php b/lib/public/Files/ObjectStore/IObjectStore.php index 4925959d6c5..e9d948682f8 100644 --- a/lib/public/Files/ObjectStore/IObjectStore.php +++ b/lib/public/Files/ObjectStore/IObjectStore.php @@ -73,4 +73,12 @@ interface IObjectStore { * @since 16.0.0 */ public function objectExists($urn); + + /** + * @param string $from the unified resource name used to identify the source object + * @param string $to the unified resource name used to identify the target object + * @return void + * @since 21.0.0 + */ + public function copyObject($from, $to); } |