]> source.dussan.org Git - nextcloud-server.git/commitdiff
Repair broken parent link in the scanner
authorRobin Appelman <icewind@owncloud.com>
Tue, 10 Jun 2014 13:26:18 +0000 (15:26 +0200)
committerRobin Appelman <icewind@owncloud.com>
Tue, 10 Jun 2014 13:26:18 +0000 (15:26 +0200)
lib/private/files/cache/scanner.php
tests/lib/files/cache/scanner.php

index 965013c5c98cd82b61940b9f1543a4f4b66a55c9..1f67ce0062c342fcd1173cc90e106a4dae3262c1 100644 (file)
@@ -100,45 +100,47 @@ class Scanner extends BasicEmitter {
                        \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
                        $data = $this->getData($file);
                        if ($data) {
-                               if ($file and !$parentExistsInCache) {
-                                       $parent = dirname($file);
-                                       if ($parent === '.' or $parent === '/') {
-                                               $parent = '';
-                                       }
-                                       if (!$this->cache->inCache($parent)) {
-                                               $this->scanFile($parent);
-                                       }
+                               $parent = dirname($file);
+                               if ($parent === '.' or $parent === '/') {
+                                       $parent = '';
+                               }
+                               $parentId = $this->cache->getId($parent);
+                               if ($file and $parentId === -1) {
+                                       $parentData = $this->scanFile($parent);
+                                       $parentId = $parentData['fileid'];
+                               }
+                               if ($parent) {
+                                       $data['parent'] = $parentId;
                                }
-                               $newData = $data;
                                $cacheData = $this->cache->get($file);
-                               if ($cacheData) {
-                                       if ($reuseExisting) {
-                                               // prevent empty etag
-                                               if (empty($cacheData['etag'])) {
-                                                       $etag = $data['etag'];
-                                               } else {
-                                                       $etag = $cacheData['etag'];
-                                               }
-                                               // only reuse data if the file hasn't explicitly changed
-                                               if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) {
-                                                       $data['mtime'] = $cacheData['mtime'];
-                                                       if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) {
-                                                               $data['size'] = $cacheData['size'];
-                                                       }
-                                                       if ($reuseExisting & self::REUSE_ETAG) {
-                                                               $data['etag'] = $etag;
-                                                       }
+                               if ($cacheData and $reuseExisting) {
+                                       // prevent empty etag
+                                       if (empty($cacheData['etag'])) {
+                                               $etag = $data['etag'];
+                                       } else {
+                                               $etag = $cacheData['etag'];
+                                       }
+                                       // only reuse data if the file hasn't explicitly changed
+                                       if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) {
+                                               $data['mtime'] = $cacheData['mtime'];
+                                               if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) {
+                                                       $data['size'] = $cacheData['size'];
                                                }
-                                               // Only update metadata that has changed
-                                               $newData = array_diff_assoc($data, $cacheData);
-                                               if (isset($newData['etag'])) {
-                                                       $cacheDataString = print_r($cacheData, true);
-                                                       $dataString = print_r($data, true);
-                                                       \OCP\Util::writeLog('OC\Files\Cache\Scanner',
-                                                               "!!! No reuse of etag for '$file' !!! \ncache: $cacheDataString \ndata: $dataString",
-                                                               \OCP\Util::DEBUG);
+                                               if ($reuseExisting & self::REUSE_ETAG) {
+                                                       $data['etag'] = $etag;
                                                }
                                        }
+                                       // Only update metadata that has changed
+                                       $newData = array_diff_assoc($data, $cacheData);
+                                       if (isset($newData['etag'])) {
+                                               $cacheDataString = print_r($cacheData, true);
+                                               $dataString = print_r($data, true);
+                                               \OCP\Util::writeLog('OC\Files\Cache\Scanner',
+                                                       "!!! No reuse of etag for '$file' !!! \ncache: $cacheDataString \ndata: $dataString",
+                                                       \OCP\Util::DEBUG);
+                                       }
+                               } else {
+                                       $newData = $data;
                                }
                                if (!empty($newData)) {
                                        $data['fileid'] = $this->addToCache($file, $newData);
index 263e5b3445fada0e0728564369e4baadefbea0f7..0a274631d1cf72fe8f0c28a259574c0f5c95b5ff 100644 (file)
@@ -32,7 +32,6 @@ class Scanner extends \PHPUnit_Framework_TestCase {
 
        function tearDown() {
                if ($this->cache) {
-                       $ids = $this->cache->getAll();
                        $this->cache->clear();
                }
        }
@@ -199,7 +198,7 @@ class Scanner extends \PHPUnit_Framework_TestCase {
                $this->assertFalse($this->cache->inCache('folder/bar.txt'));
        }
 
-       public function testScanRemovedFile(){
+       public function testScanRemovedFile() {
                $this->fillTestFolders();
 
                $this->scanner->scan('');
@@ -233,4 +232,52 @@ class Scanner extends \PHPUnit_Framework_TestCase {
                $this->assertInternalType('string', $newData0['etag']);
                $this->assertNotEmpty($newData0['etag']);
        }
+
+       public function testRepairParent() {
+               $this->fillTestFolders();
+               $this->scanner->scan('');
+               $this->assertTrue($this->cache->inCache('folder/bar.txt'));
+               $oldFolderId = $this->cache->getId('folder');
+
+               // delete the folder without removing the childs
+               $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?';
+               \OC_DB::executeAudited($sql, array($oldFolderId));
+
+               $cachedData = $this->cache->get('folder/bar.txt');
+               $this->assertEquals($oldFolderId, $cachedData['parent']);
+               $this->assertFalse($this->cache->inCache('folder'));
+
+               $this->scanner->scan('');
+
+               $this->assertTrue($this->cache->inCache('folder'));
+               $newFolderId = $this->cache->getId('folder');
+               $this->assertNotEquals($oldFolderId, $newFolderId);
+
+               $cachedData = $this->cache->get('folder/bar.txt');
+               $this->assertEquals($newFolderId, $cachedData['parent']);
+       }
+
+       public function testRepairParentShallow() {
+               $this->fillTestFolders();
+               $this->scanner->scan('');
+               $this->assertTrue($this->cache->inCache('folder/bar.txt'));
+               $oldFolderId = $this->cache->getId('folder');
+
+               // delete the folder without removing the childs
+               $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?';
+               \OC_DB::executeAudited($sql, array($oldFolderId));
+
+               $cachedData = $this->cache->get('folder/bar.txt');
+               $this->assertEquals($oldFolderId, $cachedData['parent']);
+               $this->assertFalse($this->cache->inCache('folder'));
+
+               $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW);
+
+               $this->assertTrue($this->cache->inCache('folder'));
+               $newFolderId = $this->cache->getId('folder');
+               $this->assertNotEquals($oldFolderId, $newFolderId);
+
+               $cachedData = $this->cache->get('folder/bar.txt');
+               $this->assertEquals($newFolderId, $cachedData['parent']);
+       }
 }