diff --git a/apps/files_sharing/lib/Cache.php b/apps/files_sharing/lib/Cache.php index 21f3ff622f..49765a7aab 100644 --- a/apps/files_sharing/lib/Cache.php +++ b/apps/files_sharing/lib/Cache.php @@ -42,39 +42,33 @@ class Cache extends CacheJail { */ private $storage; - /** - * @var IStorage - */ - private $sourceStorage; - /** * @var ICacheEntry */ private $sourceRootInfo; - /** - * @var \OCP\Files\Cache\ICache - */ - private $sourceCache; - private $rootUnchanged = true; /** * @param \OCA\Files_Sharing\SharedStorage $storage - * @param IStorage $sourceStorage * @param ICacheEntry $sourceRootInfo */ - public function __construct($storage, IStorage $sourceStorage, ICacheEntry $sourceRootInfo) { + public function __construct($storage, ICacheEntry $sourceRootInfo) { $this->storage = $storage; - $this->sourceStorage = $sourceStorage; $this->sourceRootInfo = $sourceRootInfo; - $this->sourceCache = $sourceStorage->getCache(); parent::__construct( - $this->sourceCache, + null, $this->sourceRootInfo->getPath() ); } + public function getCache() { + if (is_null($this->cache)) { + $this->cache = $this->storage->getSourceStorage()->getCache(); + } + return $this->cache; + } + public function getNumericStorageId() { if (isset($this->numericId)) { return $this->numericId; diff --git a/apps/files_sharing/lib/MountProvider.php b/apps/files_sharing/lib/MountProvider.php index 1ee6f2b35f..40d2fb2753 100644 --- a/apps/files_sharing/lib/MountProvider.php +++ b/apps/files_sharing/lib/MountProvider.php @@ -172,6 +172,9 @@ class MountProvider implements IMountProvider { $share->setTarget($superShare->getTarget()); $this->shareManager->moveShare($share, $user->getUID()); } + if (!is_null($share->getNodeCacheEntry())) { + $superShare->setNodeCacheEntry($share->getNodeCacheEntry()); + } } $superShare->setPermissions($permissions); diff --git a/apps/files_sharing/lib/SharedStorage.php b/apps/files_sharing/lib/SharedStorage.php index 7002d388d9..5b4aa06180 100644 --- a/apps/files_sharing/lib/SharedStorage.php +++ b/apps/files_sharing/lib/SharedStorage.php @@ -71,6 +71,8 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto */ private $logger; + private $options; + public function __construct($arguments) { $this->ownerView = $arguments['ownerView']; $this->logger = \OC::$server->getLogger(); @@ -86,6 +88,20 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto ]); } + /** + * @return ICacheEntry + */ + private function getSourceRootInfo() { + if (is_null($this->sourceRootInfo)) { + if (is_null($this->superShare->getNodeCacheEntry())) { + $this->sourceRootInfo = $this->getWrapperStorage()->getCache()->get($this->rootPath); + } else { + $this->sourceRootInfo = $this->superShare->getNodeCacheEntry(); + } + } + return $this->sourceRootInfo; + } + private function init() { if ($this->initialized) { return; @@ -95,7 +111,6 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto Filesystem::initMountPoints($this->superShare->getShareOwner()); $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId()); list($this->storage, $this->rootPath) = $this->ownerView->resolvePath($sourcePath); - $this->sourceRootInfo = $this->storage->getCache()->get($this->rootPath); } catch (NotFoundException $e) { $this->storage = new FailedStorage(['exception' => $e]); $this->rootPath = ''; @@ -110,6 +125,9 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto * @inheritdoc */ public function instanceOfStorage($class) { + if ($class === '\OC\Files\Storage\Common') { + return true; + } if (in_array($class, ['\OC\Files\Storage\Home', '\OC\Files\ObjectStore\HomeObjectStoreStorage'])) { return false; } @@ -124,8 +142,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto } private function isValid() { - $this->init(); - return $this->sourceRootInfo && ($this->sourceRootInfo->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE; + return $this->getSourceRootInfo() && ($this->getSourceRootInfo()->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE; } /** @@ -314,14 +331,10 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto if ($this->cache) { return $this->cache; } - $this->init(); - if (is_null($this->storage) || $this->storage instanceof FailedStorage) { - return new FailedCache(false); - } if (!$storage) { $storage = $this; } - $this->cache = new \OCA\Files_Sharing\Cache($storage, $this->storage, $this->sourceRootInfo); + $this->cache = new \OCA\Files_Sharing\Cache($storage, $this->getSourceRootInfo(), $this->superShare); return $this->cache; } @@ -449,4 +462,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto return parent::file_put_contents($path, $data); } + public function setMountOptions(array $options) { + $this->mountOptions = $options; + } } diff --git a/lib/private/DB/QueryBuilder/QuoteHelper.php b/lib/private/DB/QueryBuilder/QuoteHelper.php index 6d15cec5a0..041718bce5 100644 --- a/lib/private/DB/QueryBuilder/QuoteHelper.php +++ b/lib/private/DB/QueryBuilder/QuoteHelper.php @@ -61,6 +61,11 @@ class QuoteHelper { throw new \InvalidArgumentException('Only strings, Literals and Parameters are allowed'); } + $string = str_replace(' AS ', ' as ', $string); + if (substr_count($string, ' as ')) { + return implode(' as ', array_map([$this, 'quoteColumnName'], explode(' as ', $string, 2))); + } + if (substr_count($string, '.')) { list($alias, $columnName) = explode('.', $string, 2); diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index 5083b99b86..3a3f51488e 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -142,25 +142,37 @@ class Cache implements ICache { } return $data; } else { - //fix types - $data['fileid'] = (int)$data['fileid']; - $data['parent'] = (int)$data['parent']; - $data['size'] = 0 + $data['size']; - $data['mtime'] = (int)$data['mtime']; - $data['storage_mtime'] = (int)$data['storage_mtime']; - $data['encryptedVersion'] = (int)$data['encrypted']; - $data['encrypted'] = (bool)$data['encrypted']; - $data['storage'] = $this->storageId; - $data['mimetype'] = $this->mimetypeLoader->getMimetypeById($data['mimetype']); - $data['mimepart'] = $this->mimetypeLoader->getMimetypeById($data['mimepart']); - if ($data['storage_mtime'] == 0) { - $data['storage_mtime'] = $data['mtime']; - } - $data['permissions'] = (int)$data['permissions']; - return new CacheEntry($data); + return self::cacheEntryFromData($data, $this->storageId, $this->mimetypeLoader); } } + /** + * Create a CacheEntry from database row + * + * @param array $data + * @param string $storageId + * @param IMimeTypeLoader $mimetypeLoader + * @return CacheEntry + */ + public static function cacheEntryFromData($data, $storageId, IMimeTypeLoader $mimetypeLoader) { + //fix types + $data['fileid'] = (int)$data['fileid']; + $data['parent'] = (int)$data['parent']; + $data['size'] = 0 + $data['size']; + $data['mtime'] = (int)$data['mtime']; + $data['storage_mtime'] = (int)$data['storage_mtime']; + $data['encryptedVersion'] = (int)$data['encrypted']; + $data['encrypted'] = (bool)$data['encrypted']; + $data['storage'] = $storageId; + $data['mimetype'] = $mimetypeLoader->getMimetypeById($data['mimetype']); + $data['mimepart'] = $mimetypeLoader->getMimetypeById($data['mimepart']); + if ($data['storage_mtime'] == 0) { + $data['storage_mtime'] = $data['mtime']; + } + $data['permissions'] = (int)$data['permissions']; + return new CacheEntry($data); + } + /** * get the metadata of all files stored in $folder * diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php index 0a379aefdc..d8bdca6a3c 100644 --- a/lib/private/Files/Cache/Wrapper/CacheJail.php +++ b/lib/private/Files/Cache/Wrapper/CacheJail.php @@ -112,7 +112,7 @@ class CacheJail extends CacheWrapper { * @throws \RuntimeException */ public function insert($file, array $data) { - return $this->cache->insert($this->getSourcePath($file), $data); + return $this->getCache()->insert($this->getSourcePath($file), $data); } /** @@ -122,7 +122,7 @@ class CacheJail extends CacheWrapper { * @param array $data */ public function update($id, array $data) { - $this->cache->update($id, $data); + $this->getCache()->update($id, $data); } /** @@ -132,7 +132,7 @@ class CacheJail extends CacheWrapper { * @return int */ public function getId($file) { - return $this->cache->getId($this->getSourcePath($file)); + return $this->getCache()->getId($this->getSourcePath($file)); } /** @@ -145,7 +145,7 @@ class CacheJail extends CacheWrapper { if ($file === '') { return -1; } else { - return $this->cache->getParentId($this->getSourcePath($file)); + return $this->getCache()->getParentId($this->getSourcePath($file)); } } @@ -156,7 +156,7 @@ class CacheJail extends CacheWrapper { * @return bool */ public function inCache($file) { - return $this->cache->inCache($this->getSourcePath($file)); + return $this->getCache()->inCache($this->getSourcePath($file)); } /** @@ -165,7 +165,7 @@ class CacheJail extends CacheWrapper { * @param string $file */ public function remove($file) { - $this->cache->remove($this->getSourcePath($file)); + $this->getCache()->remove($this->getSourcePath($file)); } /** @@ -175,14 +175,14 @@ class CacheJail extends CacheWrapper { * @param string $target */ public function move($source, $target) { - $this->cache->move($this->getSourcePath($source), $this->getSourcePath($target)); + $this->getCache()->move($this->getSourcePath($source), $this->getSourcePath($target)); } /** * remove all entries for files that are stored on the storage from the cache */ public function clear() { - $this->cache->remove($this->root); + $this->getCache()->remove($this->root); } /** @@ -191,7 +191,7 @@ class CacheJail extends CacheWrapper { * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE */ public function getStatus($file) { - return $this->cache->getStatus($this->getSourcePath($file)); + return $this->getCache()->getStatus($this->getSourcePath($file)); } private function formatSearchResults($results) { @@ -207,7 +207,7 @@ class CacheJail extends CacheWrapper { * @return array an array of file data */ public function search($pattern) { - $results = $this->cache->search($pattern); + $results = $this->getCache()->search($pattern); return $this->formatSearchResults($results); } @@ -218,7 +218,7 @@ class CacheJail extends CacheWrapper { * @return array */ public function searchByMime($mimetype) { - $results = $this->cache->searchByMime($mimetype); + $results = $this->getCache()->searchByMime($mimetype); return $this->formatSearchResults($results); } @@ -230,7 +230,7 @@ class CacheJail extends CacheWrapper { * @return array */ public function searchByTag($tag, $userId) { - $results = $this->cache->searchByTag($tag, $userId); + $results = $this->getCache()->searchByTag($tag, $userId); return $this->formatSearchResults($results); } @@ -241,8 +241,8 @@ class CacheJail extends CacheWrapper { * @param array $data (optional) meta data of the folder */ public function correctFolderSize($path, $data = null) { - if ($this->cache instanceof Cache) { - $this->cache->correctFolderSize($this->getSourcePath($path), $data); + if ($this->getCache() instanceof Cache) { + $this->getCache()->correctFolderSize($this->getSourcePath($path), $data); } } @@ -254,8 +254,8 @@ class CacheJail extends CacheWrapper { * @return int */ public function calculateFolderSize($path, $entry = null) { - if ($this->cache instanceof Cache) { - return $this->cache->calculateFolderSize($this->getSourcePath($path), $entry); + if ($this->getCache() instanceof Cache) { + return $this->getCache()->calculateFolderSize($this->getSourcePath($path), $entry); } else { return 0; } @@ -293,7 +293,7 @@ class CacheJail extends CacheWrapper { * @return string|null */ public function getPathById($id) { - $path = $this->cache->getPathById($id); + $path = $this->getCache()->getPathById($id); return $this->getJailedPath($path); } @@ -310,6 +310,6 @@ class CacheJail extends CacheWrapper { if ($sourceCache === $this) { return $this->move($sourcePath, $targetPath); } - return $this->cache->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath)); + return $this->getCache()->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath)); } } diff --git a/lib/private/Files/Cache/Wrapper/CacheWrapper.php b/lib/private/Files/Cache/Wrapper/CacheWrapper.php index 7a8177566c..83fe7e5f43 100644 --- a/lib/private/Files/Cache/Wrapper/CacheWrapper.php +++ b/lib/private/Files/Cache/Wrapper/CacheWrapper.php @@ -45,6 +45,10 @@ class CacheWrapper extends Cache { $this->cache = $cache; } + protected function getCache() { + return $this->cache; + } + /** * Make it easy for wrappers to modify every returned cache entry * @@ -62,7 +66,7 @@ class CacheWrapper extends Cache { * @return ICacheEntry|false */ public function get($file) { - $result = $this->cache->get($file); + $result = $this->getCache()->get($file); if ($result) { $result = $this->formatCacheEntry($result); } @@ -76,7 +80,7 @@ class CacheWrapper extends Cache { * @return ICacheEntry[] */ public function getFolderContents($folder) { - // can't do a simple $this->cache->.... call here since getFolderContentsById needs to be called on this + // can't do a simple $this->getCache()->.... call here since getFolderContentsById needs to be called on this // and not the wrapped cache $fileId = $this->getId($folder); return $this->getFolderContentsById($fileId); @@ -89,7 +93,7 @@ class CacheWrapper extends Cache { * @return array */ public function getFolderContentsById($fileId) { - $results = $this->cache->getFolderContentsById($fileId); + $results = $this->getCache()->getFolderContentsById($fileId); return array_map(array($this, 'formatCacheEntry'), $results); } @@ -121,7 +125,7 @@ class CacheWrapper extends Cache { * @throws \RuntimeException */ public function insert($file, array $data) { - return $this->cache->insert($file, $data); + return $this->getCache()->insert($file, $data); } /** @@ -131,7 +135,7 @@ class CacheWrapper extends Cache { * @param array $data */ public function update($id, array $data) { - $this->cache->update($id, $data); + $this->getCache()->update($id, $data); } /** @@ -141,7 +145,7 @@ class CacheWrapper extends Cache { * @return int */ public function getId($file) { - return $this->cache->getId($file); + return $this->getCache()->getId($file); } /** @@ -151,7 +155,7 @@ class CacheWrapper extends Cache { * @return int */ public function getParentId($file) { - return $this->cache->getParentId($file); + return $this->getCache()->getParentId($file); } /** @@ -161,7 +165,7 @@ class CacheWrapper extends Cache { * @return bool */ public function inCache($file) { - return $this->cache->inCache($file); + return $this->getCache()->inCache($file); } /** @@ -170,7 +174,7 @@ class CacheWrapper extends Cache { * @param string $file */ public function remove($file) { - $this->cache->remove($file); + $this->getCache()->remove($file); } /** @@ -180,18 +184,18 @@ class CacheWrapper extends Cache { * @param string $target */ public function move($source, $target) { - $this->cache->move($source, $target); + $this->getCache()->move($source, $target); } public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) { - $this->cache->moveFromCache($sourceCache, $sourcePath, $targetPath); + $this->getCache()->moveFromCache($sourceCache, $sourcePath, $targetPath); } /** * remove all entries for files that are stored on the storage from the cache */ public function clear() { - $this->cache->clear(); + $this->getCache()->clear(); } /** @@ -200,7 +204,7 @@ class CacheWrapper extends Cache { * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE */ public function getStatus($file) { - return $this->cache->getStatus($file); + return $this->getCache()->getStatus($file); } /** @@ -210,7 +214,7 @@ class CacheWrapper extends Cache { * @return ICacheEntry[] an array of file data */ public function search($pattern) { - $results = $this->cache->search($pattern); + $results = $this->getCache()->search($pattern); return array_map(array($this, 'formatCacheEntry'), $results); } @@ -221,7 +225,7 @@ class CacheWrapper extends Cache { * @return ICacheEntry[] */ public function searchByMime($mimetype) { - $results = $this->cache->searchByMime($mimetype); + $results = $this->getCache()->searchByMime($mimetype); return array_map(array($this, 'formatCacheEntry'), $results); } @@ -233,7 +237,7 @@ class CacheWrapper extends Cache { * @return ICacheEntry[] file data */ public function searchByTag($tag, $userId) { - $results = $this->cache->searchByTag($tag, $userId); + $results = $this->getCache()->searchByTag($tag, $userId); return array_map(array($this, 'formatCacheEntry'), $results); } @@ -244,8 +248,8 @@ class CacheWrapper extends Cache { * @param array $data (optional) meta data of the folder */ public function correctFolderSize($path, $data = null) { - if ($this->cache instanceof Cache) { - $this->cache->correctFolderSize($path, $data); + if ($this->getCache() instanceof Cache) { + $this->getCache()->correctFolderSize($path, $data); } } @@ -257,8 +261,8 @@ class CacheWrapper extends Cache { * @return int */ public function calculateFolderSize($path, $entry = null) { - if ($this->cache instanceof Cache) { - return $this->cache->calculateFolderSize($path, $entry); + if ($this->getCache() instanceof Cache) { + return $this->getCache()->calculateFolderSize($path, $entry); } else { return 0; } @@ -270,7 +274,7 @@ class CacheWrapper extends Cache { * @return int[] */ public function getAll() { - return $this->cache->getAll(); + return $this->getCache()->getAll(); } /** @@ -283,7 +287,7 @@ class CacheWrapper extends Cache { * @return string|bool the path of the folder or false when no folder matched */ public function getIncomplete() { - return $this->cache->getIncomplete(); + return $this->getCache()->getIncomplete(); } /** @@ -293,7 +297,7 @@ class CacheWrapper extends Cache { * @return string|null */ public function getPathById($id) { - return $this->cache->getPathById($id); + return $this->getCache()->getPathById($id); } /** @@ -302,7 +306,7 @@ class CacheWrapper extends Cache { * @return int */ public function getNumericStorageId() { - return $this->cache->getNumericStorageId(); + return $this->getCache()->getNumericStorageId(); } /** diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index bdb6ac466e..7a60295017 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -23,6 +23,8 @@ */ namespace OC\Share20; +use OC\Files\Cache\Cache; +use OC\Files\Cache\CacheEntry; use OCP\Files\File; use OCP\Files\Folder; use OCP\Share\IShareProvider; @@ -571,7 +573,7 @@ class DefaultShareProvider implements IShareProvider { $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) )); - + $cursor = $qb->execute(); $data = $cursor->fetch(); $cursor->closeCursor(); @@ -656,7 +658,11 @@ class DefaultShareProvider implements IShareProvider { if ($shareType === \OCP\Share::SHARE_TYPE_USER) { //Get shares directly with this user $qb = $this->dbConn->getQueryBuilder(); - $qb->select('s.*', 'f.fileid', 'f.path') + $qb->select('s.*', + 'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash', + 'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime', + 'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum' + ) ->selectAlias('st.id', 'storage_string_id') ->from('share', 's') ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid')) @@ -709,7 +715,11 @@ class DefaultShareProvider implements IShareProvider { } $qb = $this->dbConn->getQueryBuilder(); - $qb->select('s.*', 'f.fileid', 'f.path') + $qb->select('s.*', + 'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash', + 'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime', + 'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum' + ) ->selectAlias('st.id', 'storage_string_id') ->from('share', 's') ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid')) @@ -798,7 +808,7 @@ class DefaultShareProvider implements IShareProvider { return $share; } - + /** * Create a share object from an database row * @@ -838,6 +848,15 @@ class DefaultShareProvider implements IShareProvider { $share->setExpirationDate($expiration); } + if (isset($data['f_permissions'])) { + $entryData = $data; + $entryData['permissions'] = $entryData['f_permissions']; + $entryData['parent'] = $entryData['f_parent'];; + $share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData, + $entryData['storage_string_id'], + \OC::$server->getMimeTypeLoader())); + } + $share->setProviderId($this->identifier()); return $share; diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php index e3e8482f4e..2e7e6d0ca2 100644 --- a/lib/private/Share20/Share.php +++ b/lib/private/Share20/Share.php @@ -22,6 +22,7 @@ */ namespace OC\Share20; +use OCP\Files\Cache\ICacheEntry; use OCP\Files\File; use OCP\Files\IRootFolder; use OCP\Files\Node; @@ -72,6 +73,9 @@ class Share implements \OCP\Share\IShare { /** @var IUserManager */ private $userManager; + /** @var ICacheEntry|null */ + private $nodeCacheEntry; + public function __construct(IRootFolder $rootFolder, IUserManager $userManager) { $this->rootFolder = $rootFolder; $this->userManager = $userManager; @@ -418,4 +422,18 @@ class Share implements \OCP\Share\IShare { public function getMailSend() { return $this->mailSend; } + + /** + * @inheritdoc + */ + public function setNodeCacheEntry(ICacheEntry $entry) { + $this->nodeCacheEntry = $entry; + } + + /** + * @inheritdoc + */ + public function getNodeCacheEntry() { + return $this->nodeCacheEntry; + } } diff --git a/lib/public/Share/IShare.php b/lib/public/Share/IShare.php index 206b0e286a..5b552b51c3 100644 --- a/lib/public/Share/IShare.php +++ b/lib/public/Share/IShare.php @@ -22,6 +22,7 @@ namespace OCP\Share; +use OCP\Files\Cache\ICacheEntry; use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\Node; @@ -324,4 +325,20 @@ interface IShare { * @since 9.0.0 */ public function getMailSend(); + + /** + * Set the cache entry for the shared node + * + * @param ICacheEntry $entry + * @since 11.0.0 + */ + public function setNodeCacheEntry(ICacheEntry $entry); + + /** + * Get the cache entry for the shared node + * + * @return null|ICacheEntry + * @since 11.0.0 + */ + public function getNodeCacheEntry(); }