Passed
Push — master ( 00c138...6b1186 )
by Roeland
08:38
created
lib/private/Files/Cache/Cache.php 2 patches
Indentation   +825 added lines, -825 removed lines patch added patch discarded remove patch
@@ -61,840 +61,840 @@
 block discarded – undo
61 61
  * - ChangePropagator: updates the mtime and etags of parent folders whenever a change to the cache is made to the cache by the updater
62 62
  */
63 63
 class Cache implements ICache {
64
-	use MoveFromCacheTrait {
65
-		MoveFromCacheTrait::moveFromCache as moveFromCacheFallback;
66
-	}
67
-
68
-	/**
69
-	 * @var array partial data for the cache
70
-	 */
71
-	protected $partial = array();
72
-
73
-	/**
74
-	 * @var string
75
-	 */
76
-	protected $storageId;
77
-
78
-	private $storage;
79
-
80
-	/**
81
-	 * @var Storage $storageCache
82
-	 */
83
-	protected $storageCache;
84
-
85
-	/** @var IMimeTypeLoader */
86
-	protected $mimetypeLoader;
87
-
88
-	/**
89
-	 * @var IDBConnection
90
-	 */
91
-	protected $connection;
92
-
93
-	protected $eventDispatcher;
94
-
95
-	/** @var QuerySearchHelper */
96
-	protected $querySearchHelper;
97
-
98
-	/**
99
-	 * @param IStorage $storage
100
-	 */
101
-	public function __construct(IStorage $storage) {
102
-		$this->storageId = $storage->getId();
103
-		$this->storage = $storage;
104
-		if (strlen($this->storageId) > 64) {
105
-			$this->storageId = md5($this->storageId);
106
-		}
107
-
108
-		$this->storageCache = new Storage($storage);
109
-		$this->mimetypeLoader = \OC::$server->getMimeTypeLoader();
110
-		$this->connection = \OC::$server->getDatabaseConnection();
111
-		$this->eventDispatcher = \OC::$server->getEventDispatcher();
112
-		$this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
113
-	}
114
-
115
-	/**
116
-	 * Get the numeric storage id for this cache's storage
117
-	 *
118
-	 * @return int
119
-	 */
120
-	public function getNumericStorageId() {
121
-		return $this->storageCache->getNumericId();
122
-	}
123
-
124
-	/**
125
-	 * get the stored metadata of a file or folder
126
-	 *
127
-	 * @param string | int $file either the path of a file or folder or the file id for a file or folder
128
-	 * @return ICacheEntry|false the cache entry as array of false if the file is not found in the cache
129
-	 */
130
-	public function get($file) {
131
-		if (is_string($file) or $file == '') {
132
-			// normalize file
133
-			$file = $this->normalize($file);
134
-
135
-			$where = 'WHERE `storage` = ? AND `path_hash` = ?';
136
-			$params = array($this->getNumericStorageId(), md5($file));
137
-		} else { //file id
138
-			$where = 'WHERE `fileid` = ?';
139
-			$params = array($file);
140
-		}
141
-		$sql = 'SELECT `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
64
+    use MoveFromCacheTrait {
65
+        MoveFromCacheTrait::moveFromCache as moveFromCacheFallback;
66
+    }
67
+
68
+    /**
69
+     * @var array partial data for the cache
70
+     */
71
+    protected $partial = array();
72
+
73
+    /**
74
+     * @var string
75
+     */
76
+    protected $storageId;
77
+
78
+    private $storage;
79
+
80
+    /**
81
+     * @var Storage $storageCache
82
+     */
83
+    protected $storageCache;
84
+
85
+    /** @var IMimeTypeLoader */
86
+    protected $mimetypeLoader;
87
+
88
+    /**
89
+     * @var IDBConnection
90
+     */
91
+    protected $connection;
92
+
93
+    protected $eventDispatcher;
94
+
95
+    /** @var QuerySearchHelper */
96
+    protected $querySearchHelper;
97
+
98
+    /**
99
+     * @param IStorage $storage
100
+     */
101
+    public function __construct(IStorage $storage) {
102
+        $this->storageId = $storage->getId();
103
+        $this->storage = $storage;
104
+        if (strlen($this->storageId) > 64) {
105
+            $this->storageId = md5($this->storageId);
106
+        }
107
+
108
+        $this->storageCache = new Storage($storage);
109
+        $this->mimetypeLoader = \OC::$server->getMimeTypeLoader();
110
+        $this->connection = \OC::$server->getDatabaseConnection();
111
+        $this->eventDispatcher = \OC::$server->getEventDispatcher();
112
+        $this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
113
+    }
114
+
115
+    /**
116
+     * Get the numeric storage id for this cache's storage
117
+     *
118
+     * @return int
119
+     */
120
+    public function getNumericStorageId() {
121
+        return $this->storageCache->getNumericId();
122
+    }
123
+
124
+    /**
125
+     * get the stored metadata of a file or folder
126
+     *
127
+     * @param string | int $file either the path of a file or folder or the file id for a file or folder
128
+     * @return ICacheEntry|false the cache entry as array of false if the file is not found in the cache
129
+     */
130
+    public function get($file) {
131
+        if (is_string($file) or $file == '') {
132
+            // normalize file
133
+            $file = $this->normalize($file);
134
+
135
+            $where = 'WHERE `storage` = ? AND `path_hash` = ?';
136
+            $params = array($this->getNumericStorageId(), md5($file));
137
+        } else { //file id
138
+            $where = 'WHERE `fileid` = ?';
139
+            $params = array($file);
140
+        }
141
+        $sql = 'SELECT `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
142 142
 					   `storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum`
143 143
 				FROM `*PREFIX*filecache` ' . $where;
144
-		$result = $this->connection->executeQuery($sql, $params);
145
-		$data = $result->fetch();
146
-
147
-		//FIXME hide this HACK in the next database layer, or just use doctrine and get rid of MDB2 and PDO
148
-		//PDO returns false, MDB2 returns null, oracle always uses MDB2, so convert null to false
149
-		if ($data === null) {
150
-			$data = false;
151
-		}
152
-
153
-		//merge partial data
154
-		if (!$data and is_string($file)) {
155
-			if (isset($this->partial[$file])) {
156
-				$data = $this->partial[$file];
157
-			}
158
-			return $data;
159
-		} else if (!$data) {
160
-			return $data;
161
-		} else {
162
-			return self::cacheEntryFromData($data, $this->mimetypeLoader);
163
-		}
164
-	}
165
-
166
-	/**
167
-	 * Create a CacheEntry from database row
168
-	 *
169
-	 * @param array $data
170
-	 * @param IMimeTypeLoader $mimetypeLoader
171
-	 * @return CacheEntry
172
-	 */
173
-	public static function cacheEntryFromData($data, IMimeTypeLoader $mimetypeLoader) {
174
-		//fix types
175
-		$data['fileid'] = (int)$data['fileid'];
176
-		$data['parent'] = (int)$data['parent'];
177
-		$data['size'] = 0 + $data['size'];
178
-		$data['mtime'] = (int)$data['mtime'];
179
-		$data['storage_mtime'] = (int)$data['storage_mtime'];
180
-		$data['encryptedVersion'] = (int)$data['encrypted'];
181
-		$data['encrypted'] = (bool)$data['encrypted'];
182
-		$data['storage_id'] = $data['storage'];
183
-		$data['storage'] = (int)$data['storage'];
184
-		$data['mimetype'] = $mimetypeLoader->getMimetypeById($data['mimetype']);
185
-		$data['mimepart'] = $mimetypeLoader->getMimetypeById($data['mimepart']);
186
-		if ($data['storage_mtime'] == 0) {
187
-			$data['storage_mtime'] = $data['mtime'];
188
-		}
189
-		$data['permissions'] = (int)$data['permissions'];
190
-		return new CacheEntry($data);
191
-	}
192
-
193
-	/**
194
-	 * get the metadata of all files stored in $folder
195
-	 *
196
-	 * @param string $folder
197
-	 * @return ICacheEntry[]
198
-	 */
199
-	public function getFolderContents($folder) {
200
-		$fileId = $this->getId($folder);
201
-		return $this->getFolderContentsById($fileId);
202
-	}
203
-
204
-	/**
205
-	 * get the metadata of all files stored in $folder
206
-	 *
207
-	 * @param int $fileId the file id of the folder
208
-	 * @return ICacheEntry[]
209
-	 */
210
-	public function getFolderContentsById($fileId) {
211
-		if ($fileId > -1) {
212
-			$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
144
+        $result = $this->connection->executeQuery($sql, $params);
145
+        $data = $result->fetch();
146
+
147
+        //FIXME hide this HACK in the next database layer, or just use doctrine and get rid of MDB2 and PDO
148
+        //PDO returns false, MDB2 returns null, oracle always uses MDB2, so convert null to false
149
+        if ($data === null) {
150
+            $data = false;
151
+        }
152
+
153
+        //merge partial data
154
+        if (!$data and is_string($file)) {
155
+            if (isset($this->partial[$file])) {
156
+                $data = $this->partial[$file];
157
+            }
158
+            return $data;
159
+        } else if (!$data) {
160
+            return $data;
161
+        } else {
162
+            return self::cacheEntryFromData($data, $this->mimetypeLoader);
163
+        }
164
+    }
165
+
166
+    /**
167
+     * Create a CacheEntry from database row
168
+     *
169
+     * @param array $data
170
+     * @param IMimeTypeLoader $mimetypeLoader
171
+     * @return CacheEntry
172
+     */
173
+    public static function cacheEntryFromData($data, IMimeTypeLoader $mimetypeLoader) {
174
+        //fix types
175
+        $data['fileid'] = (int)$data['fileid'];
176
+        $data['parent'] = (int)$data['parent'];
177
+        $data['size'] = 0 + $data['size'];
178
+        $data['mtime'] = (int)$data['mtime'];
179
+        $data['storage_mtime'] = (int)$data['storage_mtime'];
180
+        $data['encryptedVersion'] = (int)$data['encrypted'];
181
+        $data['encrypted'] = (bool)$data['encrypted'];
182
+        $data['storage_id'] = $data['storage'];
183
+        $data['storage'] = (int)$data['storage'];
184
+        $data['mimetype'] = $mimetypeLoader->getMimetypeById($data['mimetype']);
185
+        $data['mimepart'] = $mimetypeLoader->getMimetypeById($data['mimepart']);
186
+        if ($data['storage_mtime'] == 0) {
187
+            $data['storage_mtime'] = $data['mtime'];
188
+        }
189
+        $data['permissions'] = (int)$data['permissions'];
190
+        return new CacheEntry($data);
191
+    }
192
+
193
+    /**
194
+     * get the metadata of all files stored in $folder
195
+     *
196
+     * @param string $folder
197
+     * @return ICacheEntry[]
198
+     */
199
+    public function getFolderContents($folder) {
200
+        $fileId = $this->getId($folder);
201
+        return $this->getFolderContentsById($fileId);
202
+    }
203
+
204
+    /**
205
+     * get the metadata of all files stored in $folder
206
+     *
207
+     * @param int $fileId the file id of the folder
208
+     * @return ICacheEntry[]
209
+     */
210
+    public function getFolderContentsById($fileId) {
211
+        if ($fileId > -1) {
212
+            $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
213 213
 						   `storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum`
214 214
 					FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC';
215
-			$result = $this->connection->executeQuery($sql, [$fileId]);
216
-			$files = $result->fetchAll();
217
-			return array_map(function (array $data) {
218
-				return self::cacheEntryFromData($data, $this->mimetypeLoader);
219
-			}, $files);
220
-		}
221
-		return [];
222
-	}
223
-
224
-	/**
225
-	 * insert or update meta data for a file or folder
226
-	 *
227
-	 * @param string $file
228
-	 * @param array $data
229
-	 *
230
-	 * @return int file id
231
-	 * @throws \RuntimeException
232
-	 */
233
-	public function put($file, array $data) {
234
-		if (($id = $this->getId($file)) > -1) {
235
-			$this->update($id, $data);
236
-			return $id;
237
-		} else {
238
-			return $this->insert($file, $data);
239
-		}
240
-	}
241
-
242
-	/**
243
-	 * insert meta data for a new file or folder
244
-	 *
245
-	 * @param string $file
246
-	 * @param array $data
247
-	 *
248
-	 * @return int file id
249
-	 * @throws \RuntimeException
250
-	 *
251
-	 * @suppress SqlInjectionChecker
252
-	 */
253
-	public function insert($file, array $data) {
254
-		// normalize file
255
-		$file = $this->normalize($file);
256
-
257
-		if (isset($this->partial[$file])) { //add any saved partial data
258
-			$data = array_merge($this->partial[$file], $data);
259
-			unset($this->partial[$file]);
260
-		}
261
-
262
-		$requiredFields = array('size', 'mtime', 'mimetype');
263
-		foreach ($requiredFields as $field) {
264
-			if (!isset($data[$field])) { //data not complete save as partial and return
265
-				$this->partial[$file] = $data;
266
-				return -1;
267
-			}
268
-		}
269
-
270
-		$data['path'] = $file;
271
-		$data['parent'] = $this->getParentId($file);
272
-		$data['name'] = basename($file);
273
-
274
-		list($queryParts, $params) = $this->buildParts($data);
275
-		$queryParts[] = '`storage`';
276
-		$params[] = $this->getNumericStorageId();
277
-
278
-		$queryParts = array_map(function ($item) {
279
-			return trim($item, "`");
280
-		}, $queryParts);
281
-		$values = array_combine($queryParts, $params);
282
-
283
-		try {
284
-			$builder = $this->connection->getQueryBuilder();
285
-			$builder->insert('filecache');
286
-
287
-			foreach ($values as $column => $value) {
288
-				$builder->setValue($column, $builder->createNamedParameter($value));
289
-			}
290
-
291
-			if ($builder->execute()) {
292
-				$fileId = (int)$this->connection->lastInsertId('*PREFIX*filecache');
293
-				$this->eventDispatcher->dispatch(CacheInsertEvent::class, new CacheInsertEvent($this->storage, $file, $fileId));
294
-				return $fileId;
295
-			}
296
-		} catch (UniqueConstraintViolationException $e) {
297
-			// entry exists already
298
-		}
299
-
300
-		// The file was created in the mean time
301
-		if (($id = $this->getId($file)) > -1) {
302
-			$this->update($id, $data);
303
-			return $id;
304
-		} else {
305
-			throw new \RuntimeException('File entry could not be inserted but could also not be selected with getId() in order to perform an update. Please try again.');
306
-		}
307
-	}
308
-
309
-	/**
310
-	 * update the metadata of an existing file or folder in the cache
311
-	 *
312
-	 * @param int $id the fileid of the existing file or folder
313
-	 * @param array $data [$key => $value] the metadata to update, only the fields provided in the array will be updated, non-provided values will remain unchanged
314
-	 */
315
-	public function update($id, array $data) {
316
-
317
-		if (isset($data['path'])) {
318
-			// normalize path
319
-			$data['path'] = $this->normalize($data['path']);
320
-		}
321
-
322
-		if (isset($data['name'])) {
323
-			// normalize path
324
-			$data['name'] = $this->normalize($data['name']);
325
-		}
326
-
327
-		list($queryParts, $params) = $this->buildParts($data);
328
-		// duplicate $params because we need the parts twice in the SQL statement
329
-		// once for the SET part, once in the WHERE clause
330
-		$params = array_merge($params, $params);
331
-		$params[] = $id;
332
-
333
-		// don't update if the data we try to set is the same as the one in the record
334
-		// some databases (Postgres) don't like superfluous updates
335
-		$sql = 'UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? ' .
336
-			'WHERE (' .
337
-			implode(' <> ? OR ', $queryParts) . ' <> ? OR ' .
338
-			implode(' IS NULL OR ', $queryParts) . ' IS NULL' .
339
-			') AND `fileid` = ? ';
340
-		$this->connection->executeQuery($sql, $params);
341
-
342
-		$path = $this->getPathById($id);
343
-		// path can still be null if the file doesn't exist
344
-		if ($path !== null) {
345
-			$this->eventDispatcher->dispatch(CacheUpdateEvent::class, new CacheUpdateEvent($this->storage, $path, $id));
346
-		}
347
-	}
348
-
349
-	/**
350
-	 * extract query parts and params array from data array
351
-	 *
352
-	 * @param array $data
353
-	 * @return array [$queryParts, $params]
354
-	 *        $queryParts: string[], the (escaped) column names to be set in the query
355
-	 *        $params: mixed[], the new values for the columns, to be passed as params to the query
356
-	 */
357
-	protected function buildParts(array $data) {
358
-		$fields = array(
359
-			'path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted',
360
-			'etag', 'permissions', 'checksum', 'storage');
361
-
362
-		$doNotCopyStorageMTime = false;
363
-		if (array_key_exists('mtime', $data) && $data['mtime'] === null) {
364
-			// this horrific magic tells it to not copy storage_mtime to mtime
365
-			unset($data['mtime']);
366
-			$doNotCopyStorageMTime = true;
367
-		}
368
-
369
-		$params = array();
370
-		$queryParts = array();
371
-		foreach ($data as $name => $value) {
372
-			if (array_search($name, $fields) !== false) {
373
-				if ($name === 'path') {
374
-					$params[] = md5($value);
375
-					$queryParts[] = '`path_hash`';
376
-				} elseif ($name === 'mimetype') {
377
-					$params[] = $this->mimetypeLoader->getId(substr($value, 0, strpos($value, '/')));
378
-					$queryParts[] = '`mimepart`';
379
-					$value = $this->mimetypeLoader->getId($value);
380
-				} elseif ($name === 'storage_mtime') {
381
-					if (!$doNotCopyStorageMTime && !isset($data['mtime'])) {
382
-						$params[] = $value;
383
-						$queryParts[] = '`mtime`';
384
-					}
385
-				} elseif ($name === 'encrypted') {
386
-					if (isset($data['encryptedVersion'])) {
387
-						$value = $data['encryptedVersion'];
388
-					} else {
389
-						// Boolean to integer conversion
390
-						$value = $value ? 1 : 0;
391
-					}
392
-				}
393
-				$params[] = $value;
394
-				$queryParts[] = '`' . $name . '`';
395
-			}
396
-		}
397
-		return array($queryParts, $params);
398
-	}
399
-
400
-	/**
401
-	 * get the file id for a file
402
-	 *
403
-	 * A file id is a numeric id for a file or folder that's unique within an owncloud instance which stays the same for the lifetime of a file
404
-	 *
405
-	 * File ids are easiest way for apps to store references to a file since unlike paths they are not affected by renames or sharing
406
-	 *
407
-	 * @param string $file
408
-	 * @return int
409
-	 */
410
-	public function getId($file) {
411
-		// normalize file
412
-		$file = $this->normalize($file);
413
-
414
-		$pathHash = md5($file);
415
-
416
-		$sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
417
-		$result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
418
-		if ($row = $result->fetch()) {
419
-			return (int)$row['fileid'];
420
-		} else {
421
-			return -1;
422
-		}
423
-	}
424
-
425
-	/**
426
-	 * get the id of the parent folder of a file
427
-	 *
428
-	 * @param string $file
429
-	 * @return int
430
-	 */
431
-	public function getParentId($file) {
432
-		if ($file === '') {
433
-			return -1;
434
-		} else {
435
-			$parent = $this->getParentPath($file);
436
-			return (int)$this->getId($parent);
437
-		}
438
-	}
439
-
440
-	private function getParentPath($path) {
441
-		$parent = dirname($path);
442
-		if ($parent === '.') {
443
-			$parent = '';
444
-		}
445
-		return $parent;
446
-	}
447
-
448
-	/**
449
-	 * check if a file is available in the cache
450
-	 *
451
-	 * @param string $file
452
-	 * @return bool
453
-	 */
454
-	public function inCache($file) {
455
-		return $this->getId($file) != -1;
456
-	}
457
-
458
-	/**
459
-	 * remove a file or folder from the cache
460
-	 *
461
-	 * when removing a folder from the cache all files and folders inside the folder will be removed as well
462
-	 *
463
-	 * @param string $file
464
-	 */
465
-	public function remove($file) {
466
-		$entry = $this->get($file);
467
-		$sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?';
468
-		$this->connection->executeQuery($sql, array($entry['fileid']));
469
-		if ($entry['mimetype'] === 'httpd/unix-directory') {
470
-			$this->removeChildren($entry);
471
-		}
472
-	}
473
-
474
-	/**
475
-	 * Get all sub folders of a folder
476
-	 *
477
-	 * @param array $entry the cache entry of the folder to get the subfolders for
478
-	 * @return array[] the cache entries for the subfolders
479
-	 */
480
-	private function getSubFolders($entry) {
481
-		$children = $this->getFolderContentsById($entry['fileid']);
482
-		return array_filter($children, function ($child) {
483
-			return $child['mimetype'] === 'httpd/unix-directory';
484
-		});
485
-	}
486
-
487
-	/**
488
-	 * Recursively remove all children of a folder
489
-	 *
490
-	 * @param array $entry the cache entry of the folder to remove the children of
491
-	 * @throws \OC\DatabaseException
492
-	 */
493
-	private function removeChildren($entry) {
494
-		$subFolders = $this->getSubFolders($entry);
495
-		foreach ($subFolders as $folder) {
496
-			$this->removeChildren($folder);
497
-		}
498
-		$sql = 'DELETE FROM `*PREFIX*filecache` WHERE `parent` = ?';
499
-		$this->connection->executeQuery($sql, array($entry['fileid']));
500
-	}
501
-
502
-	/**
503
-	 * Move a file or folder in the cache
504
-	 *
505
-	 * @param string $source
506
-	 * @param string $target
507
-	 */
508
-	public function move($source, $target) {
509
-		$this->moveFromCache($this, $source, $target);
510
-	}
511
-
512
-	/**
513
-	 * Get the storage id and path needed for a move
514
-	 *
515
-	 * @param string $path
516
-	 * @return array [$storageId, $internalPath]
517
-	 */
518
-	protected function getMoveInfo($path) {
519
-		return [$this->getNumericStorageId(), $path];
520
-	}
521
-
522
-	/**
523
-	 * Move a file or folder in the cache
524
-	 *
525
-	 * @param \OCP\Files\Cache\ICache $sourceCache
526
-	 * @param string $sourcePath
527
-	 * @param string $targetPath
528
-	 * @throws \OC\DatabaseException
529
-	 * @throws \Exception if the given storages have an invalid id
530
-	 * @suppress SqlInjectionChecker
531
-	 */
532
-	public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
533
-		if ($sourceCache instanceof Cache) {
534
-			// normalize source and target
535
-			$sourcePath = $this->normalize($sourcePath);
536
-			$targetPath = $this->normalize($targetPath);
537
-
538
-			$sourceData = $sourceCache->get($sourcePath);
539
-			$sourceId = $sourceData['fileid'];
540
-			$newParentId = $this->getParentId($targetPath);
541
-
542
-			list($sourceStorageId, $sourcePath) = $sourceCache->getMoveInfo($sourcePath);
543
-			list($targetStorageId, $targetPath) = $this->getMoveInfo($targetPath);
544
-
545
-			if (is_null($sourceStorageId) || $sourceStorageId === false) {
546
-				throw new \Exception('Invalid source storage id: ' . $sourceStorageId);
547
-			}
548
-			if (is_null($targetStorageId) || $targetStorageId === false) {
549
-				throw new \Exception('Invalid target storage id: ' . $targetStorageId);
550
-			}
551
-
552
-			$this->connection->beginTransaction();
553
-			if ($sourceData['mimetype'] === 'httpd/unix-directory') {
554
-				//update all child entries
555
-				$sourceLength = mb_strlen($sourcePath);
556
-				$query = $this->connection->getQueryBuilder();
557
-
558
-				$fun = $query->func();
559
-				$newPathFunction = $fun->concat(
560
-					$query->createNamedParameter($targetPath),
561
-					$fun->substring('path', $query->createNamedParameter($sourceLength + 1, IQueryBuilder::PARAM_INT))// +1 for the leading slash
562
-				);
563
-				$query->update('filecache')
564
-					->set('storage', $query->createNamedParameter($targetStorageId, IQueryBuilder::PARAM_INT))
565
-					->set('path_hash', $fun->md5($newPathFunction))
566
-					->set('path', $newPathFunction)
567
-					->where($query->expr()->eq('storage', $query->createNamedParameter($sourceStorageId, IQueryBuilder::PARAM_INT)))
568
-					->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($sourcePath) . '/%')));
569
-
570
-				try {
571
-					$query->execute();
572
-				} catch (\OC\DatabaseException $e) {
573
-					$this->connection->rollBack();
574
-					throw $e;
575
-				}
576
-			}
577
-
578
-			$sql = 'UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ?, `name` = ?, `parent` = ? WHERE `fileid` = ?';
579
-			$this->connection->executeQuery($sql, array($targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId));
580
-			$this->connection->commit();
581
-		} else {
582
-			$this->moveFromCacheFallback($sourceCache, $sourcePath, $targetPath);
583
-		}
584
-	}
585
-
586
-	/**
587
-	 * remove all entries for files that are stored on the storage from the cache
588
-	 */
589
-	public function clear() {
590
-		$sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?';
591
-		$this->connection->executeQuery($sql, array($this->getNumericStorageId()));
592
-
593
-		$sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?';
594
-		$this->connection->executeQuery($sql, array($this->storageId));
595
-	}
596
-
597
-	/**
598
-	 * Get the scan status of a file
599
-	 *
600
-	 * - Cache::NOT_FOUND: File is not in the cache
601
-	 * - Cache::PARTIAL: File is not stored in the cache but some incomplete data is known
602
-	 * - Cache::SHALLOW: The folder and it's direct children are in the cache but not all sub folders are fully scanned
603
-	 * - Cache::COMPLETE: The file or folder, with all it's children) are fully scanned
604
-	 *
605
-	 * @param string $file
606
-	 *
607
-	 * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
608
-	 */
609
-	public function getStatus($file) {
610
-		// normalize file
611
-		$file = $this->normalize($file);
612
-
613
-		$pathHash = md5($file);
614
-		$sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
615
-		$result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
616
-		if ($row = $result->fetch()) {
617
-			if ((int)$row['size'] === -1) {
618
-				return self::SHALLOW;
619
-			} else {
620
-				return self::COMPLETE;
621
-			}
622
-		} else {
623
-			if (isset($this->partial[$file])) {
624
-				return self::PARTIAL;
625
-			} else {
626
-				return self::NOT_FOUND;
627
-			}
628
-		}
629
-	}
630
-
631
-	/**
632
-	 * search for files matching $pattern
633
-	 *
634
-	 * @param string $pattern the search pattern using SQL search syntax (e.g. '%searchstring%')
635
-	 * @return ICacheEntry[] an array of cache entries where the name matches the search pattern
636
-	 */
637
-	public function search($pattern) {
638
-		// normalize pattern
639
-		$pattern = $this->normalize($pattern);
640
-
641
-		if ($pattern === '%%') {
642
-			return [];
643
-		}
644
-
645
-
646
-		$sql = '
215
+            $result = $this->connection->executeQuery($sql, [$fileId]);
216
+            $files = $result->fetchAll();
217
+            return array_map(function (array $data) {
218
+                return self::cacheEntryFromData($data, $this->mimetypeLoader);
219
+            }, $files);
220
+        }
221
+        return [];
222
+    }
223
+
224
+    /**
225
+     * insert or update meta data for a file or folder
226
+     *
227
+     * @param string $file
228
+     * @param array $data
229
+     *
230
+     * @return int file id
231
+     * @throws \RuntimeException
232
+     */
233
+    public function put($file, array $data) {
234
+        if (($id = $this->getId($file)) > -1) {
235
+            $this->update($id, $data);
236
+            return $id;
237
+        } else {
238
+            return $this->insert($file, $data);
239
+        }
240
+    }
241
+
242
+    /**
243
+     * insert meta data for a new file or folder
244
+     *
245
+     * @param string $file
246
+     * @param array $data
247
+     *
248
+     * @return int file id
249
+     * @throws \RuntimeException
250
+     *
251
+     * @suppress SqlInjectionChecker
252
+     */
253
+    public function insert($file, array $data) {
254
+        // normalize file
255
+        $file = $this->normalize($file);
256
+
257
+        if (isset($this->partial[$file])) { //add any saved partial data
258
+            $data = array_merge($this->partial[$file], $data);
259
+            unset($this->partial[$file]);
260
+        }
261
+
262
+        $requiredFields = array('size', 'mtime', 'mimetype');
263
+        foreach ($requiredFields as $field) {
264
+            if (!isset($data[$field])) { //data not complete save as partial and return
265
+                $this->partial[$file] = $data;
266
+                return -1;
267
+            }
268
+        }
269
+
270
+        $data['path'] = $file;
271
+        $data['parent'] = $this->getParentId($file);
272
+        $data['name'] = basename($file);
273
+
274
+        list($queryParts, $params) = $this->buildParts($data);
275
+        $queryParts[] = '`storage`';
276
+        $params[] = $this->getNumericStorageId();
277
+
278
+        $queryParts = array_map(function ($item) {
279
+            return trim($item, "`");
280
+        }, $queryParts);
281
+        $values = array_combine($queryParts, $params);
282
+
283
+        try {
284
+            $builder = $this->connection->getQueryBuilder();
285
+            $builder->insert('filecache');
286
+
287
+            foreach ($values as $column => $value) {
288
+                $builder->setValue($column, $builder->createNamedParameter($value));
289
+            }
290
+
291
+            if ($builder->execute()) {
292
+                $fileId = (int)$this->connection->lastInsertId('*PREFIX*filecache');
293
+                $this->eventDispatcher->dispatch(CacheInsertEvent::class, new CacheInsertEvent($this->storage, $file, $fileId));
294
+                return $fileId;
295
+            }
296
+        } catch (UniqueConstraintViolationException $e) {
297
+            // entry exists already
298
+        }
299
+
300
+        // The file was created in the mean time
301
+        if (($id = $this->getId($file)) > -1) {
302
+            $this->update($id, $data);
303
+            return $id;
304
+        } else {
305
+            throw new \RuntimeException('File entry could not be inserted but could also not be selected with getId() in order to perform an update. Please try again.');
306
+        }
307
+    }
308
+
309
+    /**
310
+     * update the metadata of an existing file or folder in the cache
311
+     *
312
+     * @param int $id the fileid of the existing file or folder
313
+     * @param array $data [$key => $value] the metadata to update, only the fields provided in the array will be updated, non-provided values will remain unchanged
314
+     */
315
+    public function update($id, array $data) {
316
+
317
+        if (isset($data['path'])) {
318
+            // normalize path
319
+            $data['path'] = $this->normalize($data['path']);
320
+        }
321
+
322
+        if (isset($data['name'])) {
323
+            // normalize path
324
+            $data['name'] = $this->normalize($data['name']);
325
+        }
326
+
327
+        list($queryParts, $params) = $this->buildParts($data);
328
+        // duplicate $params because we need the parts twice in the SQL statement
329
+        // once for the SET part, once in the WHERE clause
330
+        $params = array_merge($params, $params);
331
+        $params[] = $id;
332
+
333
+        // don't update if the data we try to set is the same as the one in the record
334
+        // some databases (Postgres) don't like superfluous updates
335
+        $sql = 'UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? ' .
336
+            'WHERE (' .
337
+            implode(' <> ? OR ', $queryParts) . ' <> ? OR ' .
338
+            implode(' IS NULL OR ', $queryParts) . ' IS NULL' .
339
+            ') AND `fileid` = ? ';
340
+        $this->connection->executeQuery($sql, $params);
341
+
342
+        $path = $this->getPathById($id);
343
+        // path can still be null if the file doesn't exist
344
+        if ($path !== null) {
345
+            $this->eventDispatcher->dispatch(CacheUpdateEvent::class, new CacheUpdateEvent($this->storage, $path, $id));
346
+        }
347
+    }
348
+
349
+    /**
350
+     * extract query parts and params array from data array
351
+     *
352
+     * @param array $data
353
+     * @return array [$queryParts, $params]
354
+     *        $queryParts: string[], the (escaped) column names to be set in the query
355
+     *        $params: mixed[], the new values for the columns, to be passed as params to the query
356
+     */
357
+    protected function buildParts(array $data) {
358
+        $fields = array(
359
+            'path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted',
360
+            'etag', 'permissions', 'checksum', 'storage');
361
+
362
+        $doNotCopyStorageMTime = false;
363
+        if (array_key_exists('mtime', $data) && $data['mtime'] === null) {
364
+            // this horrific magic tells it to not copy storage_mtime to mtime
365
+            unset($data['mtime']);
366
+            $doNotCopyStorageMTime = true;
367
+        }
368
+
369
+        $params = array();
370
+        $queryParts = array();
371
+        foreach ($data as $name => $value) {
372
+            if (array_search($name, $fields) !== false) {
373
+                if ($name === 'path') {
374
+                    $params[] = md5($value);
375
+                    $queryParts[] = '`path_hash`';
376
+                } elseif ($name === 'mimetype') {
377
+                    $params[] = $this->mimetypeLoader->getId(substr($value, 0, strpos($value, '/')));
378
+                    $queryParts[] = '`mimepart`';
379
+                    $value = $this->mimetypeLoader->getId($value);
380
+                } elseif ($name === 'storage_mtime') {
381
+                    if (!$doNotCopyStorageMTime && !isset($data['mtime'])) {
382
+                        $params[] = $value;
383
+                        $queryParts[] = '`mtime`';
384
+                    }
385
+                } elseif ($name === 'encrypted') {
386
+                    if (isset($data['encryptedVersion'])) {
387
+                        $value = $data['encryptedVersion'];
388
+                    } else {
389
+                        // Boolean to integer conversion
390
+                        $value = $value ? 1 : 0;
391
+                    }
392
+                }
393
+                $params[] = $value;
394
+                $queryParts[] = '`' . $name . '`';
395
+            }
396
+        }
397
+        return array($queryParts, $params);
398
+    }
399
+
400
+    /**
401
+     * get the file id for a file
402
+     *
403
+     * A file id is a numeric id for a file or folder that's unique within an owncloud instance which stays the same for the lifetime of a file
404
+     *
405
+     * File ids are easiest way for apps to store references to a file since unlike paths they are not affected by renames or sharing
406
+     *
407
+     * @param string $file
408
+     * @return int
409
+     */
410
+    public function getId($file) {
411
+        // normalize file
412
+        $file = $this->normalize($file);
413
+
414
+        $pathHash = md5($file);
415
+
416
+        $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
417
+        $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
418
+        if ($row = $result->fetch()) {
419
+            return (int)$row['fileid'];
420
+        } else {
421
+            return -1;
422
+        }
423
+    }
424
+
425
+    /**
426
+     * get the id of the parent folder of a file
427
+     *
428
+     * @param string $file
429
+     * @return int
430
+     */
431
+    public function getParentId($file) {
432
+        if ($file === '') {
433
+            return -1;
434
+        } else {
435
+            $parent = $this->getParentPath($file);
436
+            return (int)$this->getId($parent);
437
+        }
438
+    }
439
+
440
+    private function getParentPath($path) {
441
+        $parent = dirname($path);
442
+        if ($parent === '.') {
443
+            $parent = '';
444
+        }
445
+        return $parent;
446
+    }
447
+
448
+    /**
449
+     * check if a file is available in the cache
450
+     *
451
+     * @param string $file
452
+     * @return bool
453
+     */
454
+    public function inCache($file) {
455
+        return $this->getId($file) != -1;
456
+    }
457
+
458
+    /**
459
+     * remove a file or folder from the cache
460
+     *
461
+     * when removing a folder from the cache all files and folders inside the folder will be removed as well
462
+     *
463
+     * @param string $file
464
+     */
465
+    public function remove($file) {
466
+        $entry = $this->get($file);
467
+        $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?';
468
+        $this->connection->executeQuery($sql, array($entry['fileid']));
469
+        if ($entry['mimetype'] === 'httpd/unix-directory') {
470
+            $this->removeChildren($entry);
471
+        }
472
+    }
473
+
474
+    /**
475
+     * Get all sub folders of a folder
476
+     *
477
+     * @param array $entry the cache entry of the folder to get the subfolders for
478
+     * @return array[] the cache entries for the subfolders
479
+     */
480
+    private function getSubFolders($entry) {
481
+        $children = $this->getFolderContentsById($entry['fileid']);
482
+        return array_filter($children, function ($child) {
483
+            return $child['mimetype'] === 'httpd/unix-directory';
484
+        });
485
+    }
486
+
487
+    /**
488
+     * Recursively remove all children of a folder
489
+     *
490
+     * @param array $entry the cache entry of the folder to remove the children of
491
+     * @throws \OC\DatabaseException
492
+     */
493
+    private function removeChildren($entry) {
494
+        $subFolders = $this->getSubFolders($entry);
495
+        foreach ($subFolders as $folder) {
496
+            $this->removeChildren($folder);
497
+        }
498
+        $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `parent` = ?';
499
+        $this->connection->executeQuery($sql, array($entry['fileid']));
500
+    }
501
+
502
+    /**
503
+     * Move a file or folder in the cache
504
+     *
505
+     * @param string $source
506
+     * @param string $target
507
+     */
508
+    public function move($source, $target) {
509
+        $this->moveFromCache($this, $source, $target);
510
+    }
511
+
512
+    /**
513
+     * Get the storage id and path needed for a move
514
+     *
515
+     * @param string $path
516
+     * @return array [$storageId, $internalPath]
517
+     */
518
+    protected function getMoveInfo($path) {
519
+        return [$this->getNumericStorageId(), $path];
520
+    }
521
+
522
+    /**
523
+     * Move a file or folder in the cache
524
+     *
525
+     * @param \OCP\Files\Cache\ICache $sourceCache
526
+     * @param string $sourcePath
527
+     * @param string $targetPath
528
+     * @throws \OC\DatabaseException
529
+     * @throws \Exception if the given storages have an invalid id
530
+     * @suppress SqlInjectionChecker
531
+     */
532
+    public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
533
+        if ($sourceCache instanceof Cache) {
534
+            // normalize source and target
535
+            $sourcePath = $this->normalize($sourcePath);
536
+            $targetPath = $this->normalize($targetPath);
537
+
538
+            $sourceData = $sourceCache->get($sourcePath);
539
+            $sourceId = $sourceData['fileid'];
540
+            $newParentId = $this->getParentId($targetPath);
541
+
542
+            list($sourceStorageId, $sourcePath) = $sourceCache->getMoveInfo($sourcePath);
543
+            list($targetStorageId, $targetPath) = $this->getMoveInfo($targetPath);
544
+
545
+            if (is_null($sourceStorageId) || $sourceStorageId === false) {
546
+                throw new \Exception('Invalid source storage id: ' . $sourceStorageId);
547
+            }
548
+            if (is_null($targetStorageId) || $targetStorageId === false) {
549
+                throw new \Exception('Invalid target storage id: ' . $targetStorageId);
550
+            }
551
+
552
+            $this->connection->beginTransaction();
553
+            if ($sourceData['mimetype'] === 'httpd/unix-directory') {
554
+                //update all child entries
555
+                $sourceLength = mb_strlen($sourcePath);
556
+                $query = $this->connection->getQueryBuilder();
557
+
558
+                $fun = $query->func();
559
+                $newPathFunction = $fun->concat(
560
+                    $query->createNamedParameter($targetPath),
561
+                    $fun->substring('path', $query->createNamedParameter($sourceLength + 1, IQueryBuilder::PARAM_INT))// +1 for the leading slash
562
+                );
563
+                $query->update('filecache')
564
+                    ->set('storage', $query->createNamedParameter($targetStorageId, IQueryBuilder::PARAM_INT))
565
+                    ->set('path_hash', $fun->md5($newPathFunction))
566
+                    ->set('path', $newPathFunction)
567
+                    ->where($query->expr()->eq('storage', $query->createNamedParameter($sourceStorageId, IQueryBuilder::PARAM_INT)))
568
+                    ->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($sourcePath) . '/%')));
569
+
570
+                try {
571
+                    $query->execute();
572
+                } catch (\OC\DatabaseException $e) {
573
+                    $this->connection->rollBack();
574
+                    throw $e;
575
+                }
576
+            }
577
+
578
+            $sql = 'UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ?, `name` = ?, `parent` = ? WHERE `fileid` = ?';
579
+            $this->connection->executeQuery($sql, array($targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId));
580
+            $this->connection->commit();
581
+        } else {
582
+            $this->moveFromCacheFallback($sourceCache, $sourcePath, $targetPath);
583
+        }
584
+    }
585
+
586
+    /**
587
+     * remove all entries for files that are stored on the storage from the cache
588
+     */
589
+    public function clear() {
590
+        $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?';
591
+        $this->connection->executeQuery($sql, array($this->getNumericStorageId()));
592
+
593
+        $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?';
594
+        $this->connection->executeQuery($sql, array($this->storageId));
595
+    }
596
+
597
+    /**
598
+     * Get the scan status of a file
599
+     *
600
+     * - Cache::NOT_FOUND: File is not in the cache
601
+     * - Cache::PARTIAL: File is not stored in the cache but some incomplete data is known
602
+     * - Cache::SHALLOW: The folder and it's direct children are in the cache but not all sub folders are fully scanned
603
+     * - Cache::COMPLETE: The file or folder, with all it's children) are fully scanned
604
+     *
605
+     * @param string $file
606
+     *
607
+     * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
608
+     */
609
+    public function getStatus($file) {
610
+        // normalize file
611
+        $file = $this->normalize($file);
612
+
613
+        $pathHash = md5($file);
614
+        $sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
615
+        $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
616
+        if ($row = $result->fetch()) {
617
+            if ((int)$row['size'] === -1) {
618
+                return self::SHALLOW;
619
+            } else {
620
+                return self::COMPLETE;
621
+            }
622
+        } else {
623
+            if (isset($this->partial[$file])) {
624
+                return self::PARTIAL;
625
+            } else {
626
+                return self::NOT_FOUND;
627
+            }
628
+        }
629
+    }
630
+
631
+    /**
632
+     * search for files matching $pattern
633
+     *
634
+     * @param string $pattern the search pattern using SQL search syntax (e.g. '%searchstring%')
635
+     * @return ICacheEntry[] an array of cache entries where the name matches the search pattern
636
+     */
637
+    public function search($pattern) {
638
+        // normalize pattern
639
+        $pattern = $this->normalize($pattern);
640
+
641
+        if ($pattern === '%%') {
642
+            return [];
643
+        }
644
+
645
+
646
+        $sql = '
647 647
 			SELECT `fileid`, `storage`, `path`, `parent`, `name`,
648 648
 				`mimetype`, `storage_mtime`, `mimepart`, `size`, `mtime`,
649 649
 				 `encrypted`, `etag`, `permissions`, `checksum`
650 650
 			FROM `*PREFIX*filecache`
651 651
 			WHERE `storage` = ? AND `name` ILIKE ?';
652
-		$result = $this->connection->executeQuery($sql,
653
-			[$this->getNumericStorageId(), $pattern]
654
-		);
655
-
656
-		return $this->searchResultToCacheEntries($result);
657
-	}
658
-
659
-	/**
660
-	 * @param Statement $result
661
-	 * @return CacheEntry[]
662
-	 */
663
-	private function searchResultToCacheEntries(Statement $result) {
664
-		$files = $result->fetchAll();
665
-
666
-		return array_map(function (array $data) {
667
-			return self::cacheEntryFromData($data, $this->mimetypeLoader);
668
-		}, $files);
669
-	}
670
-
671
-	/**
672
-	 * search for files by mimetype
673
-	 *
674
-	 * @param string $mimetype either a full mimetype to search ('text/plain') or only the first part of a mimetype ('image')
675
-	 *        where it will search for all mimetypes in the group ('image/*')
676
-	 * @return ICacheEntry[] an array of cache entries where the mimetype matches the search
677
-	 */
678
-	public function searchByMime($mimetype) {
679
-		if (strpos($mimetype, '/')) {
680
-			$where = '`mimetype` = ?';
681
-		} else {
682
-			$where = '`mimepart` = ?';
683
-		}
684
-		$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `storage_mtime`, `mtime`, `encrypted`, `etag`, `permissions`, `checksum`
652
+        $result = $this->connection->executeQuery($sql,
653
+            [$this->getNumericStorageId(), $pattern]
654
+        );
655
+
656
+        return $this->searchResultToCacheEntries($result);
657
+    }
658
+
659
+    /**
660
+     * @param Statement $result
661
+     * @return CacheEntry[]
662
+     */
663
+    private function searchResultToCacheEntries(Statement $result) {
664
+        $files = $result->fetchAll();
665
+
666
+        return array_map(function (array $data) {
667
+            return self::cacheEntryFromData($data, $this->mimetypeLoader);
668
+        }, $files);
669
+    }
670
+
671
+    /**
672
+     * search for files by mimetype
673
+     *
674
+     * @param string $mimetype either a full mimetype to search ('text/plain') or only the first part of a mimetype ('image')
675
+     *        where it will search for all mimetypes in the group ('image/*')
676
+     * @return ICacheEntry[] an array of cache entries where the mimetype matches the search
677
+     */
678
+    public function searchByMime($mimetype) {
679
+        if (strpos($mimetype, '/')) {
680
+            $where = '`mimetype` = ?';
681
+        } else {
682
+            $where = '`mimepart` = ?';
683
+        }
684
+        $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `storage_mtime`, `mtime`, `encrypted`, `etag`, `permissions`, `checksum`
685 685
 				FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?';
686
-		$mimetype = $this->mimetypeLoader->getId($mimetype);
687
-		$result = $this->connection->executeQuery($sql, array($mimetype, $this->getNumericStorageId()));
688
-
689
-		return $this->searchResultToCacheEntries($result);
690
-	}
691
-
692
-	public function searchQuery(ISearchQuery $searchQuery) {
693
-		$builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
694
-
695
-		$query = $builder->select(['fileid', 'storage', 'path', 'parent', 'name', 'mimetype', 'mimepart', 'size', 'mtime', 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum'])
696
-			->from('filecache', 'file');
697
-
698
-		$query->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->getNumericStorageId())));
699
-
700
-		if ($this->querySearchHelper->shouldJoinTags($searchQuery->getSearchOperation())) {
701
-			$query
702
-				->innerJoin('file', 'vcategory_to_object', 'tagmap', $builder->expr()->eq('file.fileid', 'tagmap.objid'))
703
-				->innerJoin('tagmap', 'vcategory', 'tag', $builder->expr()->andX(
704
-					$builder->expr()->eq('tagmap.type', 'tag.type'),
705
-					$builder->expr()->eq('tagmap.categoryid', 'tag.id')
706
-				))
707
-				->andWhere($builder->expr()->eq('tag.type', $builder->createNamedParameter('files')))
708
-				->andWhere($builder->expr()->eq('tag.uid', $builder->createNamedParameter($searchQuery->getUser()->getUID())));
709
-		}
710
-
711
-		$query->andWhere($this->querySearchHelper->searchOperatorToDBExpr($builder, $searchQuery->getSearchOperation()));
712
-
713
-		$this->querySearchHelper->addSearchOrdersToQuery($query, $searchQuery->getOrder());
714
-
715
-		if ($searchQuery->getLimit()) {
716
-			$query->setMaxResults($searchQuery->getLimit());
717
-		}
718
-		if ($searchQuery->getOffset()) {
719
-			$query->setFirstResult($searchQuery->getOffset());
720
-		}
721
-
722
-		$result = $query->execute();
723
-		return $this->searchResultToCacheEntries($result);
724
-	}
725
-
726
-	/**
727
-	 * Re-calculate the folder size and the size of all parent folders
728
-	 *
729
-	 * @param string|boolean $path
730
-	 * @param array $data (optional) meta data of the folder
731
-	 */
732
-	public function correctFolderSize($path, $data = null, $isBackgroundScan = false) {
733
-		$this->calculateFolderSize($path, $data);
734
-		if ($path !== '') {
735
-			$parent = dirname($path);
736
-			if ($parent === '.' or $parent === '/') {
737
-				$parent = '';
738
-			}
739
-			if ($isBackgroundScan) {
740
-				$parentData = $this->get($parent);
741
-				if ($parentData['size'] !== -1 && $this->getIncompleteChildrenCount($parentData['fileid']) === 0) {
742
-					$this->correctFolderSize($parent, $parentData, $isBackgroundScan);
743
-				}
744
-			} else {
745
-				$this->correctFolderSize($parent);
746
-			}
747
-		}
748
-	}
749
-
750
-	/**
751
-	 * get the incomplete count that shares parent $folder
752
-	 *
753
-	 * @param int $fileId the file id of the folder
754
-	 * @return int
755
-	 */
756
-	public function getIncompleteChildrenCount($fileId) {
757
-		if ($fileId > -1) {
758
-			$sql = 'SELECT count(*)
686
+        $mimetype = $this->mimetypeLoader->getId($mimetype);
687
+        $result = $this->connection->executeQuery($sql, array($mimetype, $this->getNumericStorageId()));
688
+
689
+        return $this->searchResultToCacheEntries($result);
690
+    }
691
+
692
+    public function searchQuery(ISearchQuery $searchQuery) {
693
+        $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
694
+
695
+        $query = $builder->select(['fileid', 'storage', 'path', 'parent', 'name', 'mimetype', 'mimepart', 'size', 'mtime', 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum'])
696
+            ->from('filecache', 'file');
697
+
698
+        $query->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->getNumericStorageId())));
699
+
700
+        if ($this->querySearchHelper->shouldJoinTags($searchQuery->getSearchOperation())) {
701
+            $query
702
+                ->innerJoin('file', 'vcategory_to_object', 'tagmap', $builder->expr()->eq('file.fileid', 'tagmap.objid'))
703
+                ->innerJoin('tagmap', 'vcategory', 'tag', $builder->expr()->andX(
704
+                    $builder->expr()->eq('tagmap.type', 'tag.type'),
705
+                    $builder->expr()->eq('tagmap.categoryid', 'tag.id')
706
+                ))
707
+                ->andWhere($builder->expr()->eq('tag.type', $builder->createNamedParameter('files')))
708
+                ->andWhere($builder->expr()->eq('tag.uid', $builder->createNamedParameter($searchQuery->getUser()->getUID())));
709
+        }
710
+
711
+        $query->andWhere($this->querySearchHelper->searchOperatorToDBExpr($builder, $searchQuery->getSearchOperation()));
712
+
713
+        $this->querySearchHelper->addSearchOrdersToQuery($query, $searchQuery->getOrder());
714
+
715
+        if ($searchQuery->getLimit()) {
716
+            $query->setMaxResults($searchQuery->getLimit());
717
+        }
718
+        if ($searchQuery->getOffset()) {
719
+            $query->setFirstResult($searchQuery->getOffset());
720
+        }
721
+
722
+        $result = $query->execute();
723
+        return $this->searchResultToCacheEntries($result);
724
+    }
725
+
726
+    /**
727
+     * Re-calculate the folder size and the size of all parent folders
728
+     *
729
+     * @param string|boolean $path
730
+     * @param array $data (optional) meta data of the folder
731
+     */
732
+    public function correctFolderSize($path, $data = null, $isBackgroundScan = false) {
733
+        $this->calculateFolderSize($path, $data);
734
+        if ($path !== '') {
735
+            $parent = dirname($path);
736
+            if ($parent === '.' or $parent === '/') {
737
+                $parent = '';
738
+            }
739
+            if ($isBackgroundScan) {
740
+                $parentData = $this->get($parent);
741
+                if ($parentData['size'] !== -1 && $this->getIncompleteChildrenCount($parentData['fileid']) === 0) {
742
+                    $this->correctFolderSize($parent, $parentData, $isBackgroundScan);
743
+                }
744
+            } else {
745
+                $this->correctFolderSize($parent);
746
+            }
747
+        }
748
+    }
749
+
750
+    /**
751
+     * get the incomplete count that shares parent $folder
752
+     *
753
+     * @param int $fileId the file id of the folder
754
+     * @return int
755
+     */
756
+    public function getIncompleteChildrenCount($fileId) {
757
+        if ($fileId > -1) {
758
+            $sql = 'SELECT count(*)
759 759
 					FROM `*PREFIX*filecache` WHERE `parent` = ? AND size = -1';
760
-			$result = $this->connection->executeQuery($sql, [$fileId]);
761
-			return (int)$result->fetchColumn();
762
-		}
763
-		return -1;
764
-	}
765
-
766
-	/**
767
-	 * calculate the size of a folder and set it in the cache
768
-	 *
769
-	 * @param string $path
770
-	 * @param array $entry (optional) meta data of the folder
771
-	 * @return int
772
-	 */
773
-	public function calculateFolderSize($path, $entry = null) {
774
-		$totalSize = 0;
775
-		if (is_null($entry) or !isset($entry['fileid'])) {
776
-			$entry = $this->get($path);
777
-		}
778
-		if (isset($entry['mimetype']) && $entry['mimetype'] === 'httpd/unix-directory') {
779
-			$id = $entry['fileid'];
780
-			$sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2 ' .
781
-				'FROM `*PREFIX*filecache` ' .
782
-				'WHERE `parent` = ? AND `storage` = ?';
783
-			$result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
784
-			if ($row = $result->fetch()) {
785
-				$result->closeCursor();
786
-				list($sum, $min) = array_values($row);
787
-				$sum = 0 + $sum;
788
-				$min = 0 + $min;
789
-				if ($min === -1) {
790
-					$totalSize = $min;
791
-				} else {
792
-					$totalSize = $sum;
793
-				}
794
-				$update = array();
795
-				if ($entry['size'] !== $totalSize) {
796
-					$update['size'] = $totalSize;
797
-				}
798
-				if (count($update) > 0) {
799
-					$this->update($id, $update);
800
-				}
801
-			} else {
802
-				$result->closeCursor();
803
-			}
804
-		}
805
-		return $totalSize;
806
-	}
807
-
808
-	/**
809
-	 * get all file ids on the files on the storage
810
-	 *
811
-	 * @return int[]
812
-	 */
813
-	public function getAll() {
814
-		$sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?';
815
-		$result = $this->connection->executeQuery($sql, array($this->getNumericStorageId()));
816
-		$ids = array();
817
-		while ($row = $result->fetch()) {
818
-			$ids[] = $row['fileid'];
819
-		}
820
-		return $ids;
821
-	}
822
-
823
-	/**
824
-	 * find a folder in the cache which has not been fully scanned
825
-	 *
826
-	 * If multiple incomplete folders are in the cache, the one with the highest id will be returned,
827
-	 * use the one with the highest id gives the best result with the background scanner, since that is most
828
-	 * likely the folder where we stopped scanning previously
829
-	 *
830
-	 * @return string|bool the path of the folder or false when no folder matched
831
-	 */
832
-	public function getIncomplete() {
833
-		$query = $this->connection->prepare('SELECT `path` FROM `*PREFIX*filecache`'
834
-			. ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC', 1);
835
-		$query->execute([$this->getNumericStorageId()]);
836
-		if ($row = $query->fetch()) {
837
-			return $row['path'];
838
-		} else {
839
-			return false;
840
-		}
841
-	}
842
-
843
-	/**
844
-	 * get the path of a file on this storage by it's file id
845
-	 *
846
-	 * @param int $id the file id of the file or folder to search
847
-	 * @return string|null the path of the file (relative to the storage) or null if a file with the given id does not exists within this cache
848
-	 */
849
-	public function getPathById($id) {
850
-		$sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ? AND `storage` = ?';
851
-		$result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
852
-		if ($row = $result->fetch()) {
853
-			// Oracle stores empty strings as null...
854
-			if ($row['path'] === null) {
855
-				return '';
856
-			}
857
-			return $row['path'];
858
-		} else {
859
-			return null;
860
-		}
861
-	}
862
-
863
-	/**
864
-	 * get the storage id of the storage for a file and the internal path of the file
865
-	 * unlike getPathById this does not limit the search to files on this storage and
866
-	 * instead does a global search in the cache table
867
-	 *
868
-	 * @param int $id
869
-	 * @deprecated use getPathById() instead
870
-	 * @return array first element holding the storage id, second the path
871
-	 */
872
-	static public function getById($id) {
873
-		$connection = \OC::$server->getDatabaseConnection();
874
-		$sql = 'SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?';
875
-		$result = $connection->executeQuery($sql, array($id));
876
-		if ($row = $result->fetch()) {
877
-			$numericId = $row['storage'];
878
-			$path = $row['path'];
879
-		} else {
880
-			return null;
881
-		}
882
-
883
-		if ($id = Storage::getStorageId($numericId)) {
884
-			return array($id, $path);
885
-		} else {
886
-			return null;
887
-		}
888
-	}
889
-
890
-	/**
891
-	 * normalize the given path
892
-	 *
893
-	 * @param string $path
894
-	 * @return string
895
-	 */
896
-	public function normalize($path) {
897
-
898
-		return trim(\OC_Util::normalizeUnicode($path), '/');
899
-	}
760
+            $result = $this->connection->executeQuery($sql, [$fileId]);
761
+            return (int)$result->fetchColumn();
762
+        }
763
+        return -1;
764
+    }
765
+
766
+    /**
767
+     * calculate the size of a folder and set it in the cache
768
+     *
769
+     * @param string $path
770
+     * @param array $entry (optional) meta data of the folder
771
+     * @return int
772
+     */
773
+    public function calculateFolderSize($path, $entry = null) {
774
+        $totalSize = 0;
775
+        if (is_null($entry) or !isset($entry['fileid'])) {
776
+            $entry = $this->get($path);
777
+        }
778
+        if (isset($entry['mimetype']) && $entry['mimetype'] === 'httpd/unix-directory') {
779
+            $id = $entry['fileid'];
780
+            $sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2 ' .
781
+                'FROM `*PREFIX*filecache` ' .
782
+                'WHERE `parent` = ? AND `storage` = ?';
783
+            $result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
784
+            if ($row = $result->fetch()) {
785
+                $result->closeCursor();
786
+                list($sum, $min) = array_values($row);
787
+                $sum = 0 + $sum;
788
+                $min = 0 + $min;
789
+                if ($min === -1) {
790
+                    $totalSize = $min;
791
+                } else {
792
+                    $totalSize = $sum;
793
+                }
794
+                $update = array();
795
+                if ($entry['size'] !== $totalSize) {
796
+                    $update['size'] = $totalSize;
797
+                }
798
+                if (count($update) > 0) {
799
+                    $this->update($id, $update);
800
+                }
801
+            } else {
802
+                $result->closeCursor();
803
+            }
804
+        }
805
+        return $totalSize;
806
+    }
807
+
808
+    /**
809
+     * get all file ids on the files on the storage
810
+     *
811
+     * @return int[]
812
+     */
813
+    public function getAll() {
814
+        $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?';
815
+        $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId()));
816
+        $ids = array();
817
+        while ($row = $result->fetch()) {
818
+            $ids[] = $row['fileid'];
819
+        }
820
+        return $ids;
821
+    }
822
+
823
+    /**
824
+     * find a folder in the cache which has not been fully scanned
825
+     *
826
+     * If multiple incomplete folders are in the cache, the one with the highest id will be returned,
827
+     * use the one with the highest id gives the best result with the background scanner, since that is most
828
+     * likely the folder where we stopped scanning previously
829
+     *
830
+     * @return string|bool the path of the folder or false when no folder matched
831
+     */
832
+    public function getIncomplete() {
833
+        $query = $this->connection->prepare('SELECT `path` FROM `*PREFIX*filecache`'
834
+            . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC', 1);
835
+        $query->execute([$this->getNumericStorageId()]);
836
+        if ($row = $query->fetch()) {
837
+            return $row['path'];
838
+        } else {
839
+            return false;
840
+        }
841
+    }
842
+
843
+    /**
844
+     * get the path of a file on this storage by it's file id
845
+     *
846
+     * @param int $id the file id of the file or folder to search
847
+     * @return string|null the path of the file (relative to the storage) or null if a file with the given id does not exists within this cache
848
+     */
849
+    public function getPathById($id) {
850
+        $sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ? AND `storage` = ?';
851
+        $result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
852
+        if ($row = $result->fetch()) {
853
+            // Oracle stores empty strings as null...
854
+            if ($row['path'] === null) {
855
+                return '';
856
+            }
857
+            return $row['path'];
858
+        } else {
859
+            return null;
860
+        }
861
+    }
862
+
863
+    /**
864
+     * get the storage id of the storage for a file and the internal path of the file
865
+     * unlike getPathById this does not limit the search to files on this storage and
866
+     * instead does a global search in the cache table
867
+     *
868
+     * @param int $id
869
+     * @deprecated use getPathById() instead
870
+     * @return array first element holding the storage id, second the path
871
+     */
872
+    static public function getById($id) {
873
+        $connection = \OC::$server->getDatabaseConnection();
874
+        $sql = 'SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?';
875
+        $result = $connection->executeQuery($sql, array($id));
876
+        if ($row = $result->fetch()) {
877
+            $numericId = $row['storage'];
878
+            $path = $row['path'];
879
+        } else {
880
+            return null;
881
+        }
882
+
883
+        if ($id = Storage::getStorageId($numericId)) {
884
+            return array($id, $path);
885
+        } else {
886
+            return null;
887
+        }
888
+    }
889
+
890
+    /**
891
+     * normalize the given path
892
+     *
893
+     * @param string $path
894
+     * @return string
895
+     */
896
+    public function normalize($path) {
897
+
898
+        return trim(\OC_Util::normalizeUnicode($path), '/');
899
+    }
900 900
 }
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -172,21 +172,21 @@  discard block
 block discarded – undo
