From cd8f0c21ced2283a8cf8b48af1c91d665a1dab49 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 2 Jul 2013 18:22:49 +0200 Subject: [PATCH] add quota storage wrapper --- lib/files/storage/wrapper/quota.php | 104 ++++++++++++++++++++++ tests/lib/files/storage/wrapper/quota.php | 61 +++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 lib/files/storage/wrapper/quota.php create mode 100644 tests/lib/files/storage/wrapper/quota.php diff --git a/lib/files/storage/wrapper/quota.php b/lib/files/storage/wrapper/quota.php new file mode 100644 index 0000000000..bc2d893976 --- /dev/null +++ b/lib/files/storage/wrapper/quota.php @@ -0,0 +1,104 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage\Wrapper; + +class Quota extends Wrapper { + + /** + * @var int $quota + */ + protected $quota; + + /** + * @param array $parameters + */ + public function __construct($parameters) { + $this->storage = $parameters['storage']; + $this->quota = $parameters['quota']; + } + + protected function getSize($path) { + $cache = $this->getCache(); + $data = $cache->get($path); + if (is_array($data) and isset($data['size'])) { + return $data['size']; + } else { + return \OC\Files\SPACE_NOT_COMPUTED; + } + } + + /** + * Get free space as limited by the quota + * + * @param string $path + * @return int + */ + public function free_space($path) { + if ($this->quota < 0) { + return $this->storage->free_space($path); + } else { + $used = $this->getSize(''); + if ($used < 0) { + return \OC\Files\SPACE_NOT_COMPUTED; + } else { + $free = $this->storage->free_space($path); + return min($free, ($this->quota - $used)); + } + } + } + + /** + * see http://php.net/manual/en/function.file_put_contents.php + * + * @param string $path + * @param string $data + * @return bool + */ + public function file_put_contents($path, $data) { + $free = $this->free_space(''); + if ($free < 0 or strlen($data) < $free) { + return $this->storage->file_put_contents($path, $data); + } else { + return false; + } + } + + /** + * see http://php.net/manual/en/function.copy.php + * + * @param string $source + * @param string $target + * @return bool + */ + public function copy($source, $target) { + $free = $this->free_space(''); + if ($free < 0 or $this->getSize($source) < $free) { + return $this->storage->copy($source, $target); + } else { + return false; + } + } + + /** + * see http://php.net/manual/en/function.fopen.php + * + * @param string $path + * @param string $mode + * @return resource + */ + public function fopen($path, $mode) { + $source = $this->storage->fopen($path, $mode); + $free = $this->free_space(''); + if ($free >= 0) { + return \OC\Files\Stream\Quota::wrap($source, $free); + } else { + return $source; + } + } +} diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php new file mode 100644 index 0000000000..3702f8154f --- /dev/null +++ b/tests/lib/files/storage/wrapper/quota.php @@ -0,0 +1,61 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Storage\Wrapper; + +//ensure the constants are loaded +\OC::$loader->load('\OC\Files\Filesystem'); + +class Quota extends \Test\Files\Storage\Storage { + /** + * @var string tmpDir + */ + private $tmpDir; + + public function setUp() { + $this->tmpDir = \OC_Helper::tmpFolder(); + $storage = new \OC\Files\Storage\Local(array('datadir' => $this->tmpDir)); + $this->instance = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => 10000000)); + } + + public function tearDown() { + \OC_Helper::rmdirr($this->tmpDir); + } + + protected function getLimitedStorage($limit) { + $storage = new \OC\Files\Storage\Local(array('datadir' => $this->tmpDir)); + $storage->getScanner()->scan(''); + return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $limit)); + } + + public function testFilePutContentsNotEnoughSpace() { + $instance = $this->getLimitedStorage(3); + $this->assertFalse($instance->file_put_contents('foo', 'foobar')); + } + + public function testCopyNotEnoughSpace() { + $instance = $this->getLimitedStorage(9); + $this->assertEquals(6, $instance->file_put_contents('foo', 'foobar')); + $instance->getScanner()->scan(''); + $this->assertFalse($instance->copy('foo', 'bar')); + } + + public function testFreeSpace() { + $instance = $this->getLimitedStorage(9); + $this->assertEquals(9, $instance->free_space('')); + } + + public function testFWriteNotEnoughSpace() { + $instance = $this->getLimitedStorage(9); + $stream = $instance->fopen('foo', 'w+'); + $this->assertEquals(6, fwrite($stream, 'foobar')); + $this->assertEquals(3, fwrite($stream, 'qwerty')); + fclose($stream); + $this->assertEquals('foobarqwe', $instance->file_get_contents('foo')); + } +}