]> source.dussan.org Git - nextcloud-server.git/commitdiff
Move cross storage copy logic to the storage
authorRobin Appelman <icewind@owncloud.com>
Fri, 16 Jan 2015 12:32:42 +0000 (13:32 +0100)
committerRobin Appelman <icewind@owncloud.com>
Mon, 13 Apr 2015 13:13:02 +0000 (15:13 +0200)
lib/private/files/storage/common.php
lib/private/files/storage/wrapper/wrapper.php
lib/private/files/view.php
lib/public/files/storage.php

index ed85d3c07ccb5e7f0cbe031c2a5ce1cbe6803caa..164225de3e88bc68f8fedb2a5332c49065f3721d 100644 (file)
@@ -525,4 +525,52 @@ abstract class Common implements Storage {
        public function getMountOption($name, $default = null) {
                return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default;
        }
+       /**
+        * @param \OCP\Files\Storage $sourceStorage
+        * @param string $sourceInternalPath
+        * @param string $targetInternalPath
+        * @param bool $preserveMtime
+        * @return bool
+        */
+       public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
+               if ($sourceStorage->is_dir($sourceInternalPath)) {
+                       $dh = $sourceStorage->opendir($sourceInternalPath);
+                       $result = $this->mkdir($targetInternalPath);
+                       if (is_resource($dh)) {
+                               while (($file = readdir($dh)) !== false) {
+                                       if (!Filesystem::isIgnoredDir($file)) {
+                                               $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
+                                       }
+                               }
+                       }
+               } else {
+                       $source = $sourceStorage->fopen($sourceInternalPath, 'r');
+                       $target = $this->fopen($targetInternalPath, 'w');
+                       list(, $result) = \OC_Helper::streamCopy($source, $target);
+                       if ($preserveMtime) {
+                               $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
+                       }
+                       fclose($source);
+                       fclose($target);
+               }
+               return $result;
+       }
+
+       /**
+        * @param \OCP\Files\Storage $sourceStorage
+        * @param string $sourceInternalPath
+        * @param string $targetInternalPath
+        * @return bool
+        */
+       public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
+               $result = $this->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, true);
+               if ($result) {
+                       if ($sourceStorage->is_dir($sourceInternalPath)) {
+                               $sourceStorage->rmdir($sourceInternalPath);
+                       } else {
+                               $sourceStorage->unlink($sourceInternalPath);
+                       }
+               }
+               return $result;
+       }
 }
index 6550313f710d87c9952aee5e2eea53d7f0b66dbf..2552c926e021169b626a53e3bf5c90fd7a125dbe 100644 (file)
@@ -505,4 +505,24 @@ class Wrapper implements \OC\Files\Storage\Storage {
        public function verifyPath($path, $fileName) {
                $this->storage->verifyPath($path, $fileName);
        }
+
+       /**
+        * @param \OCP\Files\Storage $sourceStorage
+        * @param string $sourceInternalPath
+        * @param string $targetInternalPath
+        * @return bool
+        */
+       public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
+               return $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
+       }
+
+       /**
+        * @param \OCP\Files\Storage $sourceStorage
+        * @param string $sourceInternalPath
+        * @param string $targetInternalPath
+        * @return bool
+        */
+       public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
+               return $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
+       }
 }
index 475a9d35af1958b51ffc72b669235a0aca2e1032..84164e2a249979766b53146cd946999a22b29e5d 100644 (file)
@@ -584,8 +584,6 @@ class View {
         * @return bool|mixed
         */
        public function rename($path1, $path2) {
-               $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : '';
-               $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : '';
                $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
                $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2));
                if (
@@ -620,7 +618,7 @@ class View {
                                $mount1 = $this->getMount($path1);
                                $mount2 = $this->getMount($path2);
                                $storage1 = $mount1->getStorage();
-                               $storage2 = $mount1->getStorage();
+                               $storage2 = $mount2->getStorage();
                                $internalPath1 = $mount1->getInternalPath($absolutePath1);
                                $internalPath2 = $mount2->getInternalPath($absolutePath2);
 
@@ -642,34 +640,9 @@ class View {
                                                $result = false;
                                        }
                                } else {
-                                       if ($this->is_dir($path1)) {
-                                               $result = $this->copy($path1, $path2, true);
-                                               if ($result === true) {
-                                                       $result = $storage1->rmdir($internalPath1);
-                                               }
-                                       } else {
-                                               $source = $this->fopen($path1 . $postFix1, 'r');
-                                               $target = $this->fopen($path2 . $postFix2, 'w');
-                                               list(, $result) = \OC_Helper::streamCopy($source, $target);
-                                               if ($result !== false) {
-                                                       $this->touch($path2, $this->filemtime($path1));
-                                               }
-
-                                               // close open handle - especially $source is necessary because unlink below will
-                                               // throw an exception on windows because the file is locked
-                                               fclose($source);
-                                               fclose($target);
-
-                                               if ($result !== false) {
-                                                       $result &= $storage1->unlink($internalPath1);
-                                               } else {
-                                                       // delete partially written target file
-                                                       $storage2->unlink($internalPath2);
-                                                       // delete cache entry that was created by fopen
-                                                       $storage2->getCache()->remove($internalPath2);
-                                               }
-                                       }
+                                       $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2);
                                }
