Do not use -1 as the size for the root folder of the home storage
This commit is contained in:
parent
a745901d50
commit
32a703ab36
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Cache;
|
||||
|
||||
class HomeCache extends Cache {
|
||||
/**
|
||||
* get the size of a folder and set it in the cache
|
||||
*
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
public function calculateFolderSize($path) {
|
||||
$totalSize = 0;
|
||||
$entry = $this->get($path);
|
||||
if ($entry && $entry['mimetype'] === 'httpd/unix-directory') {
|
||||
$isRoot = ($path === '/' or $path === '');
|
||||
$id = $entry['fileid'];
|
||||
$sql = 'SELECT SUM(`size`), MIN(`size`) FROM `*PREFIX*filecache` ' .
|
||||
'WHERE `parent` = ? AND `storage` = ?';
|
||||
if ($isRoot) {
|
||||
// filter out non-scanned dirs at the root
|
||||
$sql .= ' AND `size` >= 0';
|
||||
}
|
||||
$result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId()));
|
||||
if ($row = $result->fetchRow()) {
|
||||
list($sum, $min) = array_values($row);
|
||||
$sum = (int)$sum;
|
||||
$min = (int)$min;
|
||||
if ($min === -1) {
|
||||
$totalSize = $min;
|
||||
} else {
|
||||
$totalSize = $sum;
|
||||
}
|
||||
if ($entry['size'] !== $totalSize) {
|
||||
$this->update($id, array('size' => $totalSize));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return $totalSize;
|
||||
}
|
||||
}
|
|
@ -21,11 +21,11 @@ namespace OC\Files\Storage;
|
|||
*/
|
||||
|
||||
abstract class Common implements \OC\Files\Storage\Storage {
|
||||
private $cache;
|
||||
private $scanner;
|
||||
private $permissioncache;
|
||||
private $watcher;
|
||||
private $storageCache;
|
||||
protected $cache;
|
||||
protected $scanner;
|
||||
protected $permissioncache;
|
||||
protected $watcher;
|
||||
protected $storageCache;
|
||||
|
||||
public function __construct($parameters) {
|
||||
}
|
||||
|
|
|
@ -27,4 +27,11 @@ class Home extends Local {
|
|||
public function getId() {
|
||||
return 'home::' . $this->user->getUID();
|
||||
}
|
||||
|
||||
public function getCache($path = '') {
|
||||
if (!isset($this->cache)) {
|
||||
$this->cache = new \OC\Files\Cache\HomeCache($this);
|
||||
}
|
||||
return $this->cache;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@ class LongId extends \OC\Files\Storage\Temporary {
|
|||
|
||||
class Cache extends \PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* @var \OC\Files\Storage\Temporary $storage;
|
||||
* @var \OC\Files\Storage\Temporary $storage ;
|
||||
*/
|
||||
private $storage;
|
||||
/**
|
||||
* @var \OC\Files\Storage\Temporary $storage2;
|
||||
* @var \OC\Files\Storage\Temporary $storage2 ;
|
||||
*/
|
||||
private $storage2;
|
||||
|
||||
|
@ -137,6 +137,33 @@ class Cache extends \PHPUnit_Framework_TestCase {
|
|||
$this->assertFalse($this->cache->inCache('folder/bar'));
|
||||
}
|
||||
|
||||
public function testRootFolderSizeForNonHomeStorage() {
|
||||
$dir1 = 'knownsize';
|
||||
$dir2 = 'unknownsize';
|
||||
$fileData = array();
|
||||
$fileData[''] = array('size' => -1, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory');
|
||||
$fileData[$dir1] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory');
|
||||
$fileData[$dir2] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'httpd/unix-directory');
|
||||
|
||||
$this->cache->put('', $fileData['']);
|
||||
$this->cache->put($dir1, $fileData[$dir1]);
|
||||
$this->cache->put($dir2, $fileData[$dir2]);
|
||||
|
||||
$this->assertTrue($this->cache->inCache($dir1));
|
||||
$this->assertTrue($this->cache->inCache($dir2));
|
||||
|
||||
// check that root size ignored the unknown sizes
|
||||
$this->assertEquals(-1, $this->cache->calculateFolderSize(''));
|
||||
|
||||
// clean up
|
||||
$this->cache->remove('');
|
||||
$this->cache->remove($dir1);
|
||||
$this->cache->remove($dir2);
|
||||
|
||||
$this->assertFalse($this->cache->inCache($dir1));
|
||||
$this->assertFalse($this->cache->inCache($dir2));
|
||||
}
|
||||
|
||||
function testStatus() {
|
||||
$this->assertEquals(\OC\Files\Cache\Cache::NOT_FOUND, $this->cache->getStatus('foo'));
|
||||
$this->cache->put('foo', array('size' => -1));
|
||||
|
@ -247,14 +274,14 @@ class Cache extends \PHPUnit_Framework_TestCase {
|
|||
$data = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
|
||||
$this->cache->put('foo', $data);
|
||||
$cachedData = $this->cache->get('foo');
|
||||
$this->assertEquals($data['mtime'], $cachedData['storage_mtime']);//if no storage_mtime is saved, mtime should be used
|
||||
$this->assertEquals($data['mtime'], $cachedData['storage_mtime']); //if no storage_mtime is saved, mtime should be used
|
||||
|
||||
$this->cache->put('foo', array('storage_mtime' => 30));//when setting storage_mtime, mtime is also set
|
||||
$this->cache->put('foo', array('storage_mtime' => 30)); //when setting storage_mtime, mtime is also set
|
||||
$cachedData = $this->cache->get('foo');
|
||||
$this->assertEquals(30, $cachedData['storage_mtime']);
|
||||
$this->assertEquals(30, $cachedData['mtime']);
|
||||
|
||||
$this->cache->put('foo', array('mtime' => 25));//setting mtime does not change storage_mtime
|
||||
$this->cache->put('foo', array('mtime' => 25)); //setting mtime does not change storage_mtime
|
||||
$cachedData = $this->cache->get('foo');
|
||||
$this->assertEquals(30, $cachedData['storage_mtime']);
|
||||
$this->assertEquals(25, $cachedData['mtime']);
|
||||
|
@ -295,18 +322,18 @@ class Cache extends \PHPUnit_Framework_TestCase {
|
|||
$this->assertGreaterThan(0, $cacheMock->put('folder', $data));
|
||||
|
||||
// put un-normalized folder
|
||||
$this->assertFalse($cacheMock->get('folder/' .$folderWith0308));
|
||||
$this->assertGreaterThan(0, $cacheMock->put('folder/' .$folderWith0308, $data));
|
||||
$this->assertFalse($cacheMock->get('folder/' . $folderWith0308));
|
||||
$this->assertGreaterThan(0, $cacheMock->put('folder/' . $folderWith0308, $data));
|
||||
|
||||
// get un-normalized folder by name
|
||||
$unNormalizedFolderName = $cacheMock->get('folder/' .$folderWith0308);
|
||||
$unNormalizedFolderName = $cacheMock->get('folder/' . $folderWith0308);
|
||||
|
||||
// check if database layer normalized the folder name (this should not happen)
|
||||
$this->assertEquals($folderWith0308, $unNormalizedFolderName['name']);
|
||||
|
||||
// put normalized folder
|
||||
$this->assertFalse($cacheMock->get('folder/' . $folderWith00F6));
|
||||
$this->assertGreaterThan(0, $cacheMock->put('folder/' .$folderWith00F6, $data));
|
||||
$this->assertGreaterThan(0, $cacheMock->put('folder/' . $folderWith00F6, $data));
|
||||
|
||||
// this is our bug, we have two different hashes with the same name (Schön)
|
||||
$this->assertEquals(2, count($cacheMock->getFolderContents('folder')));
|
||||
|
@ -317,7 +344,7 @@ class Cache extends \PHPUnit_Framework_TestCase {
|
|||
*/
|
||||
public function testWithNormalizer() {
|
||||
|
||||
if(!class_exists('Patchwork\PHP\Shim\Normalizer')) {
|
||||
if (!class_exists('Patchwork\PHP\Shim\Normalizer')) {
|
||||
$this->markTestSkipped('The 3rdparty Normalizer extension is not available.');
|
||||
return;
|
||||
}
|
||||
|
@ -335,18 +362,18 @@ class Cache extends \PHPUnit_Framework_TestCase {
|
|||
$this->assertGreaterThan(0, $this->cache->put('folder', $data));
|
||||
|
||||
// put un-normalized folder
|
||||
$this->assertFalse($this->cache->get('folder/' .$folderWith0308));
|
||||
$this->assertGreaterThan(0, $this->cache->put('folder/' .$folderWith0308, $data));
|
||||
$this->assertFalse($this->cache->get('folder/' . $folderWith0308));
|
||||
$this->assertGreaterThan(0, $this->cache->put('folder/' . $folderWith0308, $data));
|
||||
|
||||
// get un-normalized folder by name
|
||||
$unNormalizedFolderName = $this->cache->get('folder/' .$folderWith0308);
|
||||
$unNormalizedFolderName = $this->cache->get('folder/' . $folderWith0308);
|
||||
|
||||
// check if folder name was normalized
|
||||
$this->assertEquals($folderWith00F6, $unNormalizedFolderName['name']);
|
||||
|
||||
// put normalized folder
|
||||
$this->assertTrue(is_array($this->cache->get('folder/' . $folderWith00F6)));
|
||||
$this->assertGreaterThan(0, $this->cache->put('folder/' .$folderWith00F6, $data));
|
||||
$this->assertGreaterThan(0, $this->cache->put('folder/' . $folderWith00F6, $data));
|
||||
|
||||
// at this point we should have only one folder named "Schön"
|
||||
$this->assertEquals(1, count($this->cache->getFolderContents('folder')));
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace Test\Files\Cache;
|
||||
|
||||
class DummyUser extends \OC\User\User {
|
||||
/**
|
||||
* @var string $home
|
||||
*/
|
||||
private $home;
|
||||
|
||||
/**
|
||||
* @var string $uid
|
||||
*/
|
||||
private $uid;
|
||||
|
||||
public function __construct($uid, $home) {
|
||||
$this->home = $home;
|
||||
$this->uid = $uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHome() {
|
||||
return $this->home;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUID() {
|
||||
return $this->uid;
|
||||
}
|
||||
}
|
||||
|
||||
class HomeCache extends \PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* @var \OC\Files\Storage\Home $storage
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Cache\HomeCache $cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @var \OC\User\User $user
|
||||
*/
|
||||
private $user;
|
||||
|
||||
public function setUp() {
|
||||
$this->user = new DummyUser('foo', \OC_Helper::tmpFolder());
|
||||
$this->storage = new \OC\Files\Storage\Home(array('user' => $this->user));
|
||||
$this->cache = $this->storage->getCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the root folder size calculation ignores the subdirs that have an unknown
|
||||
* size. This makes sure that quota calculation still works as it's based on the root
|
||||
* folder size.
|
||||
*/
|
||||
public function testRootFolderSizeIgnoresUnknownUpdate() {
|
||||
$dir1 = 'knownsize';
|
||||
$dir2 = 'unknownsize';
|
||||
$fileData = array();
|
||||
$fileData[''] = array('size' => -1, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory');
|
||||
$fileData[$dir1] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory');
|
||||
$fileData[$dir2] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'httpd/unix-directory');
|
||||
|
||||
$this->cache->put('', $fileData['']);
|
||||
$this->cache->put($dir1, $fileData[$dir1]);
|
||||
$this->cache->put($dir2, $fileData[$dir2]);
|
||||
|
||||
$this->assertTrue($this->cache->inCache($dir1));
|
||||
$this->assertTrue($this->cache->inCache($dir2));
|
||||
|
||||
// check that root size ignored the unknown sizes
|
||||
$this->assertEquals(1000, $this->cache->calculateFolderSize(''));
|
||||
|
||||
// clean up
|
||||
$this->cache->remove('');
|
||||
$this->cache->remove($dir1);
|
||||
$this->cache->remove($dir2);
|
||||
|
||||
$this->assertFalse($this->cache->inCache($dir1));
|
||||
$this->assertFalse($this->cache->inCache($dir2));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue