Completed
Pull Request — master (#6220)
by Robin
13:47
created
lib/private/Files/Config/UserMountCache.php 3 patches
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -24,7 +24,6 @@
 block discarded – undo
24 24
 
25 25
 namespace OC\Files\Config;
26 26
 
27
-use OC\DB\QueryBuilder\Literal;
28 27
 use OCA\Files_Sharing\SharedMount;
29 28
 use OCP\DB\QueryBuilder\IQueryBuilder;
30 29
 use OCP\Files\Config\ICachedMountFileInfo;
Please login to merge, or discard this patch.
Indentation   +342 added lines, -342 removed lines patch added patch discarded remove patch
@@ -43,346 +43,346 @@
 block discarded – undo
43 43
  * Cache mounts points per user in the cache so we can easilly look them up
44 44
  */
45 45
 class UserMountCache implements IUserMountCache {
46
-	/**
47
-	 * @var IDBConnection
48
-	 */
49
-	private $connection;
50
-
51
-	/**
52
-	 * @var IUserManager
53
-	 */
54
-	private $userManager;
55
-
56
-	/**
57
-	 * Cached mount info.
58
-	 * Map of $userId to ICachedMountInfo.
59
-	 *
60
-	 * @var ICache
61
-	 **/
62
-	private $mountsForUsers;
63
-
64
-	/**
65
-	 * @var ILogger
66
-	 */
67
-	private $logger;
68
-
69
-	/**
70
-	 * @var ICache
71
-	 */
72
-	private $cacheInfoCache;
73
-
74
-	/**
75
-	 * UserMountCache constructor.
76
-	 *
77
-	 * @param IDBConnection $connection
78
-	 * @param IUserManager $userManager
79
-	 * @param ILogger $logger
80
-	 */
81
-	public function __construct(IDBConnection $connection, IUserManager $userManager, ILogger $logger) {
82
-		$this->connection = $connection;
83
-		$this->userManager = $userManager;
84
-		$this->logger = $logger;
85
-		$this->cacheInfoCache = new CappedMemoryCache();
86
-		$this->mountsForUsers = new CappedMemoryCache();
87
-	}
88
-
89
-	public function registerMounts(IUser $user, array $mounts) {
90
-		// filter out non-proper storages coming from unit tests
91
-		$mounts = array_filter($mounts, function (IMountPoint $mount) {
92
-			return $mount instanceof SharedMount || $mount->getStorage() && $mount->getStorage()->getCache();
93
-		});
94
-		/** @var ICachedMountInfo[] $newMounts */
95
-		$newMounts = array_map(function (IMountPoint $mount) use ($user) {
96
-			// filter out any storages which aren't scanned yet since we aren't interested in files from those storages (yet)
97
-			if ($mount->getStorageRootId() === -1) {
98
-				return null;
99
-			} else {
100
-				return new LazyStorageMountInfo($user, $mount);
101
-			}
102
-		}, $mounts);
103
-		$newMounts = array_values(array_filter($newMounts));
104
-
105
-		$cachedMounts = $this->getMountsForUser($user);
106
-		$mountDiff = function (ICachedMountInfo $mount1, ICachedMountInfo $mount2) {
107
-			// since we are only looking for mounts for a specific user comparing on root id is enough
108
-			return $mount1->getRootId() - $mount2->getRootId();
109
-		};
110
-
111
-		/** @var ICachedMountInfo[] $addedMounts */
112
-		$addedMounts = array_udiff($newMounts, $cachedMounts, $mountDiff);
113
-		/** @var ICachedMountInfo[] $removedMounts */
114
-		$removedMounts = array_udiff($cachedMounts, $newMounts, $mountDiff);
115
-
116
-		$changedMounts = $this->findChangedMounts($newMounts, $cachedMounts);
117
-
118
-		foreach ($addedMounts as $mount) {
119
-			$this->addToCache($mount);
120
-			$this->mountsForUsers[$user->getUID()][] = $mount;
121
-		}
122
-		foreach ($removedMounts as $mount) {
123
-			$this->removeFromCache($mount);
124
-			$index = array_search($mount, $this->mountsForUsers[$user->getUID()]);
125
-			unset($this->mountsForUsers[$user->getUID()][$index]);
126
-		}
127
-		foreach ($changedMounts as $mount) {
128
-			$this->updateCachedMount($mount);
129
-		}
130
-	}
131
-
132
-	/**
133
-	 * @param ICachedMountInfo[] $newMounts
134
-	 * @param ICachedMountInfo[] $cachedMounts
135
-	 * @return ICachedMountInfo[]
136
-	 */
137
-	private function findChangedMounts(array $newMounts, array $cachedMounts) {
138
-		$changed = [];
139
-		foreach ($newMounts as $newMount) {
140
-			foreach ($cachedMounts as $cachedMount) {
141
-				if (
142
-					$newMount->getRootId() === $cachedMount->getRootId() &&
143
-					(
144
-						$newMount->getMountPoint() !== $cachedMount->getMountPoint() ||
145
-						$newMount->getStorageId() !== $cachedMount->getStorageId() ||
146
-						$newMount->getMountId() !== $cachedMount->getMountId()
147
-					)
148
-				) {
149
-					$changed[] = $newMount;
150
-				}
151
-			}
152
-		}
153
-		return $changed;
154
-	}
155
-
156
-	private function addToCache(ICachedMountInfo $mount) {
157
-		if ($mount->getStorageId() !== -1) {
158
-			$this->connection->insertIfNotExist('*PREFIX*mounts', [
159
-				'storage_id' => $mount->getStorageId(),
160
-				'root_id' => $mount->getRootId(),
161
-				'user_id' => $mount->getUser()->getUID(),
162
-				'mount_point' => $mount->getMountPoint(),
163
-				'mount_id' => $mount->getMountId()
164
-			], ['root_id', 'user_id']);
165
-		} else {
166
-			// in some cases this is legitimate, like orphaned shares
167
-			$this->logger->debug('Could not get storage info for mount at ' . $mount->getMountPoint());
168
-		}
169
-	}
170
-
171
-	private function updateCachedMount(ICachedMountInfo $mount) {
172
-		$builder = $this->connection->getQueryBuilder();
173
-
174
-		$query = $builder->update('mounts')
175
-			->set('storage_id', $builder->createNamedParameter($mount->getStorageId()))
176
-			->set('mount_point', $builder->createNamedParameter($mount->getMountPoint()))
177
-			->set('mount_id', $builder->createNamedParameter($mount->getMountId(), IQueryBuilder::PARAM_INT))
178
-			->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
179
-			->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)));
180
-
181
-		$query->execute();
182
-	}
183
-
184
-	private function removeFromCache(ICachedMountInfo $mount) {
185
-		$builder = $this->connection->getQueryBuilder();
186
-
187
-		$query = $builder->delete('mounts')
188
-			->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
189
-			->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)));
190
-		$query->execute();
191
-	}
192
-
193
-	private function dbRowToMountInfo(array $row) {
194
-		$user = $this->userManager->get($row['user_id']);
195
-		if (is_null($user)) {
196
-			return null;
197
-		}
198
-		return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point'], $row['mount_id'], isset($row['path']) ? $row['path'] : '');
199
-	}
200
-
201
-	/**
202
-	 * @param IUser $user
203
-	 * @return ICachedMountInfo[]
204
-	 */
205
-	public function getMountsForUser(IUser $user) {
206
-		if (!isset($this->mountsForUsers[$user->getUID()])) {
207
-			$builder = $this->connection->getQueryBuilder();
208
-			$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
209
-				->from('mounts', 'm')
210
-				->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
211
-				->where($builder->expr()->eq('user_id', $builder->createPositionalParameter($user->getUID())));
212
-
213
-			$rows = $query->execute()->fetchAll();
214
-
215
-			$this->mountsForUsers[$user->getUID()] = array_filter(array_map([$this, 'dbRowToMountInfo'], $rows));
216
-		}
217
-		return $this->mountsForUsers[$user->getUID()];
218
-	}
219
-
220
-	/**
221
-	 * @param int $numericStorageId
222
-	 * @param string|null $user limit the results to a single user
223
-	 * @return CachedMountInfo[]
224
-	 */
225
-	public function getMountsForStorageId($numericStorageId, $user = null) {
226
-		$builder = $this->connection->getQueryBuilder();
227
-		$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
228
-			->from('mounts', 'm')
229
-			->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
230
-			->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, IQueryBuilder::PARAM_INT)));
231
-
232
-		if ($user) {
233
-			$query->andWhere($builder->expr()->eq('user_id', $builder->createPositionalParameter($user)));
234
-		}
235
-
236
-		$rows = $query->execute()->fetchAll();
237
-
238
-		return array_filter(array_map([$this, 'dbRowToMountInfo'], $rows));
239
-	}
240
-
241
-	/**
242
-	 * @param int $rootFileId
243
-	 * @return CachedMountInfo[]
244
-	 */
245
-	public function getMountsForRootId($rootFileId) {
246
-		$builder = $this->connection->getQueryBuilder();
247
-		$query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
248
-			->from('mounts', 'm')
249
-			->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
250
-			->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, IQueryBuilder::PARAM_INT)));
251
-
252
-		$rows = $query->execute()->fetchAll();
253
-
254
-		return array_filter(array_map([$this, 'dbRowToMountInfo'], $rows));
255
-	}
256
-
257
-	/**
258
-	 * @param $fileId
259
-	 * @return array
260
-	 * @throws \OCP\Files\NotFoundException
261
-	 */
262
-	private function getCacheInfoFromFileId($fileId) {
263
-		if (!isset($this->cacheInfoCache[$fileId])) {
264
-			$builder = $this->connection->getQueryBuilder();
265
-			$query = $builder->select('storage', 'path', 'mimetype')
266
-				->from('filecache')
267
-				->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
268
-
269
-			$row = $query->execute()->fetch();
270
-			if (is_array($row)) {
271
-				$this->cacheInfoCache[$fileId] = [
272
-					(int)$row['storage'],
273
-					$row['path'],
274
-					(int)$row['mimetype']
275
-				];
276
-			} else {
277
-				throw new NotFoundException('File with id "' . $fileId . '" not found');
278
-			}
279
-		}
280
-		return $this->cacheInfoCache[$fileId];
281
-	}
282
-
283
-	/**
284
-	 * @param int $fileId
285
-	 * @param string|null $user optionally restrict the results to a single user
286
-	 * @return ICachedMountFileInfo[]
287
-	 * @since 9.0.0
288
-	 */
289
-	public function getMountsForFileId($fileId, $user = null) {
290
-		try {
291
-			list($storageId, $internalPath) = $this->getCacheInfoFromFileId($fileId);
292
-		} catch (NotFoundException $e) {
293
-			return [];
294
-		}
295
-		$mountsForStorage = $this->getMountsForStorageId($storageId, $user);
296
-
297
-		// filter mounts that are from the same storage but a different directory
298
-		$filteredMounts = array_filter($mountsForStorage, function (ICachedMountInfo $mount) use ($internalPath, $fileId) {
299
-			if ($fileId === $mount->getRootId()) {
300
-				return true;
301
-			}
302
-			$internalMountPath = $mount->getRootInternalPath();
303
-
304
-			return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/';
305
-		});
306
-
307
-		return array_map(function (ICachedMountInfo $mount) use ($internalPath) {
308
-			return new CachedMountFileInfo(
309
-				$mount->getUser(),
310
-				$mount->getStorageId(),
311
-				$mount->getRootId(),
312
-				$mount->getMountPoint(),
313
-				$mount->getMountId(),
314
-				$mount->getRootInternalPath(),
315
-				$internalPath
316
-			);
317
-		}, $filteredMounts);
318
-	}
319
-
320
-	/**
321
-	 * Remove all cached mounts for a user
322
-	 *
323
-	 * @param IUser $user
324
-	 */
325
-	public function removeUserMounts(IUser $user) {
326
-		$builder = $this->connection->getQueryBuilder();
327
-
328
-		$query = $builder->delete('mounts')
329
-			->where($builder->expr()->eq('user_id', $builder->createNamedParameter($user->getUID())));
330
-		$query->execute();
331
-	}
332
-
333
-	public function removeUserStorageMount($storageId, $userId) {
334
-		$builder = $this->connection->getQueryBuilder();
335
-
336
-		$query = $builder->delete('mounts')
337
-			->where($builder->expr()->eq('user_id', $builder->createNamedParameter($userId)))
338
-			->andWhere($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
339
-		$query->execute();
340
-	}
341
-
342
-	public function remoteStorageMounts($storageId) {
343
-		$builder = $this->connection->getQueryBuilder();
344
-
345
-		$query = $builder->delete('mounts')
346
-			->where($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
347
-		$query->execute();
348
-	}
349
-
350
-	/**
351
-	 * @param array $users
352
-	 * @return array
353
-	 * @suppress SqlInjectionChecker
354
-	 */
355
-	public function getUsedSpaceForUsers(array $users) {
356
-		$builder = $this->connection->getQueryBuilder();
357
-
358
-		$slash = $builder->createNamedParameter('/');
359
-
360
-		$mountPoint = $builder->func()->concat(
361
-			$builder->func()->concat($slash, 'user_id'),
362
-			$slash
363
-		);
364
-
365
-		$userIds = array_map(function (IUser $user) {
366
-			return $user->getUID();
367
-		}, $users);
368
-
369
-		$query = $builder->select('m.user_id', 'f.size')
370
-			->from('mounts', 'm')
371
-			->innerJoin('m', 'filecache', 'f',
372
-				$builder->expr()->andX(
373
-					$builder->expr()->eq('m.storage_id', 'f.storage'),
374
-					$builder->expr()->eq('f.path', $builder->createNamedParameter('files'))
375
-				))
376
-			->where($builder->expr()->eq('m.mount_point', $mountPoint))
377
-			->andWhere($builder->expr()->in('m.user_id', $builder->createNamedParameter($userIds, IQueryBuilder::PARAM_STR_ARRAY)));
378
-
379
-		$result = $query->execute();
380
-
381
-		$results = [];
382
-		while ($row = $result->fetch()) {
383
-			$results[$row['user_id']] = $row['size'];
384
-		}
385
-		$result->closeCursor();
386
-		return $results;
387
-	}
46
+    /**
47
+     * @var IDBConnection
48
+     */
49
+    private $connection;
50
+
51
+    /**
52
+     * @var IUserManager
53
+     */
54
+    private $userManager;
55
+
56
+    /**
57
+     * Cached mount info.
58
+     * Map of $userId to ICachedMountInfo.
59
+     *
60
+     * @var ICache
61
+     **/
62
+    private $mountsForUsers;
63
+
64
+    /**
65
+     * @var ILogger
66
+     */
67
+    private $logger;
68
+
69
+    /**
70
+     * @var ICache
71
+     */
72
+    private $cacheInfoCache;
73
+
74
+    /**
75
+     * UserMountCache constructor.
76
+     *
77
+     * @param IDBConnection $connection
78
+     * @param IUserManager $userManager
79
+     * @param ILogger $logger
80
+     */
81
+    public function __construct(IDBConnection $connection, IUserManager $userManager, ILogger $logger) {
82
+        $this->connection = $connection;
83
+        $this->userManager = $userManager;
84
+        $this->logger = $logger;
85
+        $this->cacheInfoCache = new CappedMemoryCache();
86
+        $this->mountsForUsers = new CappedMemoryCache();
87
+    }
88
+
89
+    public function registerMounts(IUser $user, array $mounts) {
90
+        // filter out non-proper storages coming from unit tests
91
+        $mounts = array_filter($mounts, function (IMountPoint $mount) {
92
+            return $mount instanceof SharedMount || $mount->getStorage() && $mount->getStorage()->getCache();
93
+        });
94
+        /** @var ICachedMountInfo[] $newMounts */
95
+        $newMounts = array_map(function (IMountPoint $mount) use ($user) {
96
+            // filter out any storages which aren't scanned yet since we aren't interested in files from those storages (yet)
97
+            if ($mount->getStorageRootId() === -1) {
98
+                return null;
99
+            } else {
100
+                return new LazyStorageMountInfo($user, $mount);
101
+            }
102
+        }, $mounts);
103
+        $newMounts = array_values(array_filter($newMounts));
104
+
105
+        $cachedMounts = $this->getMountsForUser($user);
106
+        $mountDiff = function (ICachedMountInfo $mount1, ICachedMountInfo $mount2) {
107
+            // since we are only looking for mounts for a specific user comparing on root id is enough
108
+            return $mount1->getRootId() - $mount2->getRootId();
109
+        };
110
+
111
+        /** @var ICachedMountInfo[] $addedMounts */
112
+        $addedMounts = array_udiff($newMounts, $cachedMounts, $mountDiff);
113
+        /** @var ICachedMountInfo[] $removedMounts */
114
+        $removedMounts = array_udiff($cachedMounts, $newMounts, $mountDiff);
115
+
116
+        $changedMounts = $this->findChangedMounts($newMounts, $cachedMounts);
117
+
118
+        foreach ($addedMounts as $mount) {
119
+            $this->addToCache($mount);
120
+            $this->mountsForUsers[$user->getUID()][] = $mount;
121
+        }
122
+        foreach ($removedMounts as $mount) {
123
+            $this->removeFromCache($mount);
124
+            $index = array_search($mount, $this->mountsForUsers[$user->getUID()]);
125
+            unset($this->mountsForUsers[$user->getUID()][$index]);
126
+        }
127
+        foreach ($changedMounts as $mount) {
128
+            $this->updateCachedMount($mount);
129
+        }
130
+    }
131
+
132
+    /**
133
+     * @param ICachedMountInfo[] $newMounts
134
+     * @param ICachedMountInfo[] $cachedMounts
135
+     * @return ICachedMountInfo[]
136
+     */
137
+    private function findChangedMounts(array $newMounts, array $cachedMounts) {
138
+        $changed = [];
139
+        foreach ($newMounts as $newMount) {
140
+            foreach ($cachedMounts as $cachedMount) {
141
+                if (
142
+                    $newMount->getRootId() === $cachedMount->getRootId() &&
143
+                    (
144
+                        $newMount->getMountPoint() !== $cachedMount->getMountPoint() ||
145
+                        $newMount->getStorageId() !== $cachedMount->getStorageId() ||
146
+                        $newMount->getMountId() !== $cachedMount->getMountId()
147
+                    )
148
+                ) {
149
+                    $changed[] = $newMount;
150
+                }
151
+            }
152
+        }
153
+        return $changed;
154
+    }
155
+
156
+    private function addToCache(ICachedMountInfo $mount) {
157
+        if ($mount->getStorageId() !== -1) {
158
+            $this->connection->insertIfNotExist('*PREFIX*mounts', [
159
+                'storage_id' => $mount->getStorageId(),
160
+                'root_id' => $mount->getRootId(),
161
+                'user_id' => $mount->getUser()->getUID(),
162
+                'mount_point' => $mount->getMountPoint(),
163
+                'mount_id' => $mount->getMountId()
164
+            ], ['root_id', 'user_id']);
165
+        } else {
166
+            // in some cases this is legitimate, like orphaned shares
167
+            $this->logger->debug('Could not get storage info for mount at ' . $mount->getMountPoint());
168
+        }
169
+    }
170
+
171
+    private function updateCachedMount(ICachedMountInfo $mount) {
172
+        $builder = $this->connection->getQueryBuilder();
173
+
174
+        $query = $builder->update('mounts')
175
+            ->set('storage_id', $builder->createNamedParameter($mount->getStorageId()))
176
+            ->set('mount_point', $builder->createNamedParameter($mount->getMountPoint()))
177
+            ->set('mount_id', $builder->createNamedParameter($mount->getMountId(), IQueryBuilder::PARAM_INT))
178
+            ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
179
+            ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)));
180
+
181
+        $query->execute();
182
+    }
183
+
184
+    private function removeFromCache(ICachedMountInfo $mount) {
185
+        $builder = $this->connection->getQueryBuilder();
186
+
187
+        $query = $builder->delete('mounts')
188
+            ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
189
+            ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)));
190
+        $query->execute();
191
+    }
192
+
193
+    private function dbRowToMountInfo(array $row) {
194
+        $user = $this->userManager->get($row['user_id']);
195
+        if (is_null($user)) {
196
+            return null;
197
+        }
198
+        return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point'], $row['mount_id'], isset($row['path']) ? $row['path'] : '');
199
+    }
200
+
201
+    /**
202
+     * @param IUser $user
203
+     * @return ICachedMountInfo[]
204
+     */
205
+    public function getMountsForUser(IUser $user) {
206
+        if (!isset($this->mountsForUsers[$user->getUID()])) {
207
+            $builder = $this->connection->getQueryBuilder();
208
+            $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
209
+                ->from('mounts', 'm')
210
+                ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
211
+                ->where($builder->expr()->eq('user_id', $builder->createPositionalParameter($user->getUID())));
212
+
213
+            $rows = $query->execute()->fetchAll();
214
+
215
+            $this->mountsForUsers[$user->getUID()] = array_filter(array_map([$this, 'dbRowToMountInfo'], $rows));
216
+        }
217
+        return $this->mountsForUsers[$user->getUID()];
218
+    }
219
+
220
+    /**
221
+     * @param int $numericStorageId
222
+     * @param string|null $user limit the results to a single user
223
+     * @return CachedMountInfo[]
224
+     */
225
+    public function getMountsForStorageId($numericStorageId, $user = null) {
226
+        $builder = $this->connection->getQueryBuilder();
227
+        $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
228
+            ->from('mounts', 'm')
229
+            ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
230
+            ->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, IQueryBuilder::PARAM_INT)));
231
+
232
+        if ($user) {
233
+            $query->andWhere($builder->expr()->eq('user_id', $builder->createPositionalParameter($user)));
234
+        }
235
+
236
+        $rows = $query->execute()->fetchAll();
237
+
238
+        return array_filter(array_map([$this, 'dbRowToMountInfo'], $rows));
239
+    }
240
+
241
+    /**
242
+     * @param int $rootFileId
243
+     * @return CachedMountInfo[]
244
+     */
245
+    public function getMountsForRootId($rootFileId) {
246
+        $builder = $this->connection->getQueryBuilder();
247
+        $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point', 'mount_id', 'f.path')
248
+            ->from('mounts', 'm')
249
+            ->innerJoin('m', 'filecache', 'f', $builder->expr()->eq('m.root_id', 'f.fileid'))
250
+            ->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, IQueryBuilder::PARAM_INT)));
251
+
252
+        $rows = $query->execute()->fetchAll();
253
+
254
+        return array_filter(array_map([$this, 'dbRowToMountInfo'], $rows));
255
+    }
256
+
257
+    /**
258
+     * @param $fileId
259
+     * @return array
260
+     * @throws \OCP\Files\NotFoundException
261
+     */
262
+    private function getCacheInfoFromFileId($fileId) {
263
+        if (!isset($this->cacheInfoCache[$fileId])) {
264
+            $builder = $this->connection->getQueryBuilder();
265
+            $query = $builder->select('storage', 'path', 'mimetype')
266
+                ->from('filecache')
267
+                ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
268
+
269
+            $row = $query->execute()->fetch();
270
+            if (is_array($row)) {
271
+                $this->cacheInfoCache[$fileId] = [
272
+                    (int)$row['storage'],
273
+                    $row['path'],
274
+                    (int)$row['mimetype']
275
+                ];
276
+            } else {
277
+                throw new NotFoundException('File with id "' . $fileId . '" not found');
278
+            }
279
+        }
280
+        return $this->cacheInfoCache[$fileId];
281
+    }
282
+
283
+    /**
284
+     * @param int $fileId
285
+     * @param string|null $user optionally restrict the results to a single user
286
+     * @return ICachedMountFileInfo[]
287
+     * @since 9.0.0
288
+     */
289
+    public function getMountsForFileId($fileId, $user = null) {
290
+        try {
291
+            list($storageId, $internalPath) = $this->getCacheInfoFromFileId($fileId);
292
+        } catch (NotFoundException $e) {
293
+            return [];
294
+        }
295
+        $mountsForStorage = $this->getMountsForStorageId($storageId, $user);
296
+
297
+        // filter mounts that are from the same storage but a different directory
298
+        $filteredMounts = array_filter($mountsForStorage, function (ICachedMountInfo $mount) use ($internalPath, $fileId) {
299
+            if ($fileId === $mount->getRootId()) {
300
+                return true;
301
+            }
302
+            $internalMountPath = $mount->getRootInternalPath();
303
+
304
+            return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/';
305
+        });
306
+
307
+        return array_map(function (ICachedMountInfo $mount) use ($internalPath) {
308
+            return new CachedMountFileInfo(
309
+                $mount->getUser(),
310
+                $mount->getStorageId(),
311
+                $mount->getRootId(),
312
+                $mount->getMountPoint(),
313
+                $mount->getMountId(),
314
+                $mount->getRootInternalPath(),
315
+                $internalPath
316
+            );
317
+        }, $filteredMounts);
318
+    }
319
+
320
+    /**
321
+     * Remove all cached mounts for a user
322
+     *
323
+     * @param IUser $user
324
+     */
325
+    public function removeUserMounts(IUser $user) {
326
+        $builder = $this->connection->getQueryBuilder();
327
+
328
+        $query = $builder->delete('mounts')
329
+            ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($user->getUID())));
330
+        $query->execute();
331
+    }
332
+
333
+    public function removeUserStorageMount($storageId, $userId) {
334
+        $builder = $this->connection->getQueryBuilder();
335
+
336
+        $query = $builder->delete('mounts')
337
+            ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($userId)))
338
+            ->andWhere($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
339
+        $query->execute();
340
+    }
341
+
342
+    public function remoteStorageMounts($storageId) {
343
+        $builder = $this->connection->getQueryBuilder();
344
+
345
+        $query = $builder->delete('mounts')
346
+            ->where($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
347
+        $query->execute();
348
+    }
349
+
350
+    /**
351
+     * @param array $users
352
+     * @return array
353
+     * @suppress SqlInjectionChecker
354
+     */
355
+    public function getUsedSpaceForUsers(array $users) {
356
+        $builder = $this->connection->getQueryBuilder();
357
+
358
+        $slash = $builder->createNamedParameter('/');
359
+
360
+        $mountPoint = $builder->func()->concat(
361
+            $builder->func()->concat($slash, 'user_id'),
362
+            $slash
363
+        );
364
+
365
+        $userIds = array_map(function (IUser $user) {
366
+            return $user->getUID();
367
+        }, $users);
368
+
369
+        $query = $builder->select('m.user_id', 'f.size')
370
+            ->from('mounts', 'm')
371
+            ->innerJoin('m', 'filecache', 'f',
372
+                $builder->expr()->andX(
373
+                    $builder->expr()->eq('m.storage_id', 'f.storage'),
374
+                    $builder->expr()->eq('f.path', $builder->createNamedParameter('files'))
375
+                ))
376
+            ->where($builder->expr()->eq('m.mount_point', $mountPoint))
377
+            ->andWhere($builder->expr()->in('m.user_id', $builder->createNamedParameter($userIds, IQueryBuilder::PARAM_STR_ARRAY)));
378
+
379
+        $result = $query->execute();
380
+
381
+        $results = [];
382
+        while ($row = $result->fetch()) {
383
+            $results[$row['user_id']] = $row['size'];
384
+        }
385
+        $result->closeCursor();
386
+        return $results;
387
+    }
388 388
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -88,11 +88,11 @@  discard block
 block discarded – undo
88 88
 
89 89
 	public function registerMounts(IUser $user, array $mounts) {
90 90
 		// filter out non-proper storages coming from unit tests
91
-		$mounts = array_filter($mounts, function (IMountPoint $mount) {
91
+		$mounts = array_filter($mounts, function(IMountPoint $mount) {
92 92
 			return $mount instanceof SharedMount || $mount->getStorage() && $mount->getStorage()->getCache();
93 93
 		});
94 94
 		/** @var ICachedMountInfo[] $newMounts */
95
-		$newMounts = array_map(function (IMountPoint $mount) use ($user) {
95
+		$newMounts = array_map(function(IMountPoint $mount) use ($user) {
96 96
 			// filter out any storages which aren't scanned yet since we aren't interested in files from those storages (yet)
97 97
 			if ($mount->getStorageRootId() === -1) {
98 98
 				return null;
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
 		$newMounts = array_values(array_filter($newMounts));
104 104
 
105 105
 		$cachedMounts = $this->getMountsForUser($user);
106
-		$mountDiff = function (ICachedMountInfo $mount1, ICachedMountInfo $mount2) {
106
+		$mountDiff = function(ICachedMountInfo $mount1, ICachedMountInfo $mount2) {
107 107
 			// since we are only looking for mounts for a specific user comparing on root id is enough
108 108
 			return $mount1->getRootId() - $mount2->getRootId();
109 109
 		};
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
 			], ['root_id', 'user_id']);
165 165
 		} else {
166 166
 			// in some cases this is legitimate, like orphaned shares
167
-			$this->logger->debug('Could not get storage info for mount at ' . $mount->getMountPoint());
167
+			$this->logger->debug('Could not get storage info for mount at '.$mount->getMountPoint());
168 168
 		}
169 169
 	}
170 170
 
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
 		if (is_null($user)) {
196 196
 			return null;
197 197
 		}
198
-		return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point'], $row['mount_id'], isset($row['path']) ? $row['path'] : '');
198
+		return new CachedMountInfo($user, (int) $row['storage_id'], (int) $row['root_id'], $row['mount_point'], $row['mount_id'], isset($row['path']) ? $row['path'] : '');
199 199
 	}
200 200
 
201 201
 	/**
@@ -269,12 +269,12 @@  discard block
 block discarded – undo
269 269
 			$row = $query->execute()->fetch();
270 270
 			if (is_array($row)) {
271 271
 				$this->cacheInfoCache[$fileId] = [
272
-					(int)$row['storage'],
272
+					(int) $row['storage'],
273 273
 					$row['path'],
274
-					(int)$row['mimetype']
274
+					(int) $row['mimetype']
275 275
 				];
276 276
 			} else {
277
-				throw new NotFoundException('File with id "' . $fileId . '" not found');
277
+				throw new NotFoundException('File with id "'.$fileId.'" not found');
278 278
 			}
279 279
 		}
280 280
 		return $this->cacheInfoCache[$fileId];
@@ -295,16 +295,16 @@  discard block
 block discarded – undo
295 295
 		$mountsForStorage = $this->getMountsForStorageId($storageId, $user);
296 296
 
297 297
 		// filter mounts that are from the same storage but a different directory
298
-		$filteredMounts = array_filter($mountsForStorage, function (ICachedMountInfo $mount) use ($internalPath, $fileId) {
298
+		$filteredMounts = array_filter($mountsForStorage, function(ICachedMountInfo $mount) use ($internalPath, $fileId) {
299 299
 			if ($fileId === $mount->getRootId()) {
300 300
 				return true;
301 301
 			}
302 302
 			$internalMountPath = $mount->getRootInternalPath();
303 303
 
304
-			return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/';
304
+			return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath.'/';
305 305
 		});
306 306
 
307
-		return array_map(function (ICachedMountInfo $mount) use ($internalPath) {
307
+		return array_map(function(ICachedMountInfo $mount) use ($internalPath) {
308 308
 			return new CachedMountFileInfo(
309 309
 				$mount->getUser(),
310 310
 				$mount->getStorageId(),
@@ -362,7 +362,7 @@  discard block
 block discarded – undo
362 362
 			$slash
363 363
 		);
364 364
 
365
-		$userIds = array_map(function (IUser $user) {
365
+		$userIds = array_map(function(IUser $user) {
366 366
 			return $user->getUID();
367 367
 		}, $users);
368 368
 
Please login to merge, or discard this patch.
lib/public/Files/Config/IUserMountCache.php 1 patch
Indentation   +77 added lines, -77 removed lines patch added patch discarded remove patch
@@ -31,89 +31,89 @@
 block discarded – undo
31 31
  * @since 9.0.0
32 32
  */
33 33
 interface IUserMountCache {
34
-	/**
35
-	 * Register mounts for a user to the cache
36
-	 *
37
-	 * @param IUser $user
38
-	 * @param IMountPoint[] $mounts
39
-	 * @since 9.0.0
40
-	 */
41
-	public function registerMounts(IUser $user, array $mounts);
34
+    /**
35
+     * Register mounts for a user to the cache
36
+     *
37
+     * @param IUser $user
38
+     * @param IMountPoint[] $mounts
39
+     * @since 9.0.0
40
+     */
41
+    public function registerMounts(IUser $user, array $mounts);
42 42
 
43
-	/**
44
-	 * Get all cached mounts for a user
45
-	 *
46
-	 * @param IUser $user
47
-	 * @return ICachedMountInfo[]
48
-	 * @since 9.0.0
49
-	 */
50
-	public function getMountsForUser(IUser $user);
43
+    /**
44
+     * Get all cached mounts for a user
45
+     *
46
+     * @param IUser $user
47
+     * @return ICachedMountInfo[]
48
+     * @since 9.0.0
49
+     */
50
+    public function getMountsForUser(IUser $user);
51 51
 
52
-	/**
53
-	 * Get all cached mounts by storage
54
-	 *
55
-	 * @param int $numericStorageId
56
-	 * @param string|null $user limit the results to a single user @since 12.0.0
57
-	 * @return ICachedMountInfo[]
58
-	 * @since 9.0.0
59
-	 */
60
-	public function getMountsForStorageId($numericStorageId, $user = null);
52
+    /**
53
+     * Get all cached mounts by storage
54
+     *
55
+     * @param int $numericStorageId
56
+     * @param string|null $user limit the results to a single user @since 12.0.0
57
+     * @return ICachedMountInfo[]
58
+     * @since 9.0.0
59
+     */
60
+    public function getMountsForStorageId($numericStorageId, $user = null);
61 61
 
62
-	/**
63
-	 * Get all cached mounts by root
64
-	 *
65
-	 * @param int $rootFileId
66
-	 * @return ICachedMountInfo[]
67
-	 * @since 9.0.0
68
-	 */
69
-	public function getMountsForRootId($rootFileId);
62
+    /**
63
+     * Get all cached mounts by root
64
+     *
65
+     * @param int $rootFileId
66
+     * @return ICachedMountInfo[]
67
+     * @since 9.0.0
68
+     */
69
+    public function getMountsForRootId($rootFileId);
70 70
 
71
-	/**
72
-	 * Get all cached mounts that contain a file
73
-	 *
74
-	 * @param int $fileId
75
-	 * @param string|null $user optionally restrict the results to a single user @since 12.0.0
76
-	 * @return ICachedMountFileInfo[]
77
-	 * @since 9.0.0
78
-	 */
79
-	public function getMountsForFileId($fileId, $user = null);
71
+    /**
72
+     * Get all cached mounts that contain a file
73
+     *
74
+     * @param int $fileId
75
+     * @param string|null $user optionally restrict the results to a single user @since 12.0.0
76
+     * @return ICachedMountFileInfo[]
77
+     * @since 9.0.0
78
+     */
79
+    public function getMountsForFileId($fileId, $user = null);
80 80
 
81
-	/**
82
-	 * Remove all cached mounts for a user
83
-	 *
84
-	 * @param IUser $user
85
-	 * @since 9.0.0
86
-	 */
87
-	public function removeUserMounts(IUser $user);
81
+    /**
82
+     * Remove all cached mounts for a user
83
+     *
84
+     * @param IUser $user
85
+     * @since 9.0.0
86
+     */
87
+    public function removeUserMounts(IUser $user);
88 88
 
89
-	/**
90
-	 * Remove all mounts for a user and storage
91
-	 *
92
-	 * @param $storageId
93
-	 * @param string $userId
94
-	 * @return mixed
95
-	 * @since 9.0.0
96
-	 */
97
-	public function removeUserStorageMount($storageId, $userId);
89
+    /**
90
+     * Remove all mounts for a user and storage
91
+     *
92
+     * @param $storageId
93
+     * @param string $userId
94
+     * @return mixed
95
+     * @since 9.0.0
96
+     */
97
+    public function removeUserStorageMount($storageId, $userId);
98 98
 
99
-	/**
100
-	 * Remove all cached mounts for a storage
101
-	 *
102
-	 * @param $storageId
103
-	 * @return mixed
104
-	 * @since 9.0.0
105
-	 */
106
-	public function remoteStorageMounts($storageId);
99
+    /**
100
+     * Remove all cached mounts for a storage
101
+     *
102
+     * @param $storageId
103
+     * @return mixed
104
+     * @since 9.0.0
105
+     */
106
+    public function remoteStorageMounts($storageId);
107 107
 
108
-	/**
109
-	 * Get the used space for users
110
-	 *
111
-	 * Note that this only includes the space in their home directory,
112
-	 * not any incoming shares or external storages.
113
-	 *
114
-	 * @param IUser[] $users
115
-	 * @return int[] [$userId => $userSpace]
116
-	 * @since 13.0.0
117
-	 */
118
-	public function getUsedSpaceForUsers(array $users);
108
+    /**
109
+     * Get the used space for users
110
+     *
111
+     * Note that this only includes the space in their home directory,
112
+     * not any incoming shares or external storages.
113
+     *
114
+     * @param IUser[] $users
115
+     * @return int[] [$userId => $userSpace]
116
+     * @since 13.0.0
117
+     */
118
+    public function getUsedSpaceForUsers(array $users);
119 119
 }
Please login to merge, or discard this patch.
lib/private/Files/Config/CachedMountFileInfo.php 2 patches
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -26,23 +26,23 @@
 block discarded – undo
26 26
 use OCP\IUser;
27 27
 
28 28
 class CachedMountFileInfo extends CachedMountInfo implements ICachedMountFileInfo {
29
-	/** @var string */
30
-	private $internalPath;
29
+    /** @var string */
30
+    private $internalPath;
31 31
 
32
-	public function __construct(IUser $user, $storageId, $rootId, $mountPoint, $mountId = null, $rootInternalPath = '', $internalPath) {
33
-		parent::__construct($user, $storageId, $rootId, $mountPoint, $mountId, $rootInternalPath);
34
-		$this->internalPath = $internalPath;
35
-	}
32
+    public function __construct(IUser $user, $storageId, $rootId, $mountPoint, $mountId = null, $rootInternalPath = '', $internalPath) {
33
+        parent::__construct($user, $storageId, $rootId, $mountPoint, $mountId, $rootInternalPath);
34
+        $this->internalPath = $internalPath;
35
+    }
36 36
 
37
-	public function getInternalPath() {
38
-		if ($this->getRootInternalPath()) {
39
-			return substr($this->internalPath, strlen($this->getRootInternalPath()) + 1);
40
-		} else {
41
-			return $this->internalPath;
42
-		}
43
-	}
37
+    public function getInternalPath() {
38
+        if ($this->getRootInternalPath()) {
39
+            return substr($this->internalPath, strlen($this->getRootInternalPath()) + 1);
40
+        } else {
41
+            return $this->internalPath;
42
+        }
43
+    }
44 44
 
45
-	public function getPath() {
46
-		return $this->getMountPoint() . $this->getInternalPath();
47
-	}
45
+    public function getPath() {
46
+        return $this->getMountPoint() . $this->getInternalPath();
47
+    }
48 48
 }
49 49
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -43,6 +43,6 @@
 block discarded – undo
43 43
 	}
44 44
 
45 45
 	public function getPath() {
46
-		return $this->getMountPoint() . $this->getInternalPath();
46
+		return $this->getMountPoint().$this->getInternalPath();
47 47
 	}
48 48
 }
49 49
\ No newline at end of file
Please login to merge, or discard this patch.
lib/public/Files/Config/ICachedMountFieInfo.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -27,17 +27,17 @@
 block discarded – undo
27 27
  * @since 13.0.0
28 28
  */
29 29
 interface ICachedMountFileInfo extends ICachedMountInfo {
30
-	/**
31
-	 * Return the path for the file within the cached mount
32
-	 *
33
-	 * @return string
34
-	 * @since 13.0.0
35
-	 */
36
-	public function getInternalPath();
30
+    /**
31
+     * Return the path for the file within the cached mount
32
+     *
33
+     * @return string
34
+     * @since 13.0.0
35
+     */
36
+    public function getInternalPath();
37 37
 
38
-	/**
39
-	 * @return string
40
-	 * @since 13.0.0
41
-	 */
42
-	public function getPath();
38
+    /**
39
+     * @return string
40
+     * @since 13.0.0
41
+     */
42
+    public function getPath();
43 43
 }
Please login to merge, or discard this patch.