Merge pull request #20898 from owncloud/cache-interfaces
Public Cache interfaces
This commit is contained in:
commit
52040a3f23
|
@ -135,9 +135,8 @@ class ObjectTree extends \Sabre\DAV\Tree {
|
||||||
/**
|
/**
|
||||||
* @var \OC\Files\Storage\Storage $storage
|
* @var \OC\Files\Storage\Storage $storage
|
||||||
*/
|
*/
|
||||||
$scanner = $storage->getScanner($internalPath);
|
|
||||||
// get data directly
|
// get data directly
|
||||||
$data = $scanner->getData($internalPath);
|
$data = $storage->getMetaData($internalPath);
|
||||||
$info = new FileInfo($absPath, $storage, $internalPath, $data, $mount);
|
$info = new FileInfo($absPath, $storage, $internalPath, $data, $mount);
|
||||||
} else {
|
} else {
|
||||||
$info = null;
|
$info = null;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
namespace OC\Files\Cache;
|
namespace OC\Files\Cache;
|
||||||
|
|
||||||
use OC\User\NoUserException;
|
use OC\User\NoUserException;
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
use OCP\Share_Backend_Collection;
|
use OCP\Share_Backend_Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,8 +99,8 @@ class Shared_Cache extends Cache {
|
||||||
/**
|
/**
|
||||||
* get the stored metadata of a file or folder
|
* get the stored metadata of a file or folder
|
||||||
*
|
*
|
||||||
* @param string $file
|
* @param string|int $file
|
||||||
* @return array|false
|
* @return ICacheEntry|false
|
||||||
*/
|
*/
|
||||||
public function get($file) {
|
public function get($file) {
|
||||||
$mimetypeLoader = \OC::$server->getMimeTypeLoader();
|
$mimetypeLoader = \OC::$server->getMimeTypeLoader();
|
||||||
|
@ -161,7 +162,7 @@ class Shared_Cache extends Cache {
|
||||||
* get the metadata of all files stored in $folder
|
* get the metadata of all files stored in $folder
|
||||||
*
|
*
|
||||||
* @param string $folderId
|
* @param string $folderId
|
||||||
* @return array|false
|
* @return ICacheEntry[]|false
|
||||||
*/
|
*/
|
||||||
public function getFolderContentsById($folderId) {
|
public function getFolderContentsById($folderId) {
|
||||||
$cache = $this->getSourceCache('');
|
$cache = $this->getSourceCache('');
|
||||||
|
@ -281,7 +282,7 @@ class Shared_Cache extends Cache {
|
||||||
* search for files matching $pattern
|
* search for files matching $pattern
|
||||||
*
|
*
|
||||||
* @param string $pattern
|
* @param string $pattern
|
||||||
* @return array of file data
|
* @return ICacheEntry[] of file data
|
||||||
*/
|
*/
|
||||||
public function search($pattern) {
|
public function search($pattern) {
|
||||||
|
|
||||||
|
@ -320,7 +321,7 @@ class Shared_Cache extends Cache {
|
||||||
* search for files by mimetype
|
* search for files by mimetype
|
||||||
*
|
*
|
||||||
* @param string $mimetype
|
* @param string $mimetype
|
||||||
* @return array
|
* @return ICacheEntry[]
|
||||||
*/
|
*/
|
||||||
public function searchByMime($mimetype) {
|
public function searchByMime($mimetype) {
|
||||||
$mimepart = null;
|
$mimepart = null;
|
||||||
|
@ -373,7 +374,7 @@ class Shared_Cache extends Cache {
|
||||||
*
|
*
|
||||||
* @param string|int $tag tag to search for
|
* @param string|int $tag tag to search for
|
||||||
* @param string $userId owner of the tags
|
* @param string $userId owner of the tags
|
||||||
* @return array file data
|
* @return ICacheEntry[] file data
|
||||||
*/
|
*/
|
||||||
public function searchByTag($tag, $userId) {
|
public function searchByTag($tag, $userId) {
|
||||||
// TODO: inject this
|
// TODO: inject this
|
||||||
|
|
|
@ -35,7 +35,7 @@ class SharedScanner extends Scanner {
|
||||||
*
|
*
|
||||||
* @return array an array of metadata of the file
|
* @return array an array of metadata of the file
|
||||||
*/
|
*/
|
||||||
public function getData($path){
|
protected function getData($path){
|
||||||
$data = parent::getData($path);
|
$data = parent::getData($path);
|
||||||
$sourcePath = $this->storage->getSourcePath($path);
|
$sourcePath = $this->storage->getSourcePath($path);
|
||||||
list($sourceStorage, $internalPath) = \OC\Files\Filesystem::resolvePath($sourcePath);
|
list($sourceStorage, $internalPath) = \OC\Files\Filesystem::resolvePath($sourcePath);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OC\Files\Cache;
|
namespace OC\Files\Cache;
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check the storage backends for updates and change the cache accordingly
|
* check the storage backends for updates and change the cache accordingly
|
||||||
|
@ -38,7 +39,7 @@ class Shared_Watcher extends Watcher {
|
||||||
* Update the cache for changes to $path
|
* Update the cache for changes to $path
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param array $cachedData
|
* @param ICacheEntry $cachedData
|
||||||
*/
|
*/
|
||||||
public function update($path, $cachedData) {
|
public function update($path, $cachedData) {
|
||||||
parent::update($path, $cachedData);
|
parent::update($path, $cachedData);
|
||||||
|
|
|
@ -58,8 +58,10 @@ class Test_Files_Sharing_Backend extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown() {
|
protected function tearDown() {
|
||||||
$this->view->unlink($this->filename);
|
if ($this->view) {
|
||||||
$this->view->deleteAll($this->folder);
|
$this->view->unlink($this->filename);
|
||||||
|
$this->view->deleteAll($this->folder);
|
||||||
|
}
|
||||||
|
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,9 @@ class Cache extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown() {
|
protected function tearDown() {
|
||||||
$this->cache->clear();
|
if ($this->cache) {
|
||||||
|
$this->cache->clear();
|
||||||
|
}
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,10 @@ class Test_Files_Sharing_Mount extends OCA\Files_sharing\Tests\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown() {
|
protected function tearDown() {
|
||||||
$this->view->unlink($this->folder);
|
if ($this->view) {
|
||||||
$this->view->unlink($this->filename);
|
$this->view->unlink($this->folder);
|
||||||
|
$this->view->unlink($this->filename);
|
||||||
|
}
|
||||||
|
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,10 @@ class Test_Files_Sharing_Updater extends OCA\Files_Sharing\Tests\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown() {
|
protected function tearDown() {
|
||||||
$this->view->unlink($this->filename);
|
if ($this->view) {
|
||||||
$this->view->deleteAll($this->folder);
|
$this->view->unlink($this->filename);
|
||||||
|
$this->view->deleteAll($this->folder);
|
||||||
|
}
|
||||||
|
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,13 +88,15 @@ class Test_Files_Sharing_Watcher extends OCA\Files_sharing\Tests\TestCase {
|
||||||
|
|
||||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||||
|
|
||||||
$fileinfo = $this->view->getFileInfo('container/shareddir');
|
if ($this->view) {
|
||||||
\OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
|
$fileinfo = $this->view->getFileInfo('container/shareddir');
|
||||||
self::TEST_FILES_SHARING_API_USER2);
|
\OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
|
||||||
|
self::TEST_FILES_SHARING_API_USER2);
|
||||||
|
|
||||||
$this->view->deleteAll('container');
|
$this->view->deleteAll('container');
|
||||||
|
|
||||||
$this->ownerCache->clear();
|
$this->ownerCache->clear();
|
||||||
|
}
|
||||||
|
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,10 +86,12 @@ class Test_Files_Versioning extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown() {
|
protected function tearDown() {
|
||||||
$this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files/');
|
if ($this->rootView) {
|
||||||
$this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files/');
|
$this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files/');
|
||||||
$this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files_versions/');
|
$this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files/');
|
||||||
$this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files_versions/');
|
$this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files_versions/');
|
||||||
|
$this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files_versions/');
|
||||||
|
}
|
||||||
|
|
||||||
\OC_Hook::clear();
|
\OC_Hook::clear();
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
namespace OC\Files\Cache;
|
namespace OC\Files\Cache;
|
||||||
|
|
||||||
|
use OCP\Files\Cache\ICache;
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
use \OCP\Files\IMimeTypeLoader;
|
use \OCP\Files\IMimeTypeLoader;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
|
|
||||||
|
@ -46,12 +48,7 @@ use OCP\IDBConnection;
|
||||||
* - Updater: listens to changes made to the filesystem inside of the ownCloud instance and updates the cache where needed
|
* - Updater: listens to changes made to the filesystem inside of the ownCloud instance and updates the cache where needed
|
||||||
* - ChangePropagator: updates the mtime and etags of parent folders whenever a change to the cache is made to the cache by the updater
|
* - ChangePropagator: updates the mtime and etags of parent folders whenever a change to the cache is made to the cache by the updater
|
||||||
*/
|
*/
|
||||||
class Cache {
|
class Cache implements ICache {
|
||||||
const NOT_FOUND = 0;
|
|
||||||
const PARTIAL = 1; //only partial data available, file not cached in the database
|
|
||||||
const SHALLOW = 2; //folder in cache, but not all child files are completely scanned
|
|
||||||
const COMPLETE = 3;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array partial data for the cache
|
* @var array partial data for the cache
|
||||||
*/
|
*/
|
||||||
|
@ -105,28 +102,8 @@ class Cache {
|
||||||
/**
|
/**
|
||||||
* get the stored metadata of a file or folder
|
* get the stored metadata of a file or folder
|
||||||
*
|
*
|
||||||
* the returned cache entry contains at least the following values:
|
|
||||||
* [
|
|
||||||
* 'fileid' => int, the numeric id of a file (see getId)
|
|
||||||
* 'storage' => int, the numeric id of the storage the file is stored on
|
|
||||||
* 'path' => string, the path of the file within the storage ('foo/bar.txt')
|
|
||||||
* 'name' => string, the basename of a file ('bar.txt)
|
|
||||||
* 'mimetype' => string, the full mimetype of the file ('text/plain')
|
|
||||||
* 'mimepart' => string, the first half of the mimetype ('text')
|
|
||||||
* 'size' => int, the size of the file or folder in bytes
|
|
||||||
* 'mtime' => int, the last modified date of the file as unix timestamp as shown in the ui
|
|
||||||
* 'storage_mtime' => int, the last modified date of the file as unix timestamp as stored on the storage
|
|
||||||
* Note that when a file is updated we also update the mtime of all parent folders to make it visible to the user which folder has had updates most recently
|
|
||||||
* This can differ from the mtime on the underlying storage which usually only changes when a direct child is added, removed or renamed
|
|
||||||
* 'etag' => string, the etag for the file
|
|
||||||
* An etag is used for change detection of files and folders, an etag of a file changes whenever the content of the file changes
|
|
||||||
* Etag for folders change whenever a file in the folder has changed
|
|
||||||
* 'permissions' int, the permissions for the file stored as bitwise combination of \OCP\PERMISSION_READ, \OCP\PERMISSION_CREATE
|
|
||||||
* \OCP\PERMISSION_UPDATE, \OCP\PERMISSION_DELETE and \OCP\PERMISSION_SHARE
|
|
||||||
* ]
|
|
||||||
*
|
|
||||||
* @param string | int $file either the path of a file or folder or the file id for a file or folder
|
* @param string | int $file either the path of a file or folder or the file id for a file or folder
|
||||||
* @return array|false the cache entry as array of false if the file is not found in the cache
|
* @return ICacheEntry|false the cache entry as array of false if the file is not found in the cache
|
||||||
*/
|
*/
|
||||||
public function get($file) {
|
public function get($file) {
|
||||||
if (is_string($file) or $file == '') {
|
if (is_string($file) or $file == '') {
|
||||||
|
@ -156,6 +133,7 @@ class Cache {
|
||||||
if (isset($this->partial[$file])) {
|
if (isset($this->partial[$file])) {
|
||||||
$data = $this->partial[$file];
|
$data = $this->partial[$file];
|
||||||
}
|
}
|
||||||
|
return $data;
|
||||||
} else {
|
} else {
|
||||||
//fix types
|
//fix types
|
||||||
$data['fileid'] = (int)$data['fileid'];
|
$data['fileid'] = (int)$data['fileid'];
|
||||||
|
@ -171,16 +149,15 @@ class Cache {
|
||||||
$data['storage_mtime'] = $data['mtime'];
|
$data['storage_mtime'] = $data['mtime'];
|
||||||
}
|
}
|
||||||
$data['permissions'] = (int)$data['permissions'];
|
$data['permissions'] = (int)$data['permissions'];
|
||||||
|
return new CacheEntry($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the metadata of all files stored in $folder
|
* get the metadata of all files stored in $folder
|
||||||
*
|
*
|
||||||
* @param string $folder
|
* @param string $folder
|
||||||
* @return array
|
* @return ICacheEntry[]
|
||||||
*/
|
*/
|
||||||
public function getFolderContents($folder) {
|
public function getFolderContents($folder) {
|
||||||
$fileId = $this->getId($folder);
|
$fileId = $this->getId($folder);
|
||||||
|
@ -191,7 +168,7 @@ class Cache {
|
||||||
* get the metadata of all files stored in $folder
|
* get the metadata of all files stored in $folder
|
||||||
*
|
*
|
||||||
* @param int $fileId the file id of the folder
|
* @param int $fileId the file id of the folder
|
||||||
* @return array
|
* @return ICacheEntry[]
|
||||||
*/
|
*/
|
||||||
public function getFolderContentsById($fileId) {
|
public function getFolderContentsById($fileId) {
|
||||||
if ($fileId > -1) {
|
if ($fileId > -1) {
|
||||||
|
@ -211,7 +188,9 @@ class Cache {
|
||||||
$file['storage_mtime'] = (int)$file['storage_mtime'];
|
$file['storage_mtime'] = (int)$file['storage_mtime'];
|
||||||
$file['size'] = 0 + $file['size'];
|
$file['size'] = 0 + $file['size'];
|
||||||
}
|
}
|
||||||
return $files;
|
return array_map(function (array $data) {
|
||||||
|
return new CacheEntry($data);
|
||||||
|
}, $files);
|
||||||
} else {
|
} else {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
@ -392,7 +371,7 @@ class Cache {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
$parent = $this->getParentPath($file);
|
$parent = $this->getParentPath($file);
|
||||||
return (int) $this->getId($parent);
|
return (int)$this->getId($parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,12 +460,12 @@ class Cache {
|
||||||
/**
|
/**
|
||||||
* Move a file or folder in the cache
|
* Move a file or folder in the cache
|
||||||
*
|
*
|
||||||
* @param \OC\Files\Cache\Cache $sourceCache
|
* @param \OCP\Files\Cache\ICache $sourceCache
|
||||||
* @param string $sourcePath
|
* @param string $sourcePath
|
||||||
* @param string $targetPath
|
* @param string $targetPath
|
||||||
* @throws \OC\DatabaseException
|
* @throws \OC\DatabaseException
|
||||||
*/
|
*/
|
||||||
public function moveFromCache(Cache $sourceCache, $sourcePath, $targetPath) {
|
public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
|
||||||
// normalize source and target
|
// normalize source and target
|
||||||
$sourcePath = $this->normalize($sourcePath);
|
$sourcePath = $this->normalize($sourcePath);
|
||||||
$targetPath = $this->normalize($targetPath);
|
$targetPath = $this->normalize($targetPath);
|
||||||
|
@ -571,7 +550,7 @@ class Cache {
|
||||||
* search for files matching $pattern
|
* search for files matching $pattern
|
||||||
*
|
*
|
||||||
* @param string $pattern the search pattern using SQL search syntax (e.g. '%searchstring%')
|
* @param string $pattern the search pattern using SQL search syntax (e.g. '%searchstring%')
|
||||||
* @return array an array of cache entries where the name matches the search pattern
|
* @return ICacheEntry[] an array of cache entries where the name matches the search pattern
|
||||||
*/
|
*/
|
||||||
public function search($pattern) {
|
public function search($pattern) {
|
||||||
// normalize pattern
|
// normalize pattern
|
||||||
|
@ -594,7 +573,9 @@ class Cache {
|
||||||
$row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
|
$row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
|
||||||
$files[] = $row;
|
$files[] = $row;
|
||||||
}
|
}
|
||||||
return $files;
|
return array_map(function(array $data) {
|
||||||
|
return new CacheEntry($data);
|
||||||
|
}, $files);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -602,7 +583,7 @@ class Cache {
|
||||||
*
|
*
|
||||||
* @param string $mimetype either a full mimetype to search ('text/plain') or only the first part of a mimetype ('image')
|
* @param string $mimetype either a full mimetype to search ('text/plain') or only the first part of a mimetype ('image')
|
||||||
* where it will search for all mimetypes in the group ('image/*')
|
* where it will search for all mimetypes in the group ('image/*')
|
||||||
* @return array an array of cache entries where the mimetype matches the search
|
* @return ICacheEntry[] an array of cache entries where the mimetype matches the search
|
||||||
*/
|
*/
|
||||||
public function searchByMime($mimetype) {
|
public function searchByMime($mimetype) {
|
||||||
if (strpos($mimetype, '/')) {
|
if (strpos($mimetype, '/')) {
|
||||||
|
@ -620,7 +601,9 @@ class Cache {
|
||||||
$row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
|
$row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
|
||||||
$files[] = $row;
|
$files[] = $row;
|
||||||
}
|
}
|
||||||
return $files;
|
return array_map(function (array $data) {
|
||||||
|
return new CacheEntry($data);
|
||||||
|
}, $files);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -630,7 +613,7 @@ class Cache {
|
||||||
*
|
*
|
||||||
* @param string|int $tag name or tag id
|
* @param string|int $tag name or tag id
|
||||||
* @param string $userId owner of the tags
|
* @param string $userId owner of the tags
|
||||||
* @return array file data
|
* @return ICacheEntry[] file data
|
||||||
*/
|
*/
|
||||||
public function searchByTag($tag, $userId) {
|
public function searchByTag($tag, $userId) {
|
||||||
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, ' .
|
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, ' .
|
||||||
|
@ -665,7 +648,9 @@ class Cache {
|
||||||
while ($row = $result->fetch()) {
|
while ($row = $result->fetch()) {
|
||||||
$files[] = $row;
|
$files[] = $row;
|
||||||
}
|
}
|
||||||
return $files;
|
return array_map(function (array $data) {
|
||||||
|
return new CacheEntry($data);
|
||||||
|
}, $files);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin Appelman <icewind@owncloud.com>>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OC\Files\Cache;
|
||||||
|
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta data for a file or folder
|
||||||
|
*/
|
||||||
|
class CacheEntry implements ICacheEntry, \ArrayAccess {
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $data;
|
||||||
|
|
||||||
|
public function __construct(array $data) {
|
||||||
|
$this->data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetSet($offset, $value) {
|
||||||
|
$this->data[$offset] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetExists($offset) {
|
||||||
|
return isset($this->data[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset($offset) {
|
||||||
|
unset($this->data[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetGet($offset) {
|
||||||
|
if (isset($this->data[$offset])) {
|
||||||
|
return $this->data[$offset];
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId() {
|
||||||
|
return (int)$this->data['fileid'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStorageId() {
|
||||||
|
return $this->data['storage'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getPath() {
|
||||||
|
return $this->data['path'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return $this->data['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getMimeType() {
|
||||||
|
return $this->data['mimetype'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getMimePart() {
|
||||||
|
return $this->data['mimepart'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSize() {
|
||||||
|
return $this->data['size'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMTime() {
|
||||||
|
return $this->data['mtime'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStorageMTime() {
|
||||||
|
return $this->data['storage_mtime'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEtag() {
|
||||||
|
return $this->data['etag'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPermissions() {
|
||||||
|
return $this->data['permissions'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEncrypted() {
|
||||||
|
return isset($this->data['encrypted']) && $this->data['encrypted'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData() {
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
namespace OC\Files\Cache;
|
namespace OC\Files\Cache;
|
||||||
|
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
|
|
||||||
class HomeCache extends Cache {
|
class HomeCache extends Cache {
|
||||||
/**
|
/**
|
||||||
* get the size of a folder and set it in the cache
|
* get the size of a folder and set it in the cache
|
||||||
|
@ -67,7 +69,7 @@ class HomeCache extends Cache {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return array
|
* @return ICacheEntry
|
||||||
*/
|
*/
|
||||||
public function get($path) {
|
public function get($path) {
|
||||||
$data = parent::get($path);
|
$data = parent::get($path);
|
||||||
|
|
|
@ -21,10 +21,12 @@
|
||||||
|
|
||||||
namespace OC\Files\Cache;
|
namespace OC\Files\Cache;
|
||||||
|
|
||||||
|
use OCP\Files\Cache\IPropagator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Propagate etags and mtimes within the storage
|
* Propagate etags and mtimes within the storage
|
||||||
*/
|
*/
|
||||||
class Propagator {
|
class Propagator implements IPropagator {
|
||||||
/**
|
/**
|
||||||
* @var \OC\Files\Storage\Storage
|
* @var \OC\Files\Storage\Storage
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +43,7 @@ class Propagator {
|
||||||
/**
|
/**
|
||||||
* @param string $internalPath
|
* @param string $internalPath
|
||||||
* @param int $time
|
* @param int $time
|
||||||
* @return array[] all propagated entries
|
* @return array[] all propagated cache entries
|
||||||
*/
|
*/
|
||||||
public function propagateChange($internalPath, $time) {
|
public function propagateChange($internalPath, $time) {
|
||||||
$cache = $this->storage->getCache($internalPath);
|
$cache = $this->storage->getCache($internalPath);
|
||||||
|
|
|
@ -37,6 +37,8 @@ namespace OC\Files\Cache;
|
||||||
use OC\Files\Filesystem;
|
use OC\Files\Filesystem;
|
||||||
use OC\Hooks\BasicEmitter;
|
use OC\Hooks\BasicEmitter;
|
||||||
use OCP\Config;
|
use OCP\Config;
|
||||||
|
use OCP\Files\Cache\IScanner;
|
||||||
|
use OCP\Files\Storage\ILockingStorage;
|
||||||
use OCP\Lock\ILockingProvider;
|
use OCP\Lock\ILockingProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,7 +52,7 @@ use OCP\Lock\ILockingProvider;
|
||||||
*
|
*
|
||||||
* @package OC\Files\Cache
|
* @package OC\Files\Cache
|
||||||
*/
|
*/
|
||||||
class Scanner extends BasicEmitter {
|
class Scanner extends BasicEmitter implements IScanner {
|
||||||
/**
|
/**
|
||||||
* @var \OC\Files\Storage\Storage $storage
|
* @var \OC\Files\Storage\Storage $storage
|
||||||
*/
|
*/
|
||||||
|
@ -81,12 +83,6 @@ class Scanner extends BasicEmitter {
|
||||||
*/
|
*/
|
||||||
protected $lockingProvider;
|
protected $lockingProvider;
|
||||||
|
|
||||||
const SCAN_RECURSIVE = true;
|
|
||||||
const SCAN_SHALLOW = false;
|
|
||||||
|
|
||||||
const REUSE_ETAG = 1;
|
|
||||||
const REUSE_SIZE = 2;
|
|
||||||
|
|
||||||
public function __construct(\OC\Files\Storage\Storage $storage) {
|
public function __construct(\OC\Files\Storage\Storage $storage) {
|
||||||
$this->storage = $storage;
|
$this->storage = $storage;
|
||||||
$this->storageId = $this->storage->getId();
|
$this->storageId = $this->storage->getId();
|
||||||
|
@ -112,7 +108,7 @@ class Scanner extends BasicEmitter {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return array an array of metadata of the file
|
* @return array an array of metadata of the file
|
||||||
*/
|
*/
|
||||||
public function getData($path) {
|
protected function getData($path) {
|
||||||
$data = $this->storage->getMetaData($path);
|
$data = $this->storage->getMetaData($path);
|
||||||
if (is_null($data)) {
|
if (is_null($data)) {
|
||||||
\OCP\Util::writeLog('OC\Files\Cache\Scanner', "!!! Path '$path' is not accessible or present !!!", \OCP\Util::DEBUG);
|
\OCP\Util::writeLog('OC\Files\Cache\Scanner', "!!! Path '$path' is not accessible or present !!!", \OCP\Util::DEBUG);
|
||||||
|
@ -137,7 +133,9 @@ class Scanner extends BasicEmitter {
|
||||||
and !Filesystem::isFileBlacklisted($file)
|
and !Filesystem::isFileBlacklisted($file)
|
||||||
) {
|
) {
|
||||||
if ($lock) {
|
if ($lock) {
|
||||||
$this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
|
if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
|
$this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->emit('\OC\Files\Cache\Scanner', 'scanFile', array($file, $this->storageId));
|
$this->emit('\OC\Files\Cache\Scanner', 'scanFile', array($file, $this->storageId));
|
||||||
\OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
|
\OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
|
||||||
|
@ -160,6 +158,7 @@ class Scanner extends BasicEmitter {
|
||||||
$data['parent'] = $parentId;
|
$data['parent'] = $parentId;
|
||||||
}
|
}
|
||||||
if (is_null($cacheData)) {
|
if (is_null($cacheData)) {
|
||||||
|
/** @var CacheEntry $cacheData */
|
||||||
$cacheData = $this->cache->get($file);
|
$cacheData = $this->cache->get($file);
|
||||||
}
|
}
|
||||||
if ($cacheData and $reuseExisting and isset($cacheData['fileid'])) {
|
if ($cacheData and $reuseExisting and isset($cacheData['fileid'])) {
|
||||||
|
@ -182,7 +181,7 @@ class Scanner extends BasicEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Only update metadata that has changed
|
// Only update metadata that has changed
|
||||||
$newData = array_diff_assoc($data, $cacheData);
|
$newData = array_diff_assoc($data, $cacheData->getData());
|
||||||
} else {
|
} else {
|
||||||
$newData = $data;
|
$newData = $data;
|
||||||
$fileId = -1;
|
$fileId = -1;
|
||||||
|
@ -196,7 +195,9 @@ class Scanner extends BasicEmitter {
|
||||||
$this->removeFromCache($file);
|
$this->removeFromCache($file);
|
||||||
}
|
}
|
||||||
if ($lock) {
|
if ($lock) {
|
||||||
$this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
|
if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
|
$this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +264,9 @@ class Scanner extends BasicEmitter {
|
||||||
$reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
|
$reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
|
||||||
}
|
}
|
||||||
if ($lock) {
|
if ($lock) {
|
||||||
$this->storage->acquireLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
|
if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
|
$this->storage->acquireLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$data = $this->scanFile($path, $reuse, -1, null, $lock);
|
$data = $this->scanFile($path, $reuse, -1, null, $lock);
|
||||||
if ($data and $data['mimetype'] === 'httpd/unix-directory') {
|
if ($data and $data['mimetype'] === 'httpd/unix-directory') {
|
||||||
|
@ -271,7 +274,9 @@ class Scanner extends BasicEmitter {
|
||||||
$data['size'] = $size;
|
$data['size'] = $size;
|
||||||
}
|
}
|
||||||
if ($lock) {
|
if ($lock) {
|
||||||
$this->storage->releaseLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
|
if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
|
$this->storage->releaseLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OC\Files\Cache;
|
namespace OC\Files\Cache;
|
||||||
|
use OCP\Files\Cache\IUpdater;
|
||||||
|
use OCP\Files\Storage\IStorage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the cache and propagate changes
|
* Update the cache and propagate changes
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Updater {
|
class Updater implements IUpdater {
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
|
@ -145,18 +147,18 @@ class Updater {
|
||||||
/**
|
/**
|
||||||
* Rename a file or folder in the cache and update the size, etag and mtime of the parent folders
|
* Rename a file or folder in the cache and update the size, etag and mtime of the parent folders
|
||||||
*
|
*
|
||||||
* @param \OC\Files\Storage\Storage $sourceStorage
|
* @param IStorage $sourceStorage
|
||||||
* @param string $source
|
* @param string $source
|
||||||
* @param string $target
|
* @param string $target
|
||||||
*/
|
*/
|
||||||
public function renameFromStorage(\OC\Files\Storage\Storage $sourceStorage, $source, $target) {
|
public function renameFromStorage(IStorage $sourceStorage, $source, $target) {
|
||||||
if (!$this->enabled or Scanner::isPartialFile($source) or Scanner::isPartialFile($target)) {
|
if (!$this->enabled or Scanner::isPartialFile($source) or Scanner::isPartialFile($target)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$time = time();
|
$time = time();
|
||||||
|
|
||||||
$sourceCache = $sourceStorage->getCache($source);
|
$sourceCache = $sourceStorage->getCache();
|
||||||
$sourceUpdater = $sourceStorage->getUpdater();
|
$sourceUpdater = $sourceStorage->getUpdater();
|
||||||
$sourcePropagator = $sourceStorage->getPropagator();
|
$sourcePropagator = $sourceStorage->getPropagator();
|
||||||
|
|
||||||
|
@ -181,7 +183,9 @@ class Updater {
|
||||||
|
|
||||||
$sourceCache->correctFolderSize($source);
|
$sourceCache->correctFolderSize($source);
|
||||||
$this->cache->correctFolderSize($target);
|
$this->cache->correctFolderSize($target);
|
||||||
$sourceUpdater->correctParentStorageMtime($source);
|
if ($sourceUpdater instanceof Updater) {
|
||||||
|
$sourceUpdater->correctParentStorageMtime($source);
|
||||||
|
}
|
||||||
$this->correctParentStorageMtime($target);
|
$this->correctParentStorageMtime($target);
|
||||||
$this->updateStorageMTimeOnly($target);
|
$this->updateStorageMTimeOnly($target);
|
||||||
$sourcePropagator->propagateChange($source, $time);
|
$sourcePropagator->propagateChange($source, $time);
|
||||||
|
@ -205,7 +209,7 @@ class Updater {
|
||||||
*
|
*
|
||||||
* @param string $internalPath
|
* @param string $internalPath
|
||||||
*/
|
*/
|
||||||
public function correctParentStorageMtime($internalPath) {
|
private function correctParentStorageMtime($internalPath) {
|
||||||
$parentId = $this->cache->getParentId($internalPath);
|
$parentId = $this->cache->getParentId($internalPath);
|
||||||
$parent = dirname($internalPath);
|
$parent = dirname($internalPath);
|
||||||
if ($parentId != -1) {
|
if ($parentId != -1) {
|
||||||
|
|
|
@ -22,14 +22,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OC\Files\Cache;
|
namespace OC\Files\Cache;
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
|
use OCP\Files\Cache\IWatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check the storage backends for updates and change the cache accordingly
|
* check the storage backends for updates and change the cache accordingly
|
||||||
*/
|
*/
|
||||||
class Watcher {
|
class Watcher implements IWatcher {
|
||||||
const CHECK_NEVER = 0; // never check the underlying filesystem for updates
|
|
||||||
const CHECK_ONCE = 1; // check the underlying filesystem for updates once every request for each file
|
|
||||||
const CHECK_ALWAYS = 2; // always check the underlying filesystem for updates
|
|
||||||
|
|
||||||
protected $watchPolicy = self::CHECK_ONCE;
|
protected $watchPolicy = self::CHECK_ONCE;
|
||||||
|
|
||||||
|
@ -77,7 +76,7 @@ class Watcher {
|
||||||
* check $path for updates and update if needed
|
* check $path for updates and update if needed
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param array $cachedEntry
|
* @param ICacheEntry|null $cachedEntry
|
||||||
* @return boolean true if path was updated
|
* @return boolean true if path was updated
|
||||||
*/
|
*/
|
||||||
public function checkUpdate($path, $cachedEntry = null) {
|
public function checkUpdate($path, $cachedEntry = null) {
|
||||||
|
@ -96,7 +95,7 @@ class Watcher {
|
||||||
* Update the cache for changes to $path
|
* Update the cache for changes to $path
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param array $cachedData
|
* @param ICacheEntry $cachedData
|
||||||
*/
|
*/
|
||||||
public function update($path, $cachedData) {
|
public function update($path, $cachedData) {
|
||||||
if ($this->storage->is_dir($path)) {
|
if ($this->storage->is_dir($path)) {
|
||||||
|
@ -114,7 +113,7 @@ class Watcher {
|
||||||
* Check if the cache for $path needs to be updated
|
* Check if the cache for $path needs to be updated
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param array $cachedData
|
* @param ICacheEntry $cachedData
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function needsUpdate($path, $cachedData) {
|
public function needsUpdate($path, $cachedData) {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
namespace OC\Files\Cache\Wrapper;
|
namespace OC\Files\Cache\Wrapper;
|
||||||
|
|
||||||
use OC\Files\Cache\Cache;
|
use OC\Files\Cache\Cache;
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
|
|
||||||
class CacheWrapper extends Cache {
|
class CacheWrapper extends Cache {
|
||||||
/**
|
/**
|
||||||
|
@ -42,8 +43,8 @@ class CacheWrapper extends Cache {
|
||||||
/**
|
/**
|
||||||
* Make it easy for wrappers to modify every returned cache entry
|
* Make it easy for wrappers to modify every returned cache entry
|
||||||
*
|
*
|
||||||
* @param array $entry
|
* @param ICacheEntry $entry
|
||||||
* @return array
|
* @return ICacheEntry
|
||||||
*/
|
*/
|
||||||
protected function formatCacheEntry($entry) {
|
protected function formatCacheEntry($entry) {
|
||||||
return $entry;
|
return $entry;
|
||||||
|
@ -53,7 +54,7 @@ class CacheWrapper extends Cache {
|
||||||
* get the stored metadata of a file or folder
|
* get the stored metadata of a file or folder
|
||||||
*
|
*
|
||||||
* @param string /int $file
|
* @param string /int $file
|
||||||
* @return array|false
|
* @return ICacheEntry|false
|
||||||
*/
|
*/
|
||||||
public function get($file) {
|
public function get($file) {
|
||||||
$result = $this->cache->get($file);
|
$result = $this->cache->get($file);
|
||||||
|
@ -67,7 +68,7 @@ class CacheWrapper extends Cache {
|
||||||
* get the metadata of all files stored in $folder
|
* get the metadata of all files stored in $folder
|
||||||
*
|
*
|
||||||
* @param string $folder
|
* @param string $folder
|
||||||
* @return array
|
* @return ICacheEntry[]
|
||||||
*/
|
*/
|
||||||
public function getFolderContents($folder) {
|
public function getFolderContents($folder) {
|
||||||
// cant do a simple $this->cache->.... call here since getFolderContentsById needs to be called on this
|
// cant do a simple $this->cache->.... call here since getFolderContentsById needs to be called on this
|
||||||
|
@ -178,7 +179,7 @@ class CacheWrapper extends Cache {
|
||||||
* search for files matching $pattern
|
* search for files matching $pattern
|
||||||
*
|
*
|
||||||
* @param string $pattern
|
* @param string $pattern
|
||||||
* @return array an array of file data
|
* @return ICacheEntry[] an array of file data
|
||||||
*/
|
*/
|
||||||
public function search($pattern) {
|
public function search($pattern) {
|
||||||
$results = $this->cache->search($pattern);
|
$results = $this->cache->search($pattern);
|
||||||
|
@ -189,7 +190,7 @@ class CacheWrapper extends Cache {
|
||||||
* search for files by mimetype
|
* search for files by mimetype
|
||||||
*
|
*
|
||||||
* @param string $mimetype
|
* @param string $mimetype
|
||||||
* @return array
|
* @return ICacheEntry[]
|
||||||
*/
|
*/
|
||||||
public function searchByMime($mimetype) {
|
public function searchByMime($mimetype) {
|
||||||
$results = $this->cache->searchByMime($mimetype);
|
$results = $this->cache->searchByMime($mimetype);
|
||||||
|
@ -201,7 +202,7 @@ class CacheWrapper extends Cache {
|
||||||
*
|
*
|
||||||
* @param string|int $tag name or tag id
|
* @param string|int $tag name or tag id
|
||||||
* @param string $userId owner of the tags
|
* @param string $userId owner of the tags
|
||||||
* @return array file data
|
* @return ICacheEntry[] file data
|
||||||
*/
|
*/
|
||||||
public function searchByTag($tag, $userId) {
|
public function searchByTag($tag, $userId) {
|
||||||
$results = $this->cache->searchByTag($tag, $userId);
|
$results = $this->cache->searchByTag($tag, $userId);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
namespace OC\Files;
|
namespace OC\Files;
|
||||||
|
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
use OCP\IUser;
|
use OCP\IUser;
|
||||||
|
|
||||||
class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
||||||
|
@ -71,7 +72,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
|
||||||
* @param string|boolean $path
|
* @param string|boolean $path
|
||||||
* @param Storage\Storage $storage
|
* @param Storage\Storage $storage
|
||||||
* @param string $internalPath
|
* @param string $internalPath
|
||||||
* @param array $data
|
* @param array|ICacheEntry $data
|
||||||
* @param \OCP\Files\Mount\IMountPoint $mount
|
* @param \OCP\Files\Mount\IMountPoint $mount
|
||||||
* @param \OCP\IUser|null $owner
|
* @param \OCP\IUser|null $owner
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
namespace OC\Files\ObjectStore;
|
namespace OC\Files\ObjectStore;
|
||||||
|
|
||||||
use Icewind\Streams\IteratorDirectory;
|
use Icewind\Streams\IteratorDirectory;
|
||||||
|
use OC\Files\Cache\CacheEntry;
|
||||||
use OCP\Files\ObjectStore\IObjectStore;
|
use OCP\Files\ObjectStore\IObjectStore;
|
||||||
|
|
||||||
class ObjectStoreStorage extends \OC\Files\Storage\Common {
|
class ObjectStoreStorage extends \OC\Files\Storage\Common {
|
||||||
|
@ -192,7 +193,12 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
|
||||||
|
|
||||||
public function stat($path) {
|
public function stat($path) {
|
||||||
$path = $this->normalizePath($path);
|
$path = $this->normalizePath($path);
|
||||||
return $this->getCache()->get($path);
|
$cacheEntry = $this->getCache()->get($path);
|
||||||
|
if ($cacheEntry instanceof CacheEntry) {
|
||||||
|
return $cacheEntry->getData();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -46,6 +46,7 @@ use OCP\Files\FileNameTooLongException;
|
||||||
use OCP\Files\InvalidCharacterInPathException;
|
use OCP\Files\InvalidCharacterInPathException;
|
||||||
use OCP\Files\InvalidPathException;
|
use OCP\Files\InvalidPathException;
|
||||||
use OCP\Files\ReservedWordException;
|
use OCP\Files\ReservedWordException;
|
||||||
|
use OCP\Files\Storage\ILockingStorage;
|
||||||
use OCP\Lock\ILockingProvider;
|
use OCP\Lock\ILockingProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +60,7 @@ use OCP\Lock\ILockingProvider;
|
||||||
* Some \OC\Files\Storage\Common methods call functions which are first defined
|
* Some \OC\Files\Storage\Common methods call functions which are first defined
|
||||||
* in classes which extend it, e.g. $this->stat() .
|
* in classes which extend it, e.g. $this->stat() .
|
||||||
*/
|
*/
|
||||||
abstract class Common implements Storage {
|
abstract class Common implements Storage, ILockingStorage {
|
||||||
|
|
||||||
use LocalTempFileTrait;
|
use LocalTempFileTrait;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace OC\Files\Storage\Wrapper;
|
||||||
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
|
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
|
||||||
use OC\Encryption\Update;
|
use OC\Encryption\Update;
|
||||||
use OC\Encryption\Util;
|
use OC\Encryption\Util;
|
||||||
|
use OC\Files\Cache\CacheEntry;
|
||||||
use OC\Files\Filesystem;
|
use OC\Files\Filesystem;
|
||||||
use OC\Files\Mount\Manager;
|
use OC\Files\Mount\Manager;
|
||||||
use OC\Files\Storage\LocalTempFileTrait;
|
use OC\Files\Storage\LocalTempFileTrait;
|
||||||
|
@ -123,13 +124,14 @@ class Encryption extends Wrapper {
|
||||||
public function filesize($path) {
|
public function filesize($path) {
|
||||||
$fullPath = $this->getFullPath($path);
|
$fullPath = $this->getFullPath($path);
|
||||||
|
|
||||||
|
/** @var CacheEntry $info */
|
||||||
$info = $this->getCache()->get($path);
|
$info = $this->getCache()->get($path);
|
||||||
if (isset($this->unencryptedSize[$fullPath])) {
|
if (isset($this->unencryptedSize[$fullPath])) {
|
||||||
$size = $this->unencryptedSize[$fullPath];
|
$size = $this->unencryptedSize[$fullPath];
|
||||||
// update file cache
|
// update file cache
|
||||||
$info['encrypted'] = true;
|
$info['encrypted'] = true;
|
||||||
$info['size'] = $size;
|
$info['size'] = $size;
|
||||||
$this->getCache()->put($path, $info);
|
$this->getCache()->put($path, $info->getData());
|
||||||
|
|
||||||
return $size;
|
return $size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
namespace OC\Files\Storage\Wrapper;
|
namespace OC\Files\Storage\Wrapper;
|
||||||
|
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
|
|
||||||
class Quota extends Wrapper {
|
class Quota extends Wrapper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +66,7 @@ class Quota extends Wrapper {
|
||||||
$cache = $storage->getCache();
|
$cache = $storage->getCache();
|
||||||
}
|
}
|
||||||
$data = $cache->get($path);
|
$data = $cache->get($path);
|
||||||
if (is_array($data) and isset($data['size'])) {
|
if ($data instanceof ICacheEntry and isset($data['size'])) {
|
||||||
return $data['size'];
|
return $data['size'];
|
||||||
} else {
|
} else {
|
||||||
return \OCP\Files\FileInfo::SPACE_NOT_COMPUTED;
|
return \OCP\Files\FileInfo::SPACE_NOT_COMPUTED;
|
||||||
|
|
|
@ -26,9 +26,10 @@
|
||||||
namespace OC\Files\Storage\Wrapper;
|
namespace OC\Files\Storage\Wrapper;
|
||||||
|
|
||||||
use OCP\Files\InvalidPathException;
|
use OCP\Files\InvalidPathException;
|
||||||
|
use OCP\Files\Storage\ILockingStorage;
|
||||||
use OCP\Lock\ILockingProvider;
|
use OCP\Lock\ILockingProvider;
|
||||||
|
|
||||||
class Wrapper implements \OC\Files\Storage\Storage {
|
class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage {
|
||||||
/**
|
/**
|
||||||
* @var \OC\Files\Storage\Storage $storage
|
* @var \OC\Files\Storage\Storage $storage
|
||||||
*/
|
*/
|
||||||
|
@ -583,7 +584,9 @@ class Wrapper implements \OC\Files\Storage\Storage {
|
||||||
* @throws \OCP\Lock\LockedException
|
* @throws \OCP\Lock\LockedException
|
||||||
*/
|
*/
|
||||||
public function acquireLock($path, $type, ILockingProvider $provider) {
|
public function acquireLock($path, $type, ILockingProvider $provider) {
|
||||||
$this->storage->acquireLock($path, $type, $provider);
|
if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
|
$this->storage->acquireLock($path, $type, $provider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -592,7 +595,9 @@ class Wrapper implements \OC\Files\Storage\Storage {
|
||||||
* @param \OCP\Lock\ILockingProvider $provider
|
* @param \OCP\Lock\ILockingProvider $provider
|
||||||
*/
|
*/
|
||||||
public function releaseLock($path, $type, ILockingProvider $provider) {
|
public function releaseLock($path, $type, ILockingProvider $provider) {
|
||||||
$this->storage->releaseLock($path, $type, $provider);
|
if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
|
$this->storage->releaseLock($path, $type, $provider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -601,6 +606,8 @@ class Wrapper implements \OC\Files\Storage\Storage {
|
||||||
* @param \OCP\Lock\ILockingProvider $provider
|
* @param \OCP\Lock\ILockingProvider $provider
|
||||||
*/
|
*/
|
||||||
public function changeLock($path, $type, ILockingProvider $provider) {
|
public function changeLock($path, $type, ILockingProvider $provider) {
|
||||||
$this->storage->changeLock($path, $type, $provider);
|
if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
|
$this->storage->changeLock($path, $type, $provider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,15 +43,16 @@
|
||||||
namespace OC\Files;
|
namespace OC\Files;
|
||||||
|
|
||||||
use Icewind\Streams\CallbackWrapper;
|
use Icewind\Streams\CallbackWrapper;
|
||||||
use OC\Files\Cache\Updater;
|
|
||||||
use OC\Files\Mount\MoveableMount;
|
use OC\Files\Mount\MoveableMount;
|
||||||
use OC\Files\Storage\Storage;
|
use OC\Files\Storage\Storage;
|
||||||
use OC\User\User;
|
use OC\User\User;
|
||||||
|
use OCP\Files\Cache\ICacheEntry;
|
||||||
use OCP\Files\FileNameTooLongException;
|
use OCP\Files\FileNameTooLongException;
|
||||||
use OCP\Files\InvalidCharacterInPathException;
|
use OCP\Files\InvalidCharacterInPathException;
|
||||||
use OCP\Files\InvalidPathException;
|
use OCP\Files\InvalidPathException;
|
||||||
use OCP\Files\NotFoundException;
|
use OCP\Files\NotFoundException;
|
||||||
use OCP\Files\ReservedWordException;
|
use OCP\Files\ReservedWordException;
|
||||||
|
use OCP\Files\Storage\ILockingStorage;
|
||||||
use OCP\IUser;
|
use OCP\IUser;
|
||||||
use OCP\Lock\ILockingProvider;
|
use OCP\Lock\ILockingProvider;
|
||||||
use OCP\Lock\LockedException;
|
use OCP\Lock\LockedException;
|
||||||
|
@ -1274,7 +1275,7 @@ class View {
|
||||||
if ($storage) {
|
if ($storage) {
|
||||||
$data = $this->getCacheEntry($storage, $internalPath, $relativePath);
|
$data = $this->getCacheEntry($storage, $internalPath, $relativePath);
|
||||||
|
|
||||||
if (!is_array($data)) {
|
if (!$data instanceof ICacheEntry) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1334,7 +1335,7 @@ class View {
|
||||||
|
|
||||||
$data = $this->getCacheEntry($storage, $internalPath, $directory);
|
$data = $this->getCacheEntry($storage, $internalPath, $directory);
|
||||||
|
|
||||||
if (!is_array($data) || !isset($data['fileid'])) {
|
if (!$data instanceof ICacheEntry || !isset($data['fileid'])) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1345,7 +1346,7 @@ class View {
|
||||||
/**
|
/**
|
||||||
* @var \OC\Files\FileInfo[] $files
|
* @var \OC\Files\FileInfo[] $files
|
||||||
*/
|
*/
|
||||||
$files = array_map(function (array $content) use ($path, $storage, $mount, $sharingDisabled) {
|
$files = array_map(function (ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) {
|
||||||
if ($sharingDisabled) {
|
if ($sharingDisabled) {
|
||||||
$content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
|
$content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
|
||||||
}
|
}
|
||||||
|
@ -1834,11 +1835,14 @@ class View {
|
||||||
$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
|
$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
|
||||||
if ($mount) {
|
if ($mount) {
|
||||||
try {
|
try {
|
||||||
$mount->getStorage()->acquireLock(
|
$storage = $mount->getStorage();
|
||||||
$mount->getInternalPath($absolutePath),
|
if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
$type,
|
$storage->acquireLock(
|
||||||
$this->lockingProvider
|
$mount->getInternalPath($absolutePath),
|
||||||
);
|
$type,
|
||||||
|
$this->lockingProvider
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (\OCP\Lock\LockedException $e) {
|
} catch (\OCP\Lock\LockedException $e) {
|
||||||
// rethrow with the a human-readable path
|
// rethrow with the a human-readable path
|
||||||
throw new \OCP\Lock\LockedException(
|
throw new \OCP\Lock\LockedException(
|
||||||
|
@ -1872,11 +1876,14 @@ class View {
|
||||||
$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
|
$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
|
||||||
if ($mount) {
|
if ($mount) {
|
||||||
try {
|
try {
|
||||||
$mount->getStorage()->changeLock(
|
$storage = $mount->getStorage();
|
||||||
$mount->getInternalPath($absolutePath),
|
if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
$type,
|
$storage->changeLock(
|
||||||
$this->lockingProvider
|
$mount->getInternalPath($absolutePath),
|
||||||
);
|
$type,
|
||||||
|
$this->lockingProvider
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (\OCP\Lock\LockedException $e) {
|
} catch (\OCP\Lock\LockedException $e) {
|
||||||
// rethrow with the a human-readable path
|
// rethrow with the a human-readable path
|
||||||
throw new \OCP\Lock\LockedException(
|
throw new \OCP\Lock\LockedException(
|
||||||
|
@ -1907,11 +1914,14 @@ class View {
|
||||||
|
|
||||||
$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
|
$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
|
||||||
if ($mount) {
|
if ($mount) {
|
||||||
$mount->getStorage()->releaseLock(
|
$storage = $mount->getStorage();
|
||||||
$mount->getInternalPath($absolutePath),
|
if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
|
||||||
$type,
|
$storage->releaseLock(
|
||||||
$this->lockingProvider
|
$mount->getInternalPath($absolutePath),
|
||||||
);
|
$type,
|
||||||
|
$this->lockingProvider
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin Appelman <icewind@owncloud.com>>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCP\Files\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata cache for a storage
|
||||||
|
*
|
||||||
|
* The cache stores the metadata for all files and folders in a storage and is kept up to date trough the following mechanisms:
|
||||||
|
*
|
||||||
|
* - Scanner: scans the storage and updates the cache where needed
|
||||||
|
* - Watcher: checks for changes made to the filesystem outside of the ownCloud instance and rescans files and folder when a change is detected
|
||||||
|
* - Updater: listens to changes made to the filesystem inside of the ownCloud instance and updates the cache where needed
|
||||||
|
* - ChangePropagator: updates the mtime and etags of parent folders whenever a change to the cache is made to the cache by the updater
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
interface ICache {
|
||||||
|
const NOT_FOUND = 0;
|
||||||
|
const PARTIAL = 1; //only partial data available, file not cached in the database
|
||||||
|
const SHALLOW = 2; //folder in cache, but not all child files are completely scanned
|
||||||
|
const COMPLETE = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the numeric storage id for this cache's storage
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getNumericStorageId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the stored metadata of a file or folder
|
||||||
|
*
|
||||||
|
* @param string | int $file either the path of a file or folder or the file id for a file or folder
|
||||||
|
* @return ICacheEntry[]|false the cache entry or false if the file is not found in the cache
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function get($file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the metadata of all files stored in $folder
|
||||||
|
*
|
||||||
|
* @param string $folder
|
||||||
|
* @return ICacheEntry[]
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getFolderContents($folder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the metadata of all files stored in $folder
|
||||||
|
*
|
||||||
|
* @param int $fileId the file id of the folder
|
||||||
|
* @return ICacheEntry[]
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getFolderContentsById($fileId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* store meta data for a file or folder
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return int file id
|
||||||
|
* @throws \RuntimeException
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function put($file, array $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update the metadata of an existing file or folder in the cache
|
||||||
|
*
|
||||||
|
* @param int $id the fileid of the existing file or folder
|
||||||
|
* @param array $data [$key => $value] the metadata to update, only the fields provided in the array will be updated, non-provided values will remain unchanged
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function update($id, array $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the file id for a file
|
||||||
|
*
|
||||||
|
* A file id is a numeric id for a file or folder that's unique within an owncloud instance which stays the same for the lifetime of a file
|
||||||
|
*
|
||||||
|
* File ids are easiest way for apps to store references to a file since unlike paths they are not affected by renames or sharing
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getId($file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the id of the parent folder of a file
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getParentId($file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if a file is available in the cache
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function inCache($file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a file or folder from the cache
|
||||||
|
*
|
||||||
|
* when removing a folder from the cache all files and folders inside the folder will be removed as well
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function remove($file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move a file or folder in the cache
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function move($source, $target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move a file or folder in the cache
|
||||||
|
*
|
||||||
|
* @param \OCP\Files\Cache\ICache $sourceCache
|
||||||
|
* @param string $sourcePath
|
||||||
|
* @param string $targetPath
|
||||||
|
* @throws \OC\DatabaseException
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove all entries for files that are stored on the storage from the cache
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scan status of a file
|
||||||
|
*
|
||||||
|
* - ICache::NOT_FOUND: File is not in the cache
|
||||||
|
* - ICache::PARTIAL: File is not stored in the cache but some incomplete data is known
|
||||||
|
* - ICache::SHALLOW: The folder and it's direct children are in the cache but not all sub folders are fully scanned
|
||||||
|
* - ICache::COMPLETE: The file or folder, with all it's children) are fully scanned
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
*
|
||||||
|
* @return int ICache::NOT_FOUND, ICache::PARTIAL, ICache::SHALLOW or ICache::COMPLETE
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getStatus($file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search for files matching $pattern
|
||||||
|
*
|
||||||
|
* @param string $pattern the search pattern using SQL search syntax (e.g. '%searchstring%')
|
||||||
|
* @return ICacheEntry[] an array of cache entries where the name matches the search pattern
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function search($pattern);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search for files by mimetype
|
||||||
|
*
|
||||||
|
* @param string $mimetype either a full mimetype to search ('text/plain') or only the first part of a mimetype ('image')
|
||||||
|
* where it will search for all mimetypes in the group ('image/*')
|
||||||
|
* @return ICacheEntry[] an array of cache entries where the mimetype matches the search
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function searchByMime($mimetype);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for files by tag of a given users.
|
||||||
|
*
|
||||||
|
* Note that every user can tag files differently.
|
||||||
|
*
|
||||||
|
* @param string|int $tag name or tag id
|
||||||
|
* @param string $userId owner of the tags
|
||||||
|
* @return ICacheEntry[] file data
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function searchByTag($tag, $userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all file ids on the files on the storage
|
||||||
|
*
|
||||||
|
* @return int[]
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find a folder in the cache which has not been fully scanned
|
||||||
|
*
|
||||||
|
* If multiple incomplete folders are in the cache, the one with the highest id will be returned,
|
||||||
|
* use the one with the highest id gives the best result with the background scanner, since that is most
|
||||||
|
* likely the folder where we stopped scanning previously
|
||||||
|
*
|
||||||
|
* @return string|bool the path of the folder or false when no folder matched
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getIncomplete();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the path of a file on this storage by it's file id
|
||||||
|
*
|
||||||
|
* @param int $id the file id of the file or folder to search
|
||||||
|
* @return string|null the path of the file (relative to the storage) or null if a file with the given id does not exists within this cache
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getPathById($id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* normalize the given path for usage in the cache
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function normalize($path);
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin Appelman <icewind@owncloud.com>>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCP\Files\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta data for a file or folder
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
interface ICacheEntry {
|
||||||
|
/**
|
||||||
|
* Get the numeric id of a file
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the numeric id for the storage
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getStorageId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the path of the file relative to the storage root
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getPath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the file name
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the full mimetype
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getMimeType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first part of the mimetype
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getMimePart();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the file size in bytes
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the last modified date as unix timestamp
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getMTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the last modified date on the storage as unix timestamp
|
||||||
|
*
|
||||||
|
* Note that when a file is updated we also update the mtime of all parent folders to make it visible to the user which folder has had updates most recently
|
||||||
|
* This can differ from the mtime on the underlying storage which usually only changes when a direct child is added, removed or renamed
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getStorageMTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the etag for the file
|
||||||
|
*
|
||||||
|
* An etag is used for change detection of files and folders, an etag of a file changes whenever the content of the file changes
|
||||||
|
* Etag for folders change whenever a file in the folder has changed
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getEtag();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the permissions for the file stored as bitwise combination of \OCP\PERMISSION_READ, \OCP\PERMISSION_CREATE
|
||||||
|
* \OCP\PERMISSION_UPDATE, \OCP\PERMISSION_DELETE and \OCP\PERMISSION_SHARE
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getPermissions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the file is encrypted
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function isEncrypted();
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin Appelman <icewind@owncloud.com>>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCP\Files\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Propagate etags and mtimes within the storage
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
interface IPropagator {
|
||||||
|
/**
|
||||||
|
* @param string $internalPath
|
||||||
|
* @param int $time
|
||||||
|
* @return array[] all propagated cache entries
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function propagateChange($internalPath, $time);
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin Appelman <icewind@owncloud.com>>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCP\Files\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan files from the storage and save to the cache
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
interface IScanner {
|
||||||
|
const SCAN_RECURSIVE = true;
|
||||||
|
const SCAN_SHALLOW = false;
|
||||||
|
|
||||||
|
const REUSE_ETAG = 1;
|
||||||
|
const REUSE_SIZE = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scan a single file and store it in the cache
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @param int $reuseExisting
|
||||||
|
* @param int $parentId
|
||||||
|
* @param array | null $cacheData existing data in the cache for the file to be scanned
|
||||||
|
* @param bool $lock set to false to disable getting an additional read lock during scanning
|
||||||
|
* @return array an array of metadata of the scanned file
|
||||||
|
* @throws \OC\ServerNotAvailableException
|
||||||
|
* @throws \OCP\Lock\LockedException
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scan a folder and all its children
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param bool $recursive
|
||||||
|
* @param int $reuse
|
||||||
|
* @param bool $lock set to false to disable getting an additional read lock during scanning
|
||||||
|
* @return array an array of the meta data of the scanned file or folder
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $lock = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if the file should be ignored when scanning
|
||||||
|
* NOTE: files with a '.part' extension are ignored as well!
|
||||||
|
* prevents unfinished put requests to be scanned
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return boolean
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public static function isPartialFile($file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* walk over any folders that are not fully scanned yet and scan them
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function backgroundScan();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin Appelman <icewind@owncloud.com>>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCP\Files\Cache;
|
||||||
|
|
||||||
|
use OCP\Files\Storage\IStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cache and propagate changes
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
interface IUpdater {
|
||||||
|
/**
|
||||||
|
* Get the propagator for etags and mtime for the view the updater works on
|
||||||
|
*
|
||||||
|
* @return IPropagator
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getPropagator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Propagate etag and mtime changes for the parent folders of $path up to the root of the filesystem
|
||||||
|
*
|
||||||
|
* @param string $path the path of the file to propagate the changes for
|
||||||
|
* @param int|null $time the timestamp to set as mtime for the parent folders, if left out the current time is used
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function propagate($path, $time = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cache for $path and update the size, etag and mtime of the parent folders
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param int $time
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function update($path, $time = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove $path from the cache and update the size, etag and mtime of the parent folders
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function remove($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rename a file or folder in the cache and update the size, etag and mtime of the parent folders
|
||||||
|
*
|
||||||
|
* @param IStorage $sourceStorage
|
||||||
|
* @param string $source
|
||||||
|
* @param string $target
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function renameFromStorage(IStorage $sourceStorage, $source, $target);
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin Appelman <icewind@owncloud.com>>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCP\Files\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check the storage backends for updates and change the cache accordingly
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
interface IWatcher {
|
||||||
|
const CHECK_NEVER = 0; // never check the underlying filesystem for updates
|
||||||
|
const CHECK_ONCE = 1; // check the underlying filesystem for updates once every request for each file
|
||||||
|
const CHECK_ALWAYS = 2; // always check the underlying filesystem for updates
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $policy either IWatcher::CHECK_NEVER, IWatcher::CHECK_ONCE, IWatcher::CHECK_ALWAYS
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function setPolicy($policy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int either IWatcher::CHECK_NEVER, IWatcher::CHECK_ONCE, IWatcher::CHECK_ALWAYS
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getPolicy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check $path for updates and update if needed
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param ICacheEntry|null $cachedEntry
|
||||||
|
* @return boolean true if path was updated
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function checkUpdate($path, $cachedEntry = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cache for changes to $path
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param ICacheEntry $cachedData
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function update($path, $cachedData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the cache for $path needs to be updated
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param ICacheEntry $cachedData
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function needsUpdate($path, $cachedData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove deleted files in $path from the cache
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function cleanFolder($path);
|
||||||
|
}
|
|
@ -33,16 +33,19 @@
|
||||||
// use OCP namespace for all classes that are considered public.
|
// use OCP namespace for all classes that are considered public.
|
||||||
// This means that they should be used by apps instead of the internal ownCloud classes
|
// This means that they should be used by apps instead of the internal ownCloud classes
|
||||||
namespace OCP\Files;
|
namespace OCP\Files;
|
||||||
use OCP\Files\InvalidPathException;
|
|
||||||
|
use OCP\Files\Storage\IStorage;
|
||||||
use OCP\Lock\ILockingProvider;
|
use OCP\Lock\ILockingProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide a common interface to all different storage options
|
* Provide a common interface to all different storage options
|
||||||
*
|
*
|
||||||
* All paths passed to the storage are relative to the storage and should NOT have a leading slash.
|
* All paths passed to the storage are relative to the storage and should NOT have a leading slash.
|
||||||
|
*
|
||||||
* @since 6.0.0
|
* @since 6.0.0
|
||||||
|
* @deprecated 9.0.0 use \OCP\Files\Storage\IStorage instead
|
||||||
*/
|
*/
|
||||||
interface Storage {
|
interface Storage extends IStorage {
|
||||||
/**
|
/**
|
||||||
* $parameters is a free form array with the configuration options needed to construct the storage
|
* $parameters is a free form array with the configuration options needed to construct the storage
|
||||||
*
|
*
|
||||||
|
@ -462,10 +465,4 @@ interface Storage {
|
||||||
* @param bool $isAvailable
|
* @param bool $isAvailable
|
||||||
*/
|
*/
|
||||||
public function setAvailability($isAvailable);
|
public function setAvailability($isAvailable);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $path path for which to retrieve the owner
|
|
||||||
* @since 9.0.0
|
|
||||||
*/
|
|
||||||
public function getOwner($path);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Robin Appelman <icewind@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCP\Files\Storage;
|
||||||
|
|
||||||
|
use OCP\Lock\ILockingProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage backends that require explicit locking
|
||||||
|
*
|
||||||
|
* Storage backends implementing this interface do not need to implement their own locking implementation but should use the provided lockingprovider instead
|
||||||
|
* The implementation of the locking methods only need to map internal storage paths to "lock keys"
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
interface ILockingStorage {
|
||||||
|
/**
|
||||||
|
* @param string $path The path of the file to acquire the lock for
|
||||||
|
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
|
||||||
|
* @param \OCP\Lock\ILockingProvider $provider
|
||||||
|
* @throws \OCP\Lock\LockedException
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function acquireLock($path, $type, ILockingProvider $provider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path The path of the file to acquire the lock for
|
||||||
|
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
|
||||||
|
* @param \OCP\Lock\ILockingProvider $provider
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function releaseLock($path, $type, ILockingProvider $provider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path The path of the file to change the lock for
|
||||||
|
* @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
|
||||||
|
* @param \OCP\Lock\ILockingProvider $provider
|
||||||
|
* @throws \OCP\Lock\LockedException
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function changeLock($path, $type, ILockingProvider $provider);
|
||||||
|
}
|
|
@ -0,0 +1,482 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||||
|
* @author Michael Roth <michael.roth@rz.uni-augsburg.de>
|
||||||
|
* @author Morris Jobke <hey@morrisjobke.de>
|
||||||
|
* @author Robin Appelman <icewind@owncloud.com>
|
||||||
|
* @author Robin McCorkell <rmccorkell@karoshi.org.uk>
|
||||||
|
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||||
|
* @author Vincent Petry <pvince81@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public interface of ownCloud for apps to use.
|
||||||
|
* Files/Storage interface
|
||||||
|
*/
|
||||||
|
|
||||||
|
// use OCP namespace for all classes that are considered public.
|
||||||
|
// This means that they should be used by apps instead of the internal ownCloud classes
|
||||||
|
namespace OCP\Files\Storage;
|
||||||
|
|
||||||
|
use OCP\Files\Cache\ICache;
|
||||||
|
use OCP\Files\Cache\IPropagator;
|
||||||
|
use OCP\Files\Cache\IScanner;
|
||||||
|
use OCP\Files\Cache\IUpdater;
|
||||||
|
use OCP\Files\Cache\IWatcher;
|
||||||
|
use OCP\Files\InvalidPathException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide a common interface to all different storage options
|
||||||
|
*
|
||||||
|
* All paths passed to the storage are relative to the storage and should NOT have a leading slash.
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
interface IStorage {
|
||||||
|
/**
|
||||||
|
* $parameters is a free form array with the configuration options needed to construct the storage
|
||||||
|
*
|
||||||
|
* @param array $parameters
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function __construct($parameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the identifier for the storage,
|
||||||
|
* the returned id should be the same for every storage object that is created with the same parameters
|
||||||
|
* and two storage objects with the same id should refer to two storages that display the same files.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.mkdir.php
|
||||||
|
* implementations need to implement a recursive mkdir
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function mkdir($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.rmdir.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function rmdir($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.opendir.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return resource|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function opendir($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.is-dir.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function is_dir($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.is-file.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function is_file($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.stat.php
|
||||||
|
* only the following keys are required in the result: size and mtime
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return array|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function stat($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.filetype.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function filetype($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.filesize.php
|
||||||
|
* The result for filesize when called on a folder is required to be 0
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return int|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function filesize($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if a file can be created in $path
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function isCreatable($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if a file can be read
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function isReadable($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if a file can be written to
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function isUpdatable($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if a file can be deleted
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function isDeletable($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if a file can be shared
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function isSharable($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the full permissions of a path.
|
||||||
|
* Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return int
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getPermissions($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.file_exists.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function file_exists($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.filemtime.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return int|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function filemtime($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.file_get_contents.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function file_get_contents($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.file_put_contents.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param string $data
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function file_put_contents($path, $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.unlink.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function unlink($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.rename.php
|
||||||
|
*
|
||||||
|
* @param string $path1
|
||||||
|
* @param string $path2
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function rename($path1, $path2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.copy.php
|
||||||
|
*
|
||||||
|
* @param string $path1
|
||||||
|
* @param string $path2
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function copy($path1, $path2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.fopen.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param string $mode
|
||||||
|
* @return resource|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function fopen($path, $mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the mimetype for a file or folder
|
||||||
|
* The mimetype for a folder is required to be "httpd/unix-directory"
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getMimeType($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.hash-file.php
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param string $path
|
||||||
|
* @param bool $raw
|
||||||
|
* @return string|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function hash($type, $path, $raw = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.free_space.php
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return int|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function free_space($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search for occurrences of $query in file names
|
||||||
|
*
|
||||||
|
* @param string $query
|
||||||
|
* @return array|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function search($query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* see http://php.net/manual/en/function.touch.php
|
||||||
|
* If the backend does not support the operation, false should be returned
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param int $mtime
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function touch($path, $mtime = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the path to a local version of the file.
|
||||||
|
* The local version of the file can be temporary and doesn't have to be persistent across requests
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getLocalFile($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the path to a local version of the folder.
|
||||||
|
* The local version of the folder can be temporary and doesn't have to be persistent across requests
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getLocalFolder($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if a file or folder has been updated since $time
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param int $time
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*
|
||||||
|
* hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
|
||||||
|
* returning true for other changes in the folder is optional
|
||||||
|
*/
|
||||||
|
public function hasUpdated($path, $time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the ETag for a file or folder
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getETag($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the storage is local, which means that files
|
||||||
|
* are stored on the local filesystem instead of remotely.
|
||||||
|
* Calling getLocalFile() for local storages should always
|
||||||
|
* return the local files, whereas for non-local storages
|
||||||
|
* it might return a temporary file.
|
||||||
|
*
|
||||||
|
* @return bool true if the files are stored locally, false otherwise
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function isLocal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class
|
||||||
|
*
|
||||||
|
* @param string $class
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function instanceOfStorage($class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom storage implementation can return an url for direct download of a give file.
|
||||||
|
*
|
||||||
|
* For now the returned array can hold the parameter url - in future more attributes might follow.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return array|false
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getDirectDownload($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path the path of the target folder
|
||||||
|
* @param string $fileName the name of the file itself
|
||||||
|
* @return void
|
||||||
|
* @throws InvalidPathException
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function verifyPath($path, $fileName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \OCP\Files\Storage $sourceStorage
|
||||||
|
* @param string $sourceInternalPath
|
||||||
|
* @param string $targetInternalPath
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \OCP\Files\Storage $sourceStorage
|
||||||
|
* @param string $sourceInternalPath
|
||||||
|
* @param string $targetInternalPath
|
||||||
|
* @return bool
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test a storage for availability
|
||||||
|
*
|
||||||
|
* @since 9.0.0
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function test();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 9.0.0
|
||||||
|
* @return array [ available, last_checked ]
|
||||||
|
*/
|
||||||
|
public function getAvailability();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 9.0.0
|
||||||
|
* @param bool $isAvailable
|
||||||
|
*/
|
||||||
|
public function setAvailability($isAvailable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path path for which to retrieve the owner
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getOwner($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICache
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getCache();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IPropagator
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getPropagator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IScanner
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getScanner();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IUpdater
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getUpdater();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IWatcher
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getWatcher();
|
||||||
|
}
|
|
@ -556,7 +556,7 @@ class Cache extends \Test\TestCase {
|
||||||
$this->assertEquals($folderWith00F6, $unNormalizedFolderName['name']);
|
$this->assertEquals($folderWith00F6, $unNormalizedFolderName['name']);
|
||||||
|
|
||||||
// put normalized folder
|
// put normalized folder
|
||||||
$this->assertTrue(is_array($this->cache->get('folder/' . $folderWith00F6)));
|
$this->assertInstanceOf('\OCP\Files\Cache\ICacheEntry', $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"
|
// at this point we should have only one folder named "Schön"
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Test\Files\Cache;
|
namespace Test\Files\Cache;
|
||||||
|
use OC\Files\Cache\CacheEntry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Scanner
|
* Class Scanner
|
||||||
|
@ -226,6 +227,7 @@ class Scanner extends \Test\TestCase {
|
||||||
|
|
||||||
// manipulate etag to simulate an empty etag
|
// manipulate etag to simulate an empty etag
|
||||||
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
|
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
|
||||||
|
/** @var CacheEntry $data0 */
|
||||||
$data0 = $this->cache->get('folder/bar.txt');
|
$data0 = $this->cache->get('folder/bar.txt');
|
||||||
$this->assertInternalType('string', $data0['etag']);
|
$this->assertInternalType('string', $data0['etag']);
|
||||||
$data1 = $this->cache->get('folder');
|
$data1 = $this->cache->get('folder');
|
||||||
|
@ -233,7 +235,7 @@ class Scanner extends \Test\TestCase {
|
||||||
$data2 = $this->cache->get('');
|
$data2 = $this->cache->get('');
|
||||||
$this->assertInternalType('string', $data2['etag']);
|
$this->assertInternalType('string', $data2['etag']);
|
||||||
$data0['etag'] = '';
|
$data0['etag'] = '';
|
||||||
$this->cache->put('folder/bar.txt', $data0);
|
$this->cache->put('folder/bar.txt', $data0->getData());
|
||||||
|
|
||||||
// rescan
|
// rescan
|
||||||
$this->scanner->scan('folder/bar.txt', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
|
$this->scanner->scan('folder/bar.txt', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
namespace Test\Files\Storage\Wrapper;
|
namespace Test\Files\Storage\Wrapper;
|
||||||
|
|
||||||
//ensure the constants are loaded
|
//ensure the constants are loaded
|
||||||
|
use OC\Files\Cache\CacheEntry;
|
||||||
|
|
||||||
\OC::$loader->load('\OC\Files\Filesystem');
|
\OC::$loader->load('\OC\Files\Filesystem');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,7 +196,7 @@ class Quota extends \Test\Files\Storage\Storage {
|
||||||
$cache->expects($this->once())
|
$cache->expects($this->once())
|
||||||
->method('get')
|
->method('get')
|
||||||
->with('files')
|
->with('files')
|
||||||
->will($this->returnValue(array('size' => 50)));
|
->will($this->returnValue(new CacheEntry(['size' => 50])));
|
||||||
|
|
||||||
$instance = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => 1024, 'root' => 'files'));
|
$instance = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => 1024, 'root' => 'files'));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue