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