172 172
 	 */
173 173
 	public static function cacheEntryFromData($data, IMimeTypeLoader $mimetypeLoader) {
174 174
 		//fix types
175
-		$data['fileid'] = (int)$data['fileid'];
176
-		$data['parent'] = (int)$data['parent'];
175
+		$data['fileid'] = (int) $data['fileid'];
176
+		$data['parent'] = (int) $data['parent'];
177 177
 		$data['size'] = 0 + $data['size'];
178
-		$data['mtime'] = (int)$data['mtime'];
179
-		$data['storage_mtime'] = (int)$data['storage_mtime'];
180
-		$data['encryptedVersion'] = (int)$data['encrypted'];
181
-		$data['encrypted'] = (bool)$data['encrypted'];
178
+		$data['mtime'] = (int) $data['mtime'];
179
+		$data['storage_mtime'] = (int) $data['storage_mtime'];
180
+		$data['encryptedVersion'] = (int) $data['encrypted'];
181
+		$data['encrypted'] = (bool) $data['encrypted'];
182 182
 		$data['storage_id'] = $data['storage'];
183
-		$data['storage'] = (int)$data['storage'];
183
+		$data['storage'] = (int) $data['storage'];
184 184
 		$data['mimetype'] = $mimetypeLoader->getMimetypeById($data['mimetype']);
185 185
 		$data['mimepart'] = $mimetypeLoader->getMimetypeById($data['mimepart']);
186 186
 		if ($data['storage_mtime'] == 0) {
187 187
 			$data['storage_mtime'] = $data['mtime'];
188 188
 		}
189
-		$data['permissions'] = (int)$data['permissions'];
189
+		$data['permissions'] = (int) $data['permissions'];
190 190
 		return new CacheEntry($data);
191 191
 	}