+                               \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2);
                                if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
                                        // if it was a rename from a part file to a regular file it was a write and not a rename operation
                                        $this->updater->update($path2);
@@ -708,8 +681,6 @@ class View {
         * @return bool|mixed
         */
        public function copy($path1, $path2, $preserveMtime = false) {
-               $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : '';
-               $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : '';
                $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
                $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2));
                if (
@@ -738,52 +709,20 @@ class View {
                                $this->emit_file_hooks_pre($exists, $path2, $run);
                        }
                        if ($run) {
-                               $mp1 = $this->getMountPoint($path1 . $postFix1);
-                               $mp2 = $this->getMountPoint($path2 . $postFix2);
-                               if ($mp1 == $mp2) {
-                                       list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
-                                       list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
-                                       if ($storage) {
-                                               $result = $storage->copy($internalPath1, $internalPath2);
-                                               if (!$result) {
-                                                       // delete partially written target file
-                                                       $storage->unlink($internalPath2);
-                                                       $storage->getCache()->remove($internalPath2);
-                                               }
+                               $mount1 = $this->getMount($path1);
+                               $mount2 = $this->getMount($path2);
+                               $storage1 = $mount1->getStorage();
+                               $internalPath1 = $mount1->getInternalPath($absolutePath1);
+                               $storage2 = $mount2->getStorage();
+                               $internalPath2 = $mount2->getInternalPath($absolutePath2);
+                               if ($mount1->getMountPoint() == $mount2->getMountPoint()) {
+                                       if ($storage1) {
+                                               $result = $storage1->copy($internalPath1, $internalPath2);
                                        } else {
                                                $result = false;
                                        }
                                } else {
-                                       if ($this->is_dir($path1) && ($dh = $this->opendir($path1))) {
-                                               $result = $this->mkdir($path2);
-                                               if ($preserveMtime) {
-                                                       $this->touch($path2, $this->filemtime($path1));
-                                               }
-                                               if (is_resource($dh)) {
-                                                       while (($file = readdir($dh)) !== false) {
-                                                               if (!Filesystem::isIgnoredDir($file)) {
-                                                                       if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file, $preserveMtime)) {
-                                                                               $result = false;
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       } else {
-                                               list($storage2, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
-                                               $source = $this->fopen($path1 . $postFix1, 'r');
-                                               $target = $this->fopen($path2 . $postFix2, 'w');
-                                               list(, $result) = \OC_Helper::streamCopy($source, $target);
-                                               if($result && $preserveMtime) {
-                                                       $this->touch($path2, $this->filemtime($path1));
-                                               }
-                                               fclose($source);
-                                               fclose($target);
-                                               if (!$result) {
-                                                       // delete partially written target file
-                                                       $storage2->unlink($internalPath2);
-                                                       $storage2->getCache()->remove($internalPath2);
-                                               }
-                                       }
+                                       $result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2);
                                }
                                $this->updater->update($path2);
                                if ($this->shouldEmitHooks() && $result !== false) {
index 8a20eff2d9ff8559daa04c3805fffc0d1463ed6a..bac2c95ebced9ee5adc1f938dfe2c5f51c6a39e7 100644 (file)
@@ -358,4 +358,20 @@ interface Storage {
         * @throws InvalidPathException
         */
        public function verifyPath($path, $fileName);
+
+       /**
+        * @param \OCP\Files\Storage $sourceStorage
+        * @param string $sourceInternalPath
+        * @param string $targetInternalPath
+        * @return bool
+        */
+       public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath);
+
+       /**
+        * @param \OCP\Files\Storage $sourceStorage
+        * @param string $sourceInternalPath
+        * @param string $targetInternalPath
+        * @return bool
+        */
+       public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath);
 }