aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Files/Config/UserMountCache.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Files/Config/UserMountCache.php')
-rw-r--r--lib/private/Files/Config/UserMountCache.php119
1 files changed, 55 insertions, 64 deletions
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index b5b07d8f29e..3e53a67a044 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -1,30 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Dariusz Olszewski <starypatyk@users.noreply.github.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Vincent Petry <vincent@nextcloud.com>
- *
- * @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/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Files\Config;
@@ -32,6 +11,10 @@ use OC\User\LazyUser;
use OCP\Cache\CappedMemoryCache;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Diagnostics\IEventLogger;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\Config\Event\UserMountAddedEvent;
+use OCP\Files\Config\Event\UserMountRemovedEvent;
+use OCP\Files\Config\Event\UserMountUpdatedEvent;
use OCP\Files\Config\ICachedMountFileInfo;
use OCP\Files\Config\ICachedMountInfo;
use OCP\Files\Config\IUserMountCache;
@@ -45,8 +28,6 @@ use Psr\Log\LoggerInterface;
* Cache mounts points per user in the cache so we can easily look them up
*/
class UserMountCache implements IUserMountCache {
- private IDBConnection $connection;
- private IUserManager $userManager;
/**
* Cached mount info.
@@ -58,24 +39,19 @@ class UserMountCache implements IUserMountCache {
* @var CappedMemoryCache<string>
**/
private CappedMemoryCache $internalPathCache;
- private LoggerInterface $logger;
/** @var CappedMemoryCache<array> */
private CappedMemoryCache $cacheInfoCache;
- private IEventLogger $eventLogger;
/**
* UserMountCache constructor.
*/
public function __construct(
- IDBConnection $connection,
- IUserManager $userManager,
- LoggerInterface $logger,
- IEventLogger $eventLogger
+ private IDBConnection $connection,
+ private IUserManager $userManager,
+ private LoggerInterface $logger,
+ private IEventLogger $eventLogger,
+ private IEventDispatcher $eventDispatcher,
) {
- $this->connection = $connection;
- $this->userManager = $userManager;
- $this->logger = $logger;
- $this->eventLogger = $eventLogger;
$this->cacheInfoCache = new CappedMemoryCache();
$this->internalPathCache = new CappedMemoryCache();
$this->mountsForUsers = new CappedMemoryCache();
@@ -127,24 +103,39 @@ class UserMountCache implements IUserMountCache {
$userUID = $user->getUID();
try {
foreach ($addedMounts as $mount) {
+ $this->logger->debug("Adding mount '{$mount->getKey()}' for user '$userUID'", ['app' => 'files', 'mount_provider' => $mount->getMountProvider()]);
$this->addToCache($mount);
/** @psalm-suppress InvalidArgument */
$this->mountsForUsers[$userUID][$mount->getKey()] = $mount;
}
foreach ($removedMounts as $mount) {
+ $this->logger->debug("Removing mount '{$mount->getKey()}' for user '$userUID'", ['app' => 'files', 'mount_provider' => $mount->getMountProvider()]);
$this->removeFromCache($mount);
unset($this->mountsForUsers[$userUID][$mount->getKey()]);
}
- foreach ($changedMounts as $mount) {
- $this->updateCachedMount($mount);
+ foreach ($changedMounts as $mountPair) {
+ $newMount = $mountPair[1];
+ $this->logger->debug("Updating mount '{$newMount->getKey()}' for user '$userUID'", ['app' => 'files', 'mount_provider' => $newMount->getMountProvider()]);
+ $this->updateCachedMount($newMount);
/** @psalm-suppress InvalidArgument */
- $this->mountsForUsers[$userUID][$mount->getKey()] = $mount;
+ $this->mountsForUsers[$userUID][$newMount->getKey()] = $newMount;
}
$this->connection->commit();
} catch (\Throwable $e) {
$this->connection->rollBack();
throw $e;
}
+
+ // Only fire events after all mounts have already been adjusted in the database.
+ foreach ($addedMounts as $mount) {
+ $this->eventDispatcher->dispatchTyped(new UserMountAddedEvent($mount));
+ }
+ foreach ($removedMounts as $mount) {
+ $this->eventDispatcher->dispatchTyped(new UserMountRemovedEvent($mount));
+ }
+ foreach ($changedMounts as $mountPair) {
+ $this->eventDispatcher->dispatchTyped(new UserMountUpdatedEvent($mountPair[0], $mountPair[1]));
+ }
}
$this->eventLogger->end('fs:setup:user:register');
}
@@ -152,19 +143,19 @@ class UserMountCache implements IUserMountCache {
/**
* @param array<string, ICachedMountInfo> $newMounts
* @param array<string, ICachedMountInfo> $cachedMounts
- * @return ICachedMountInfo[]
+ * @return list<list{0: ICachedMountInfo, 1: ICachedMountInfo}> Pairs of old and new mounts
*/
- private function findChangedMounts(array $newMounts, array $cachedMounts) {
+ private function findChangedMounts(array $newMounts, array $cachedMounts): array {
$changed = [];
foreach ($cachedMounts as $key => $cachedMount) {
if (isset($newMounts[$key])) {
$newMount = $newMounts[$key];
if (
- $newMount->getStorageId() !== $cachedMount->getStorageId() ||
- $newMount->getMountId() !== $cachedMount->getMountId() ||
- $newMount->getMountProvider() !== $cachedMount->getMountProvider()
+ $newMount->getStorageId() !== $cachedMount->getStorageId()
+ || $newMount->getMountId() !== $cachedMount->getMountId()
+ || $newMount->getMountProvider() !== $cachedMount->getMountProvider()
) {
- $changed[] = $newMount;
+ $changed[] = [$cachedMount, $newMount];
}
}
}
@@ -198,7 +189,7 @@ class UserMountCache implements IUserMountCache {
->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)));
- $query->execute();
+ $query->executeStatement();
}
private function removeFromCache(ICachedMountInfo $mount) {
@@ -208,7 +199,7 @@ class UserMountCache implements IUserMountCache {
->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)))
->andWhere($builder->expr()->eq('mount_point', $builder->createNamedParameter($mount->getMountPoint())));
- $query->execute();
+ $query->executeStatement();
}
/**
@@ -258,9 +249,9 @@ class UserMountCache implements IUserMountCache {
$builder = $this->connection->getQueryBuilder();
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'mount_provider_class')
->from('mounts', 'm')
- ->where($builder->expr()->eq('user_id', $builder->createPositionalParameter($userUID)));
+ ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($userUID)));
- $result = $query->execute();
+ $result = $query->executeQuery();
$rows = $result->fetchAll();
$result->closeCursor();
@@ -285,7 +276,7 @@ class UserMountCache implements IUserMountCache {
$builder = $this->connection->getQueryBuilder();
$query = $builder->select('path')
->from('filecache')
- ->where($builder->expr()->eq('fileid', $builder->createPositionalParameter($info->getRootId())));
+ ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($info->getRootId())));
return $query->executeQuery()->fetchOne() ?: '';
}
@@ -299,13 +290,13 @@ class UserMountCache implements IUserMountCache {
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class')
->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
- ->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, IQueryBuilder::PARAM_INT)));
+ ->where($builder->expr()->eq('storage_id', $builder->createNamedParameter($numericStorageId, IQueryBuilder::PARAM_INT)));
if ($user) {
- $query->andWhere($builder->expr()->eq('user_id', $builder->createPositionalParameter($user)));
+ $query->andWhere($builder->expr()->eq('user_id', $builder->createNamedParameter($user)));
}
- $result = $query->execute();
+ $result = $query->executeQuery();
$rows = $result->fetchAll();
$result->closeCursor();
@@ -321,9 +312,9 @@ class UserMountCache implements IUserMountCache {
$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class')
->from('mounts', 'm')
->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
- ->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, IQueryBuilder::PARAM_INT)));
+ ->where($builder->expr()->eq('root_id', $builder->createNamedParameter($rootFileId, IQueryBuilder::PARAM_INT)));
- $result = $query->execute();
+ $result = $query->executeQuery();
$rows = $result->fetchAll();
$result->closeCursor();
@@ -342,7 +333,7 @@ class UserMountCache implements IUserMountCache {
->from('filecache')
->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
- $result = $query->execute();
+ $result = $query->executeQuery();
$row = $result->fetch();
$result->closeCursor();
@@ -383,9 +374,9 @@ class UserMountCache implements IUserMountCache {
return $internalMountPath === '' || str_starts_with($internalPath, $internalMountPath . '/');
});
- $filteredMounts = array_filter($filteredMounts, function (ICachedMountInfo $mount) {
+ $filteredMounts = array_values(array_filter($filteredMounts, function (ICachedMountInfo $mount) {
return $this->userManager->userExists($mount->getUser()->getUID());
- });
+ }));
return array_map(function (ICachedMountInfo $mount) use ($internalPath) {
return new CachedMountFileInfo(
@@ -411,7 +402,7 @@ class UserMountCache implements IUserMountCache {
$query = $builder->delete('mounts')
->where($builder->expr()->eq('user_id', $builder->createNamedParameter($user->getUID())));
- $query->execute();
+ $query->executeStatement();
}
public function removeUserStorageMount($storageId, $userId) {
@@ -420,7 +411,7 @@ class UserMountCache implements IUserMountCache {
$query = $builder->delete('mounts')
->where($builder->expr()->eq('user_id', $builder->createNamedParameter($userId)))
->andWhere($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
- $query->execute();
+ $query->executeStatement();
}
public function remoteStorageMounts($storageId) {
@@ -428,7 +419,7 @@ class UserMountCache implements IUserMountCache {
$query = $builder->delete('mounts')
->where($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
- $query->execute();
+ $query->executeStatement();
}
/**
@@ -459,7 +450,7 @@ class UserMountCache implements IUserMountCache {
->where($builder->expr()->eq('m.mount_point', $mountPoint))
->andWhere($builder->expr()->in('m.user_id', $builder->createNamedParameter($userIds, IQueryBuilder::PARAM_STR_ARRAY)));
- $result = $query->execute();
+ $result = $query->executeQuery();
$results = [];
while ($row = $result->fetch()) {
@@ -498,7 +489,7 @@ class UserMountCache implements IUserMountCache {
}
}
- throw new NotFoundException("No cached mount for path " . $path);
+ throw new NotFoundException('No cached mount for path ' . $path);
}
public function getMountsInPath(IUser $user, string $path): array {