192 192
 
@@ -214,7 +214,7 @@  discard block
 block discarded – undo
214 214
 					FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC';
215 215
 			$result = $this->connection->executeQuery($sql, [$fileId]);
216 216
 			$files = $result->fetchAll();
217
-			return array_map(function (array $data) {
217
+			return array_map(function(array $data) {
218 218
 				return self::cacheEntryFromData($data, $this->mimetypeLoader);
219 219
 			}, $files);
220 220
 		}
@@ -275,7 +275,7 @@  discard block
 block discarded – undo
275 275
 		$queryParts[] = '`storage`';
276 276
 		$params[] = $this->getNumericStorageId();
277 277
 
278
-		$queryParts = array_map(function ($item) {
278
+		$queryParts = array_map(function($item) {
279 279
 			return trim($item, "`");
280 280
 		}, $queryParts);
281 281
 		$values = array_combine($queryParts, $params);
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
 			}
290 290
 
291 291
 			if ($builder->execute()) {
292
-				$fileId = (int)$this->connection->lastInsertId('*PREFIX*filecache');
292
+				$fileId = (int) $this->connection->lastInsertId('*PREFIX*filecache');
293 293
 				$this->eventDispatcher->dispatch(CacheInsertEvent::class, new CacheInsertEvent($this->storage, $file, $fileId));
294 294
 				return $fileId;
295 295
 			}
@@ -332,10 +332,10 @@  discard block
 block discarded – undo
332 332
 
333 333
 		// don't update if the data we try to set is the same as the one in the record
334 334
 		// some databases (Postgres) don't like superfluous updates
335
-		$sql = 'UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? ' .
336
-			'WHERE (' .
337
-			implode(' <> ? OR ', $queryParts) . ' <> ? OR ' .
338
-			implode(' IS NULL OR ', $queryParts) . ' IS NULL' .
335
+		$sql = 'UPDATE `*PREFIX*filecache` SET '.implode(' = ?, ', $queryParts).'=? '.
336
+			'WHERE ('.
337
+			implode(' <> ? OR ', $queryParts).' <> ? OR '.
338
+			implode(' IS NULL OR ', $queryParts).' IS NULL'.
339 339
 			') AND `fileid` = ? ';
340 340
 		$this->connection->executeQuery($sql, $params);
341 341
 
@@ -391,7 +391,7 @@  discard block
 block discarded – undo
391 391
 					}
392 392
 				}
