Prechádzať zdrojové kódy

allow deleting "ghost files" trough the View and Node api

Robin Appelman 8 rokov pred
rodič
commit
63408fa6ef
2 zmenil súbory, kde vykonal 78 pridanie a 16 odobranie
  1. 28 15
      lib/private/Files/View.php
  2. 50 1
      tests/lib/Files/ViewTest.php

+ 28 - 15
lib/private/Files/View.php

@@ -337,10 +337,17 @@ class View {
 			return $this->removeMount($mount, $absolutePath);
 		}
 		if ($this->is_dir($path)) {
-			return $this->basicOperation('rmdir', $path, array('delete'));
+			$result = $this->basicOperation('rmdir', $path, array('delete'));
 		} else {
-			return false;
+			$result = false;
 		}
+
+		if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete
+			$storage = $mount->getStorage();
+			$internalPath = $mount->getInternalPath($absolutePath);
+			$storage->getUpdater()->remove($internalPath);
+		}
+		return $result;
 	}
 
 	/**
@@ -429,7 +436,7 @@ class View {
 
 	/**
 	 * @param string $path
-	 * @param int $from 
+	 * @param int $from
 	 * @param int $to
 	 * @return bool|mixed
 	 * @throws \OCP\Files\InvalidPathException
@@ -441,18 +448,18 @@ class View {
 		$handle = $this->fopen($path, 'rb');
 		if ($handle) {
 			if (fseek($handle, $from) === 0) {
-			    $chunkSize = 8192; // 8 kB chunks
-			    $end = $to + 1;
-			    while (!feof($handle) && ftell($handle) < $end) {
-				$len = $end-ftell($handle);
-				if ($len > $chunkSize) { 
-				    $len = $chunkSize; 
+				$chunkSize = 8192; // 8 kB chunks
+				$end = $to + 1;
+				while (!feof($handle) && ftell($handle) < $end) {
+					$len = $end - ftell($handle);
+					if ($len > $chunkSize) {
+						$len = $chunkSize;
+					}
+					echo fread($handle, $len);
+					flush();
 				}
-				echo fread($handle, $len);
-				flush();
-			    }
-			    $size = ftell($handle) - $from;
-			    return $size;
+				$size = ftell($handle) - $from;
+				return $size;
 			}
 
 			throw new \OCP\Files\UnseekableException('fseek error');
@@ -679,7 +686,13 @@ class View {
 		if ($mount and $mount->getInternalPath($absolutePath) === '') {
 			return $this->removeMount($mount, $absolutePath);
 		}
-		return $this->basicOperation('unlink', $path, array('delete'));
+		$result = $this->basicOperation('unlink', $path, array('delete'));
+		if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete
+			$storage = $mount->getStorage();
+			$internalPath = $mount->getInternalPath($absolutePath);
+			$storage->getUpdater()->remove($internalPath);
+		}
+		return $result;
 	}
 
 	/**

+ 50 - 1
tests/lib/Files/ViewTest.php

@@ -2417,7 +2417,7 @@ class ViewTest extends \Test\TestCase {
 
 		$content = $view->getDirectoryContent('', $filter);
 
-		$files = array_map(function(FileInfo $info) {
+		$files = array_map(function (FileInfo $info) {
 			return $info->getName();
 		}, $content);
 		sort($files);
@@ -2444,4 +2444,53 @@ class ViewTest extends \Test\TestCase {
 		$data = $view->getFileInfo('.');
 		$this->assertEquals('', $data->getChecksum());
 	}
+
+	public function testDeleteGhostFile() {
+		$storage = new Temporary(array());
+		$scanner = $storage->getScanner();
+		$cache = $storage->getCache();
+		$storage->file_put_contents('foo.txt', 'bar');
+		\OC\Files\Filesystem::mount($storage, array(), '/test/');
+		$scanner->scan('');
+
+		$storage->unlink('foo.txt');
+
+		$this->assertTrue($cache->inCache('foo.txt'));
+
+		$view = new \OC\Files\View('/test');
+		$rootInfo = $view->getFileInfo('');
+		$this->assertEquals(3, $rootInfo->getSize());
+		$view->unlink('foo.txt');
+		$newInfo = $view->getFileInfo('');
+
+		$this->assertFalse($cache->inCache('foo.txt'));
+		$this->assertNotEquals($rootInfo->getEtag(), $newInfo->getEtag());
+		$this->assertEquals(0, $newInfo->getSize());
+	}
+
+	public function testDeleteGhostFolder() {
+		$storage = new Temporary(array());
+		$scanner = $storage->getScanner();
+		$cache = $storage->getCache();
+		$storage->mkdir('foo');
+		$storage->file_put_contents('foo/foo.txt', 'bar');
+		\OC\Files\Filesystem::mount($storage, array(), '/test/');
+		$scanner->scan('');
+
+		$storage->rmdir('foo');
+
+		$this->assertTrue($cache->inCache('foo'));
+		$this->assertTrue($cache->inCache('foo/foo.txt'));
+
+		$view = new \OC\Files\View('/test');
+		$rootInfo = $view->getFileInfo('');
+		$this->assertEquals(3, $rootInfo->getSize());
+		$view->rmdir('foo');
+		$newInfo = $view->getFileInfo('');
+
+		$this->assertFalse($cache->inCache('foo'));
+		$this->assertFalse($cache->inCache('foo/foo.txt'));
+		$this->assertNotEquals($rootInfo->getEtag(), $newInfo->getEtag());
+		$this->assertEquals(0, $newInfo->getSize());
+	}
 }