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