393 393
 				$params[] = $value;
394
-				$queryParts[] = '`' . $name . '`';
394
+				$queryParts[] = '`'.$name.'`';
395 395
 			}
396 396
 		}
397 397
 		return array($queryParts, $params);
@@ -416,7 +416,7 @@  discard block
 block discarded – undo
416 416
 		$sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
417 417
 		$result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
418 418
 		if ($row = $result->fetch()) {
419
-			return (int)$row['fileid'];
419
+			return (int) $row['fileid'];
420 420
 		} else {
421 421
 			return -1;
422 422
 		}
@@ -433,7 +433,7 @@  discard block
 block discarded – undo
433 433
 			return -1;
434 434
 		} else {
435 435
 			$parent = $this->getParentPath($file);
436
-			return (int)$this->getId($parent);
436
+			return (int) $this->getId($parent);
437 437
 		}
438 438
 	}
439 439
 
@@ -479,7 +479,7 @@  discard block
 block discarded – undo
479 479
 	 */
480 480
 	private function getSubFolders($entry) {
481 481
 		$children = $this->getFolderContentsById($entry['fileid']);
482
-		return array_filter($children, function ($child) {
482
+		return array_filter($children, function($child) {
483 483
 			return $child['mimetype'] === 'httpd/unix-directory';
484 484
 		});
485 485
 	}
@@ -543,10 +543,10 @@  discard block
 block discarded – undo
543 543
 			list($targetStorageId, $targetPath) = $this->getMoveInfo($targetPath);
544 544
 
545 545
 			if (is_null($sourceStorageId) || $sourceStorageId === false) {
546
-				throw new \Exception('Invalid source storage id: ' . $sourceStorageId);
546
+				throw new \Exception('Invalid source storage id: '.$sourceStorageId);
547 547
 			}
548 548
 			if (is_null($targetStorageId) || $targetStorageId === false) {
549
-				throw new \Exception('Invalid target storage id: ' . $targetStorageId);
549
+				throw new \Exception('Invalid target storage id: '.$targetStorageId);
550 550
 			}
551 551
 
552 552
 			$this->connection->beginTransaction();
@@ -565,7 +565,7 @@  discard block
 block discarded – undo
565 565
 					->set('path_hash', $fun->md5($newPathFunction))
566 566
 					->set('path', $newPathFunction)
567 567
 					->where($query->expr()->eq('storage', $query->createNamedParameter($sourceStorageId, IQueryBuilder::PARAM_INT)))
568
-					->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($sourcePath) . '/%')));
568
+					->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($sourcePath).'/%')));
569 569
 
