summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRobin Appelman <icewind@owncloud.com>2015-01-16 13:32:42 +0100
committerRobin Appelman <icewind@owncloud.com>2015-04-13 15:13:02 +0200
commit8575bb2cb9f57d2b7e6d9e9e48e7c85485a7c63b (patch)
treef9ef4eca310c8c9262a9b2755d0dfa97260d517f /lib
parentb302592a6435b4f9bf18719b04314d9f463d54da (diff)
downloadnextcloud-server-8575bb2cb9f57d2b7e6d9e9e48e7c85485a7c63b.tar.gz
nextcloud-server-8575bb2cb9f57d2b7e6d9e9e48e7c85485a7c63b.zip
Move cross storage copy logic to the storage
Diffstat (limited to 'lib')
-rw-r--r--lib/private/files/storage/common.php48
-rw-r--r--lib/private/files/storage/wrapper/wrapper.php20
-rw-r--r--lib/private/files/view.php87
-rw-r--r--lib/public/files/storage.php16
4 files changed, 97 insertions, 74 deletions
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
index ed85d3c07cc..164225de3e8 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -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;
+ }
}
diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php
index 6550313f710..2552c926e02 100644
--- a/lib/private/files/storage/wrapper/wrapper.php
+++ b/lib/private/files/storage/wrapper/wrapper.php
@@ -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);
+ }
}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 475a9d35af1..84164e2a249 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -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) {
diff --git a/lib/public/files/storage.php b/lib/public/files/storage.php
index 8a20eff2d9f..bac2c95ebce 100644
--- a/lib/public/files/storage.php
+++ b/lib/public/files/storage.php
@@ -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);
}