diff options
Diffstat (limited to 'lib/private/Files/ObjectStore')
-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 3a48efcb31e..060a249b9c6 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 */ @@ -309,7 +314,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { } else { return false; } - // no break + // no break case 'w': case 'wb': case 'w+': @@ -464,7 +469,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; }); @@ -513,4 +518,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 d7c878178d2..49284533723 100644 --- a/lib/private/Files/ObjectStore/S3ObjectTrait.php +++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php @@ -123,4 +123,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 87347c3f71b..ba5eb9e37ff 100644 --- a/lib/private/Files/ObjectStore/Swift.php +++ b/lib/private/Files/ObjectStore/Swift.php @@ -86,13 +86,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, ]); } } @@ -113,7 +113,7 @@ class Swift implements IObjectStore { 'stream' => true, 'headers' => [ 'X-Auth-Token' => $tokenId, - 'Cache-Control' => 'no-cache' + 'Cache-Control' => 'no-cache', ], ] ); @@ -148,4 +148,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 + ]); + } } |