570 570
 				try {
571 571
 					$query->execute();
@@ -614,7 +614,7 @@  discard block
 block discarded – undo
614 614
 		$sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
615 615
 		$result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
616 616
 		if ($row = $result->fetch()) {
617
-			if ((int)$row['size'] === -1) {
617
+			if ((int) $row['size'] === -1) {
618 618
 				return self::SHALLOW;
619 619
 			} else {
620 620
 				return self::COMPLETE;
@@ -663,7 +663,7 @@  discard block
 block discarded – undo
663 663
 	private function searchResultToCacheEntries(Statement $result) {
664 664
 		$files = $result->fetchAll();
665 665
 
666
-		return array_map(function (array $data) {
666
+		return array_map(function(array $data) {
667 667
 			return self::cacheEntryFromData($data, $this->mimetypeLoader);
668 668
 		}, $files);
669 669
 	}
@@ -682,7 +682,7 @@  discard block
 block discarded – undo
682 682
 			$where = '`mimepart` = ?';
683 683
 		}
684 684
 		$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `storage_mtime`, `mtime`, `encrypted`, `etag`, `permissions`, `checksum`
685
-				FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?';
685
+				FROM `*PREFIX*filecache` WHERE ' . $where.' AND `storage` = ?';
686 686
 		$mimetype = $this->mimetypeLoader->getId($mimetype);
687 687
 		$result = $this->connection->executeQuery($sql, array($mimetype, $this->getNumericStorageId()));
688 688
 
@@ -758,7 +758,7 @@  discard block
 block discarded – undo
758 758
 			$sql = 'SELECT count(*)
759 759
 					FROM `*PREFIX*filecache` WHERE `parent` = ? AND size = -1';
760 760
 			$result = $this->connection->executeQuery($sql, [$fileId]);
761
-			return (int)$result->fetchColumn();
761
+			return (int) $result->fetchColumn();
762 762
 		}
763 763
 		return -1;
764 764
 	}
@@ -777,8 +777,8 @@  discard block
 block discarded – undo
777 777
 		}
778 778
 		if (isset($entry['mimetype']) && $entry['mimetype'] === 'httpd/unix-directory') {
779 779
 			$id = $entry['fileid'];
780
-			$sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2 ' .
781
-				'FROM `*PREFIX*filecache` ' .
780
+			$sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2 '.
781
+				'FROM `*PREFIX*filecache` '.
782 782
 				'WHERE `parent` = ? AND `storage` = ?';
783 783
 			$result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
784 784
 			if ($row = $result->fetch()) {
Please login to merge, or discard this patch.