Merge pull request #4869 from owncloud/fixing-4866-master

recreate an etag within the scanner if the cache contains an empty etag
This commit is contained in:
Thomas Müller 2013-09-23 07:13:12 -07:00
commit 5d671a84b2
3 changed files with 62 additions and 14 deletions

View File

@ -201,7 +201,6 @@ class Cache {
$data['path'] = $file; $data['path'] = $file;
$data['parent'] = $this->getParentId($file); $data['parent'] = $this->getParentId($file);
$data['name'] = \OC_Util::basename($file); $data['name'] = \OC_Util::basename($file);
$data['encrypted'] = isset($data['encrypted']) ? ((int)$data['encrypted']) : 0;
list($queryParts, $params) = $this->buildParts($data); list($queryParts, $params) = $this->buildParts($data);
$queryParts[] = '`storage`'; $queryParts[] = '`storage`';
@ -265,6 +264,9 @@ class Cache {
$params[] = $value; $params[] = $value;
$queryParts[] = '`mtime`'; $queryParts[] = '`mtime`';
} }
} elseif ($name === 'encrypted') {
// Boolean to integer conversion
$value = $value ? 1 : 0;
} }
$params[] = $value; $params[] = $value;
$queryParts[] = '`' . $name . '`'; $queryParts[] = '`' . $name . '`';

View File

@ -97,13 +97,34 @@ class Scanner extends BasicEmitter {
} }
$newData = $data; $newData = $data;
if ($reuseExisting and $cacheData = $this->cache->get($file)) { if ($reuseExisting and $cacheData = $this->cache->get($file)) {
// prevent empty etag
$etag = $cacheData['etag'];
$propagateETagChange = false;
if (empty($etag)) {
$etag = $data['etag'];
$propagateETagChange = true;
}
// only reuse data if the file hasn't explicitly changed // only reuse data if the file hasn't explicitly changed
if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) { if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) {
if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) { if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) {
$data['size'] = $cacheData['size']; $data['size'] = $cacheData['size'];
} }
if ($reuseExisting & self::REUSE_ETAG) { if ($reuseExisting & self::REUSE_ETAG) {
$data['etag'] = $cacheData['etag']; $data['etag'] = $etag;
if ($propagateETagChange) {
$parent = $file;
while ($parent !== '') {
$parent = dirname($parent);
if ($parent === '.') {
$parent = '';
}
$parentCacheData = $this->cache->get($parent);
$this->cache->update($parentCacheData['fileid'], array(
'etag' => $this->storage->getETag($parent),
));
}
}
} }
} }
// Only update metadata that has changed // Only update metadata that has changed

View File

@ -24,6 +24,21 @@ class Scanner extends \PHPUnit_Framework_TestCase {
*/ */
private $cache; private $cache;
function setUp() {
$this->storage = new \OC\Files\Storage\Temporary(array());
$this->scanner = new \OC\Files\Cache\Scanner($this->storage);
$this->cache = new \OC\Files\Cache\Cache($this->storage);
}
function tearDown() {
if ($this->cache) {
$ids = $this->cache->getAll();
$permissionsCache = $this->storage->getPermissionsCache();
$permissionsCache->removeMultiple($ids, \OC_User::getUser());
$this->cache->clear();
}
}
function testFile() { function testFile() {
$data = "dummy file data\n"; $data = "dummy file data\n";
$this->storage->file_put_contents('foo.txt', $data); $this->storage->file_put_contents('foo.txt', $data);
@ -194,18 +209,28 @@ class Scanner extends \PHPUnit_Framework_TestCase {
$this->assertFalse($this->cache->inCache('folder/bar.txt')); $this->assertFalse($this->cache->inCache('folder/bar.txt'));
} }
function setUp() { public function testETagRecreation() {
$this->storage = new \OC\Files\Storage\Temporary(array()); $this->fillTestFolders();
$this->scanner = new \OC\Files\Cache\Scanner($this->storage);
$this->cache = new \OC\Files\Cache\Cache($this->storage);
}
function tearDown() { $this->scanner->scan('folder/bar.txt');
if ($this->cache) {
$ids = $this->cache->getAll(); // manipulate etag to simulate an empty etag
$permissionsCache = $this->storage->getPermissionsCache(); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
$permissionsCache->removeMultiple($ids, \OC_User::getUser()); $data0 = $this->cache->get('folder/bar.txt');
$this->cache->clear(); $data1 = $this->cache->get('folder');
} $data2 = $this->cache->get('');
$data0['etag'] = '';
$this->cache->put('folder/bar.txt', $data0);
// rescan
$this->scanner->scan('folder/bar.txt', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
// verify cache content
$newData0 = $this->cache->get('folder/bar.txt');
$newData1 = $this->cache->get('folder');
$newData2 = $this->cache->get('');
$this->assertNotEmpty($newData0['etag']);
$this->assertNotEquals($data1['etag'], $newData1['etag']);
$this->assertNotEquals($data2['etag'], $newData2['etag']);
} }
} }