aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Appelman <icewind@owncloud.com>2014-06-10 15:26:18 +0200
committerRobin Appelman <icewind@owncloud.com>2014-06-10 15:26:18 +0200
commit21cfd1014a99e25f4ee255b872957fc1b98a7610 (patch)
treee8c1fd54980a0aff84c4d98f913c546bbb4fe459
parentecc41fe0c3375022d2455fd563f91b2691bdd857 (diff)
downloadnextcloud-server-21cfd1014a99e25f4ee255b872957fc1b98a7610.tar.gz
nextcloud-server-21cfd1014a99e25f4ee255b872957fc1b98a7610.zip
Repair broken parent link in the scanner
-rw-r--r--lib/private/files/cache/scanner.php70
-rw-r--r--tests/lib/files/cache/scanner.php51
2 files changed, 85 insertions, 36 deletions
diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php
index 965013c5c98..1f67ce0062c 100644
--- a/lib/private/files/cache/scanner.php
+++ b/lib/private/files/cache/scanner.php
@@ -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);
diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php
index 263e5b3445f..0a274631d1c 100644
--- a/tests/lib/files/cache/scanner.php
+++ b/tests/lib/files/cache/scanner.php
@@ -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']);
+ }
}