diff options
author | Robin Appelman <robin@icewind.nl> | 2020-11-05 16:30:05 +0100 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2020-11-24 15:16:58 +0100 |
commit | 9d4848e86383afd1ec49aa81f606f2042def2133 (patch) | |
tree | 164177856713c1b64fa303bd87a7d03da949291d /lib/private | |
parent | f37155d28ba1bc805eeb3abd445d3d965ecb34bd (diff) | |
download | nextcloud-server-9d4848e86383afd1ec49aa81f606f2042def2133.tar.gz nextcloud-server-9d4848e86383afd1ec49aa81f606f2042def2133.zip |
use in objectstore copy
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib/private')
-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 |
5 files changed, 83 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 + ]); + } } |