| Total Complexity | 47 |
| Total Lines | 400 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like UserMountCache often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use UserMountCache, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 48 | class UserMountCache implements IUserMountCache { |
||
| 49 | /** |
||
| 50 | * @var IDBConnection |
||
| 51 | */ |
||
| 52 | private $connection; |
||
| 53 | |||
| 54 | /** |
||
| 55 | * @var IUserManager |
||
| 56 | */ |
||
| 57 | private $userManager; |
||
| 58 | |||
| 59 | /** |
||
| 60 | * Cached mount info. |
||
| 61 | * Map of $userId to ICachedMountInfo. |
||
| 62 | * |
||
| 63 | * @var ICache |
||
| 64 | **/ |
||
| 65 | private $mountsForUsers; |
||
| 66 | |||
| 67 | /** |
||
| 68 | * @var ILogger |
||
| 69 | */ |
||
| 70 | private $logger; |
||
| 71 | |||
| 72 | /** |
||
| 73 | * @var ICache |
||
| 74 | */ |
||
| 75 | private $cacheInfoCache; |
||
| 76 | |||
| 77 | /** |
||
| 78 | * UserMountCache constructor. |
||
| 79 | * |
||
| 80 | * @param IDBConnection $connection |
||
| 81 | * @param IUserManager $userManager |
||
| 82 | * @param ILogger $logger |
||
| 83 | */ |
||
| 84 | public function __construct(IDBConnection $connection, IUserManager $userManager, ILogger $logger) { |
||
| 90 | } |
||
| 91 | |||
| 92 | public function registerMounts(IUser $user, array $mounts) { |
||
| 146 | } |
||
| 147 | } |
||
| 148 | |||
| 149 | /** |
||
| 150 | * @param ICachedMountInfo[] $newMounts |
||
| 151 | * @param ICachedMountInfo[] $cachedMounts |
||
| 152 | * @return ICachedMountInfo[] |
||
| 153 | */ |
||
| 154 | private function findChangedMounts(array $newMounts, array $cachedMounts) { |
||
| 175 | } |
||
| 176 | |||
| 177 | private function addToCache(ICachedMountInfo $mount) { |
||
| 178 | if ($mount->getStorageId() !== -1) { |
||
| 179 | $this->connection->insertIfNotExist('*PREFIX*mounts', [ |
||
| 180 | 'storage_id' => $mount->getStorageId(), |
||
| 181 | 'root_id' => $mount->getRootId(), |
||
| 182 | 'user_id' => $mount->getUser()->getUID(), |
||
| 183 | 'mount_point' => $mount->getMountPoint(), |
||
| 184 | 'mount_id' => $mount->getMountId(), |
||
| 185 | 'mount_provider_class' => $mount->getMountProvider(), |
||
| 186 | ], ['root_id', 'user_id']); |
||
| 187 | } else { |
||
| 188 | // in some cases this is legitimate, like orphaned shares |
||
| 189 | $this->logger->debug('Could not get storage info for mount at ' . $mount->getMountPoint()); |
||
| 190 | } |
||
| 191 | } |
||
| 192 | |||
| 193 | private function updateCachedMount(ICachedMountInfo $mount) { |
||
| 194 | $builder = $this->connection->getQueryBuilder(); |
||
| 195 | |||
| 196 | $query = $builder->update('mounts') |
||
| 197 | ->set('storage_id', $builder->createNamedParameter($mount->getStorageId())) |
||
| 198 | ->set('mount_point', $builder->createNamedParameter($mount->getMountPoint())) |
||
| 199 | ->set('mount_id', $builder->createNamedParameter($mount->getMountId(), IQueryBuilder::PARAM_INT)) |
||
| 200 | ->set('mount_provider_class', $builder->createNamedParameter($mount->getMountProvider())) |
||
| 201 | ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID()))) |
||
| 202 | ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT))); |
||
| 203 | |||
| 204 | $query->execute(); |
||
| 205 | } |
||
| 206 | |||
| 207 | private function removeFromCache(ICachedMountInfo $mount) { |
||
| 214 | } |
||
| 215 | |||
| 216 | private function dbRowToMountInfo(array $row) { |
||
| 217 | $user = $this->userManager->get($row['user_id']); |
||
| 218 | if (is_null($user)) { |
||
| 219 | return null; |
||
| 220 | } |
||
| 221 | $mount_id = $row['mount_id']; |
||
| 222 | if (!is_null($mount_id)) { |
||
| 223 | $mount_id = (int)$mount_id; |
||
| 224 | } |
||
| 225 | return new CachedMountInfo( |
||
| 226 | $user, |
||
| 227 | (int)$row['storage_id'], |
||
| 228 | (int)$row['root_id'], |
||
| 229 | $row['mount_point'], |
||
| 230 | $row['mount_provider_class'] ?? '', |
||
| 231 | $mount_id, |
||
| 232 | isset($row['path']) ? $row['path'] : '', |
||
| 233 | ); |
||
| 234 | } |
||
| 235 | |||
| 236 | /** |
||
| 237 | * @param IUser $user |
||
| 238 | * @return ICachedMountInfo[] |
||
| 239 | */ |
||
| 240 | public function getMountsForUser(IUser $user) { |
||
| 241 | if (!isset($this->mountsForUsers[$user->getUID()])) { |
||
| 242 | $builder = $this->connection->getQueryBuilder(); |
||
| 243 | $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class') |
||
| 244 | ->from('mounts', 'm') |
||
| 245 | ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid')) |
||
| 246 | ->where($builder->expr()->eq('user_id', $builder->createPositionalParameter($user->getUID()))); |
||
| 247 | |||
| 248 | $result = $query->execute(); |
||
| 249 | $rows = $result->fetchAll(); |
||
| 250 | $result->closeCursor(); |
||
| 251 | |||
| 252 | $this->mountsForUsers[$user->getUID()] = array_filter(array_map([$this, 'dbRowToMountInfo'], $rows)); |
||
| 253 | } |
||
| 254 | return $this->mountsForUsers[$user->getUID()]; |
||
| 255 | } |
||
| 256 | |||
| 257 | /** |
||
| 258 | * @param int $numericStorageId |
||
| 259 | * @param string|null $user limit the results to a single user |
||
| 260 | * @return CachedMountInfo[] |
||
| 261 | */ |
||
| 262 | public function getMountsForStorageId($numericStorageId, $user = null) { |
||
| 263 | $builder = $this->connection->getQueryBuilder(); |
||
| 264 | $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class') |
||
| 265 | ->from('mounts', 'm') |
||
| 266 | ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid')) |
||
| 267 | ->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, IQueryBuilder::PARAM_INT))); |
||
| 268 | |||
| 269 | if ($user) { |
||
| 270 | $query->andWhere($builder->expr()->eq('user_id', $builder->createPositionalParameter($user))); |
||
| 271 | } |
||
| 272 | |||
| 273 | $result = $query->execute(); |
||
| 274 | $rows = $result->fetchAll(); |
||
| 275 | $result->closeCursor(); |
||
| 276 | |||
| 277 | return array_filter(array_map([$this, 'dbRowToMountInfo'], $rows)); |
||
| 278 | } |
||
| 279 | |||
| 280 | /** |
||
| 281 | * @param int $rootFileId |
||
| 282 | * @return CachedMountInfo[] |
||
| 283 | */ |
||
| 284 | public function getMountsForRootId($rootFileId) { |
||
| 285 | $builder = $this->connection->getQueryBuilder(); |
||
| 286 | $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class') |
||
| 287 | ->from('mounts', 'm') |
||
| 288 | ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid')) |
||
| 289 | ->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, IQueryBuilder::PARAM_INT))); |
||
| 290 | |||
| 291 | $result = $query->execute(); |
||
| 292 | $rows = $result->fetchAll(); |
||
| 293 | $result->closeCursor(); |
||
| 294 | |||
| 295 | return array_filter(array_map([$this, 'dbRowToMountInfo'], $rows)); |
||
| 296 | } |
||
| 297 | |||
| 298 | /** |
||
| 299 | * @param $fileId |
||
| 300 | * @return array{int, string, int} |
||
|
|
|||
| 301 | * @throws \OCP\Files\NotFoundException |
||
| 302 | */ |
||
| 303 | private function getCacheInfoFromFileId($fileId): array { |
||
| 325 | } |
||
| 326 | |||
| 327 | /** |
||
| 328 | * @param int $fileId |
||
| 329 | * @param string|null $user optionally restrict the results to a single user |
||
| 330 | * @return ICachedMountFileInfo[] |
||
| 331 | * @since 9.0.0 |
||
| 332 | */ |
||
| 333 | public function getMountsForFileId($fileId, $user = null) { |
||
| 334 | try { |
||
| 335 | [$storageId, $internalPath] = $this->getCacheInfoFromFileId($fileId); |
||
| 336 | } catch (NotFoundException $e) { |
||
| 337 | return []; |
||
| 338 | } |
||
| 339 | $builder = $this->connection->getQueryBuilder(); |
||
| 340 | $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path', 'mount_provider_class') |
||
| 341 | ->from('mounts', 'm') |
||
| 342 | ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid')) |
||
| 343 | ->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($storageId, IQueryBuilder::PARAM_INT))); |
||
| 344 | |||
| 345 | if ($user) { |
||
| 346 | $query->andWhere($builder->expr()->eq('user_id', $builder->createPositionalParameter($user))); |
||
| 347 | } |
||
| 348 | |||
| 349 | $result = $query->execute(); |
||
| 350 | $rows = $result->fetchAll(); |
||
| 351 | $result->closeCursor(); |
||
| 352 | // filter mounts that are from the same storage but a different directory |
||
| 353 | $filteredMounts = array_filter($rows, function (array $row) use ($internalPath, $fileId) { |
||
| 354 | if ($fileId === (int)$row['root_id']) { |
||
| 355 | return true; |
||
| 356 | } |
||
| 357 | $internalMountPath = $row['path'] ?? ''; |
||
| 358 | |||
| 359 | return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/'; |
||
| 360 | }); |
||
| 361 | |||
| 362 | $filteredMounts = array_filter(array_map([$this, 'dbRowToMountInfo'], $filteredMounts)); |
||
| 363 | return array_map(function (ICachedMountInfo $mount) use ($internalPath) { |
||
| 364 | return new CachedMountFileInfo( |
||
| 365 | $mount->getUser(), |
||
| 366 | $mount->getStorageId(), |
||
| 367 | $mount->getRootId(), |
||
| 368 | $mount->getMountPoint(), |
||
| 369 | $mount->getMountId(), |
||
| 370 | $mount->getMountProvider(), |
||
| 371 | $mount->getRootInternalPath(), |
||
| 372 | $internalPath |
||
| 373 | ); |
||
| 374 | }, $filteredMounts); |
||
| 375 | } |
||
| 376 | |||
| 377 | /** |
||
| 378 | * Remove all cached mounts for a user |
||
| 379 | * |
||
| 380 | * @param IUser $user |
||
| 381 | */ |
||
| 382 | public function removeUserMounts(IUser $user) { |
||
| 383 | $builder = $this->connection->getQueryBuilder(); |
||
| 384 | |||
| 385 | $query = $builder->delete('mounts') |
||
| 386 | ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($user->getUID()))); |
||
| 387 | $query->execute(); |
||
| 388 | } |
||
| 389 | |||
| 390 | public function removeUserStorageMount($storageId, $userId) { |
||
| 397 | } |
||
| 398 | |||
| 399 | public function remoteStorageMounts($storageId) { |
||
| 400 | $builder = $this->connection->getQueryBuilder(); |
||
| 405 | } |
||
| 406 | |||
| 407 | /** |
||
| 408 | * @param array $users |
||
| 409 | * @return array |
||
| 410 | */ |
||
| 411 | public function getUsedSpaceForUsers(array $users) { |
||
| 412 | $builder = $this->connection->getQueryBuilder(); |
||
| 413 | |||
| 414 | $slash = $builder->createNamedParameter('/'); |
||
| 415 | |||
| 416 | $mountPoint = $builder->func()->concat( |
||
| 417 | $builder->func()->concat($slash, 'user_id'), |
||
| 418 | $slash |
||
| 419 | ); |
||
| 420 | |||
| 421 | $userIds = array_map(function (IUser $user) { |
||
| 422 | return $user->getUID(); |
||
| 423 | }, $users); |
||
| 424 | |||
| 425 | $query = $builder->select('m.user_id', 'f.size') |
||
| 426 | ->from('mounts', 'm') |
||
| 427 | ->innerJoin('m', 'filecache', 'f', |
||
| 428 | $builder->expr()->andX( |
||
| 429 | $builder->expr()->eq('m.storage_id', 'f.storage'), |
||
| 430 | $builder->expr()->eq('f.path_hash', $builder->createNamedParameter(md5('files'))) |
||
| 431 | )) |
||
| 432 | ->where($builder->expr()->eq('m.mount_point', $mountPoint)) |
||
| 433 | ->andWhere($builder->expr()->in('m.user_id', $builder->createNamedParameter($userIds, IQueryBuilder::PARAM_STR_ARRAY))); |
||
| 434 | |||
| 435 | $result = $query->execute(); |
||
| 436 | |||
| 437 | $results = []; |
||
| 438 | while ($row = $result->fetch()) { |
||
| 439 | $results[$row['user_id']] = $row['size']; |
||
| 440 | } |
||
| 441 | $result->closeCursor(); |
||
| 442 | return $results; |
||
| 443 | } |
||
| 444 | |||
| 445 | public function clear(): void { |
||
| 448 | } |
||
| 449 | } |
||
| 450 |