Completed
Pull Request — master (#5460)
by Robin
15:25
created
lib/private/Files/ObjectStore/ObjectStoreStorage.php 2 patches
Indentation   +378 added lines, -378 removed lines patch added patch discarded remove patch
@@ -31,382 +31,382 @@
 block discarded – undo
31 31
 use OCP\Files\ObjectStore\IObjectStore;
32 32
 
33 33
 class ObjectStoreStorage extends \OC\Files\Storage\Common {
34
-	/**
35
-	 * @var \OCP\Files\ObjectStore\IObjectStore $objectStore
36
-	 */
37
-	protected $objectStore;
38
-	/**
39
-	 * @var string $id
40
-	 */
41
-	protected $id;
42
-	/**
43
-	 * @var \OC\User\User $user
44
-	 */
45
-	protected $user;
46
-
47
-	private $objectPrefix = 'urn:oid:';
48
-
49
-	private $logger;
50
-
51
-	public function __construct($params) {
52
-		if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
53
-			$this->objectStore = $params['objectstore'];
54
-		} else {
55
-			throw new \Exception('missing IObjectStore instance');
56
-		}
57
-		if (isset($params['storageid'])) {
58
-			$this->id = 'object::store:' . $params['storageid'];
59
-		} else {
60
-			$this->id = 'object::store:' . $this->objectStore->getStorageId();
61
-		}
62
-		if (isset($params['objectPrefix'])) {
63
-			$this->objectPrefix = $params['objectPrefix'];
64
-		}
65
-		//initialize cache with root directory in cache
66
-		if (!$this->is_dir('/')) {
67
-			$this->mkdir('/');
68
-		}
69
-
70
-		$this->logger = \OC::$server->getLogger();
71
-	}
72
-
73
-	public function mkdir($path) {
74
-		$path = $this->normalizePath($path);
75
-
76
-		if ($this->file_exists($path)) {
77
-			return false;
78
-		}
79
-
80
-		$mTime = time();
81
-		$data = [
82
-			'mimetype' => 'httpd/unix-directory',
83
-			'size' => 0,
84
-			'mtime' => $mTime,
85
-			'storage_mtime' => $mTime,
86
-			'permissions' => \OCP\Constants::PERMISSION_ALL,
87
-		];
88
-		if ($path === '') {
89
-			//create root on the fly
90
-			$data['etag'] = $this->getETag('');
91
-			$this->getCache()->put('', $data);
92
-			return true;
93
-		} else {
94
-			// if parent does not exist, create it
95
-			$parent = $this->normalizePath(dirname($path));
96
-			$parentType = $this->filetype($parent);
97
-			if ($parentType === false) {
98
-				if (!$this->mkdir($parent)) {
99
-					// something went wrong
100
-					return false;
101
-				}
102
-			} else if ($parentType === 'file') {
103
-				// parent is a file
104
-				return false;
105
-			}
106
-			// finally create the new dir
107
-			$mTime = time(); // update mtime
108
-			$data['mtime'] = $mTime;
109
-			$data['storage_mtime'] = $mTime;
110
-			$data['etag'] = $this->getETag($path);
111
-			$this->getCache()->put($path, $data);
112
-			return true;
113
-		}
114
-	}
115
-
116
-	/**
117
-	 * @param string $path
118
-	 * @return string
119
-	 */
120
-	private function normalizePath($path) {
121
-		$path = trim($path, '/');
122
-		//FIXME why do we sometimes get a path like 'files//username'?
123
-		$path = str_replace('//', '/', $path);
124
-
125
-		// dirname('/folder') returns '.' but internally (in the cache) we store the root as ''
126
-		if (!$path || $path === '.') {
127
-			$path = '';
128
-		}
129
-
130
-		return $path;
131
-	}
132
-
133
-	/**
134
-	 * Object Stores use a NoopScanner because metadata is directly stored in
135
-	 * the file cache and cannot really scan the filesystem. The storage passed in is not used anywhere.
136
-	 *
137
-	 * @param string $path
138
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
139
-	 * @return \OC\Files\ObjectStore\NoopScanner
140
-	 */
141
-	public function getScanner($path = '', $storage = null) {
142
-		if (!$storage) {
143
-			$storage = $this;
144
-		}
145
-		if (!isset($this->scanner)) {
146
-			$this->scanner = new NoopScanner($storage);
147
-		}
148
-		return $this->scanner;
149
-	}
150
-
151
-	public function getId() {
152
-		return $this->id;
153
-	}
154
-
155
-	public function rmdir($path) {
156
-		$path = $this->normalizePath($path);
157
-
158
-		if (!$this->is_dir($path)) {
159
-			return false;
160
-		}
161
-
162
-		$this->rmObjects($path);
163
-
164
-		$this->getCache()->remove($path);
165
-
166
-		return true;
167
-	}
168
-
169
-	private function rmObjects($path) {
170
-		$children = $this->getCache()->getFolderContents($path);
171
-		foreach ($children as $child) {
172
-			if ($child['mimetype'] === 'httpd/unix-directory') {
173
-				$this->rmObjects($child['path']);
174
-			} else {
175
-				$this->unlink($child['path']);
176
-			}
177
-		}
178
-	}
179
-
180
-	public function unlink($path) {
181
-		$path = $this->normalizePath($path);
182
-		$stat = $this->stat($path);
183
-
184
-		if ($stat && isset($stat['fileid'])) {
185
-			if ($stat['mimetype'] === 'httpd/unix-directory') {
186
-				return $this->rmdir($path);
187
-			}
188
-			try {
189
-				$this->objectStore->deleteObject($this->getURN($stat['fileid']));
190
-			} catch (\Exception $ex) {
191
-				if ($ex->getCode() !== 404) {
192
-					$this->logger->error('Could not delete object ' . $this->getURN($stat['fileid']) . ' for ' . $path, ['app' => 'objectstore']);
193
-					$this->logger->logException($ex);
194
-					return false;
195
-				} else {
196
-					//removing from cache is ok as it does not exist in the objectstore anyway
197
-				}
198
-			}
199
-			$this->getCache()->remove($path);
200
-			return true;
201
-		}
202
-		return false;
203
-	}
204
-
205
-	public function stat($path) {
206
-		$path = $this->normalizePath($path);
207
-		$cacheEntry = $this->getCache()->get($path);
208
-		if ($cacheEntry instanceof CacheEntry) {
209
-			return $cacheEntry->getData();
210
-		} else {
211
-			return false;
212
-		}
213
-	}
214
-
215
-	/**
216
-	 * Override this method if you need a different unique resource identifier for your object storage implementation.
217
-	 * The default implementations just appends the fileId to 'urn:oid:'. Make sure the URN is unique over all users.
218
-	 * You may need a mapping table to store your URN if it cannot be generated from the fileid.
219
-	 *
220
-	 * @param int $fileId the fileid
221
-	 * @return null|string the unified resource name used to identify the object
222
-	 */
223
-	protected function getURN($fileId) {
224
-		if (is_numeric($fileId)) {
225
-			return $this->objectPrefix . $fileId;
226
-		}
227
-		return null;
228
-	}
229
-
230
-	public function opendir($path) {
231
-		$path = $this->normalizePath($path);
232
-
233
-		try {
234
-			$files = array();
235
-			$folderContents = $this->getCache()->getFolderContents($path);
236
-			foreach ($folderContents as $file) {
237
-				$files[] = $file['name'];
238
-			}
239
-
240
-			return IteratorDirectory::wrap($files);
241
-		} catch (\Exception $e) {
242
-			$this->logger->logException($e);
243
-			return false;
244
-		}
245
-	}
246
-
247
-	public function filetype($path) {
248
-		$path = $this->normalizePath($path);
249
-		$stat = $this->stat($path);
250
-		if ($stat) {
251
-			if ($stat['mimetype'] === 'httpd/unix-directory') {
252
-				return 'dir';
253
-			}
254
-			return 'file';
255
-		} else {
256
-			return false;
257
-		}
258
-	}
259
-
260
-	public function fopen($path, $mode) {
261
-		$path = $this->normalizePath($path);
262
-
263
-		switch ($mode) {
264
-			case 'r':
265
-			case 'rb':
266
-				$stat = $this->stat($path);
267
-				if (is_array($stat)) {
268
-					try {
269
-						return $this->objectStore->readObject($this->getURN($stat['fileid']));
270
-					} catch (\Exception $ex) {
271
-						$this->logger->error('Count not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path, ['app' => 'objectstore']);
272
-						$this->logger->logException($ex);
273
-						return false;
274
-					}
275
-				} else {
276
-					return false;
277
-				}
278
-			case 'w':
279
-			case 'wb':
280
-			case 'a':
281
-			case 'ab':
282
-			case 'r+':
283
-			case 'w+':
284
-			case 'wb+':
285
-			case 'a+':
286
-			case 'x':
287
-			case 'x+':
288
-			case 'c':
289
-			case 'c+':
290
-				if (strrpos($path, '.') !== false) {
291
-					$ext = substr($path, strrpos($path, '.'));
292
-				} else {
293
-					$ext = '';
294
-				}
295
-				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
296
-				if ($this->file_exists($path)) {
297
-					$source = $this->fopen($path, 'r');
298
-					file_put_contents($tmpFile, $source);
299
-				}
300
-				$handle = fopen($tmpFile, $mode);
301
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
302
-					$this->writeBack($tmpFile, $path);
303
-				});
304
-		}
305
-		return false;
306
-	}
307
-
308
-	public function file_exists($path) {
309
-		$path = $this->normalizePath($path);
310
-		return (bool)$this->stat($path);
311
-	}
312
-
313
-	public function rename($source, $target) {
314
-		$source = $this->normalizePath($source);
315
-		$target = $this->normalizePath($target);
316
-		$this->remove($target);
317
-		$this->getCache()->move($source, $target);
318
-		$this->touch(dirname($target));
319
-		return true;
320
-	}
321
-
322
-	public function getMimeType($path) {
323
-		$path = $this->normalizePath($path);
324
-		$stat = $this->stat($path);
325
-		if (is_array($stat)) {
326
-			return $stat['mimetype'];
327
-		} else {
328
-			return false;
329
-		}
330
-	}
331
-
332
-	public function touch($path, $mtime = null) {
333
-		if (is_null($mtime)) {
334
-			$mtime = time();
335
-		}
336
-
337
-		$path = $this->normalizePath($path);
338
-		$dirName = dirname($path);
339
-		$parentExists = $this->is_dir($dirName);
340
-		if (!$parentExists) {
341
-			return false;
342
-		}
343
-
344
-		$stat = $this->stat($path);
345
-		if (is_array($stat)) {
346
-			// update existing mtime in db
347
-			$stat['mtime'] = $mtime;
348
-			$this->getCache()->update($stat['fileid'], $stat);
349
-		} else {
350
-			$mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
351
-			// create new file
352
-			$stat = array(
353
-				'etag' => $this->getETag($path),
354
-				'mimetype' => $mimeType,
355
-				'size' => 0,
356
-				'mtime' => $mtime,
357
-				'storage_mtime' => $mtime,
358
-				'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
359
-			);
360
-			$fileId = $this->getCache()->put($path, $stat);
361
-			try {
362
-				//read an empty file from memory
363
-				$this->objectStore->writeObject($this->getURN($fileId), fopen('php://memory', 'r'));
364
-			} catch (\Exception $ex) {
365
-				$this->getCache()->remove($path);
366
-				$this->logger->error('Could not create object ' . $this->getURN($fileId) . ' for ' . $path, ['app' => 'objectstore']);
367
-				$this->logger->logException($ex);
368
-				return false;
369
-			}
370
-		}
371
-		return true;
372
-	}
373
-
374
-	public function writeBack($tmpFile, $path) {
375
-		$stat = $this->stat($path);
376
-		if (empty($stat)) {
377
-			// create new file
378
-			$stat = array(
379
-				'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
380
-			);
381
-		}
382
-		// update stat with new data
383
-		$mTime = time();
384
-		$stat['size'] = filesize($tmpFile);
385
-		$stat['mtime'] = $mTime;
386
-		$stat['storage_mtime'] = $mTime;
387
-		$stat['mimetype'] = \OC::$server->getMimeTypeDetector()->detect($tmpFile);
388
-		$stat['etag'] = $this->getETag($path);
389
-
390
-		$fileId = $this->getCache()->put($path, $stat);
391
-		try {
392
-			//upload to object storage
393
-			$this->objectStore->writeObject($this->getURN($fileId), fopen($tmpFile, 'r'));
394
-		} catch (\Exception $ex) {
395
-			$this->getCache()->remove($path);
396
-			$this->logger->error('Could not create object ' . $this->getURN($fileId) . ' for ' . $path, ['app' => 'objectstore']);
397
-			$this->logger->logException($ex);
398
-			throw $ex; // make this bubble up
399
-		}
400
-	}
401
-
402
-	/**
403
-	 * external changes are not supported, exclusive access to the object storage is assumed
404
-	 *
405
-	 * @param string $path
406
-	 * @param int $time
407
-	 * @return false
408
-	 */
409
-	public function hasUpdated($path, $time) {
410
-		return false;
411
-	}
34
+    /**
35
+     * @var \OCP\Files\ObjectStore\IObjectStore $objectStore
36
+     */
37
+    protected $objectStore;
38
+    /**
39
+     * @var string $id
40
+     */
41
+    protected $id;
42
+    /**
43
+     * @var \OC\User\User $user
44
+     */
45
+    protected $user;
46
+
47
+    private $objectPrefix = 'urn:oid:';
48
+
49
+    private $logger;
50
+
51
+    public function __construct($params) {
52
+        if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
53
+            $this->objectStore = $params['objectstore'];
54
+        } else {
55
+            throw new \Exception('missing IObjectStore instance');
56
+        }
57
+        if (isset($params['storageid'])) {
58
+            $this->id = 'object::store:' . $params['storageid'];
59
+        } else {
60
+            $this->id = 'object::store:' . $this->objectStore->getStorageId();
61
+        }
62
+        if (isset($params['objectPrefix'])) {
63
+            $this->objectPrefix = $params['objectPrefix'];
64
+        }
65
+        //initialize cache with root directory in cache
66
+        if (!$this->is_dir('/')) {
67
+            $this->mkdir('/');
68
+        }
69
+
70
+        $this->logger = \OC::$server->getLogger();
71
+    }
72
+
73
+    public function mkdir($path) {
74
+        $path = $this->normalizePath($path);
75
+
76
+        if ($this->file_exists($path)) {
77
+            return false;
78
+        }
79
+
80
+        $mTime = time();
81
+        $data = [
82
+            'mimetype' => 'httpd/unix-directory',
83
+            'size' => 0,
84
+            'mtime' => $mTime,
85
+            'storage_mtime' => $mTime,
86
+            'permissions' => \OCP\Constants::PERMISSION_ALL,
87
+        ];
88
+        if ($path === '') {
89
+            //create root on the fly
90
+            $data['etag'] = $this->getETag('');
91
+            $this->getCache()->put('', $data);
92
+            return true;
93
+        } else {
94
+            // if parent does not exist, create it
95
+            $parent = $this->normalizePath(dirname($path));
96
+            $parentType = $this->filetype($parent);
97
+            if ($parentType === false) {
98
+                if (!$this->mkdir($parent)) {
99
+                    // something went wrong
100
+                    return false;
101
+                }
102
+            } else if ($parentType === 'file') {
103
+                // parent is a file
104
+                return false;
105
+            }
106
+            // finally create the new dir
107
+            $mTime = time(); // update mtime
108
+            $data['mtime'] = $mTime;
109
+            $data['storage_mtime'] = $mTime;
110
+            $data['etag'] = $this->getETag($path);
111
+            $this->getCache()->put($path, $data);
112
+            return true;
113
+        }
114
+    }
115
+
116
+    /**
117
+     * @param string $path
118
+     * @return string
119
+     */
120
+    private function normalizePath($path) {
121
+        $path = trim($path, '/');
122
+        //FIXME why do we sometimes get a path like 'files//username'?
123
+        $path = str_replace('//', '/', $path);
124
+
125
+        // dirname('/folder') returns '.' but internally (in the cache) we store the root as ''
126
+        if (!$path || $path === '.') {
127
+            $path = '';
128
+        }
129
+
130
+        return $path;
131
+    }
132
+
133
+    /**
134
+     * Object Stores use a NoopScanner because metadata is directly stored in
135
+     * the file cache and cannot really scan the filesystem. The storage passed in is not used anywhere.
136
+     *
137
+     * @param string $path
138
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
139
+     * @return \OC\Files\ObjectStore\NoopScanner
140
+     */
141
+    public function getScanner($path = '', $storage = null) {
142
+        if (!$storage) {
143
+            $storage = $this;
144
+        }
145
+        if (!isset($this->scanner)) {
146
+            $this->scanner = new NoopScanner($storage);
147
+        }
148
+        return $this->scanner;
149
+    }
150
+
151
+    public function getId() {
152
+        return $this->id;
153
+    }
154
+
155
+    public function rmdir($path) {
156
+        $path = $this->normalizePath($path);
157
+
158
+        if (!$this->is_dir($path)) {
159
+            return false;
160
+        }
161
+
162
+        $this->rmObjects($path);
163
+
164
+        $this->getCache()->remove($path);
165
+
166
+        return true;
167
+    }
168
+
169
+    private function rmObjects($path) {
170
+        $children = $this->getCache()->getFolderContents($path);
171
+        foreach ($children as $child) {
172
+            if ($child['mimetype'] === 'httpd/unix-directory') {
173
+                $this->rmObjects($child['path']);
174
+            } else {
175
+                $this->unlink($child['path']);
176
+            }
177
+        }
178
+    }
179
+
180
+    public function unlink($path) {
181
+        $path = $this->normalizePath($path);
182
+        $stat = $this->stat($path);
183
+
184
+        if ($stat && isset($stat['fileid'])) {
185
+            if ($stat['mimetype'] === 'httpd/unix-directory') {
186
+                return $this->rmdir($path);
187
+            }
188
+            try {
189
+                $this->objectStore->deleteObject($this->getURN($stat['fileid']));
190
+            } catch (\Exception $ex) {
191
+                if ($ex->getCode() !== 404) {
192
+                    $this->logger->error('Could not delete object ' . $this->getURN($stat['fileid']) . ' for ' . $path, ['app' => 'objectstore']);
193
+                    $this->logger->logException($ex);
194
+                    return false;
195
+                } else {
196
+                    //removing from cache is ok as it does not exist in the objectstore anyway
197
+                }
198
+            }
199
+            $this->getCache()->remove($path);
200
+            return true;
201
+        }
202
+        return false;
203
+    }
204
+
205
+    public function stat($path) {
206
+        $path = $this->normalizePath($path);
207
+        $cacheEntry = $this->getCache()->get($path);
208
+        if ($cacheEntry instanceof CacheEntry) {
209
+            return $cacheEntry->getData();
210
+        } else {
211
+            return false;
212
+        }
213
+    }
214
+
215
+    /**
216
+     * Override this method if you need a different unique resource identifier for your object storage implementation.
217
+     * The default implementations just appends the fileId to 'urn:oid:'. Make sure the URN is unique over all users.
218
+     * You may need a mapping table to store your URN if it cannot be generated from the fileid.
219
+     *
220
+     * @param int $fileId the fileid
221
+     * @return null|string the unified resource name used to identify the object
222
+     */
223
+    protected function getURN($fileId) {
224
+        if (is_numeric($fileId)) {
225
+            return $this->objectPrefix . $fileId;
226
+        }
227
+        return null;
228
+    }
229
+
230
+    public function opendir($path) {
231
+        $path = $this->normalizePath($path);
232
+
233
+        try {
234
+            $files = array();
235
+            $folderContents = $this->getCache()->getFolderContents($path);
236
+            foreach ($folderContents as $file) {
237
+                $files[] = $file['name'];
238
+            }
239
+
240
+            return IteratorDirectory::wrap($files);
241
+        } catch (\Exception $e) {
242
+            $this->logger->logException($e);
243
+            return false;
244
+        }
245
+    }
246
+
247
+    public function filetype($path) {
248
+        $path = $this->normalizePath($path);
249
+        $stat = $this->stat($path);
250
+        if ($stat) {
251
+            if ($stat['mimetype'] === 'httpd/unix-directory') {
252
+                return 'dir';
253
+            }
254
+            return 'file';
255
+        } else {
256
+            return false;
257
+        }
258
+    }
259
+
260
+    public function fopen($path, $mode) {
261
+        $path = $this->normalizePath($path);
262
+
263
+        switch ($mode) {
264
+            case 'r':
265
+            case 'rb':
266
+                $stat = $this->stat($path);
267
+                if (is_array($stat)) {
268
+                    try {
269
+                        return $this->objectStore->readObject($this->getURN($stat['fileid']));
270
+                    } catch (\Exception $ex) {
271
+                        $this->logger->error('Count not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path, ['app' => 'objectstore']);
272
+                        $this->logger->logException($ex);
273
+                        return false;
274
+                    }
275
+                } else {
276
+                    return false;
277
+                }
278
+            case 'w':
279
+            case 'wb':
280
+            case 'a':
281
+            case 'ab':
282
+            case 'r+':
283
+            case 'w+':
284
+            case 'wb+':
285
+            case 'a+':
286
+            case 'x':
287
+            case 'x+':
288
+            case 'c':
289
+            case 'c+':
290
+                if (strrpos($path, '.') !== false) {
291
+                    $ext = substr($path, strrpos($path, '.'));
292
+                } else {
293
+                    $ext = '';
294
+                }
295
+                $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
296
+                if ($this->file_exists($path)) {
297
+                    $source = $this->fopen($path, 'r');
298
+                    file_put_contents($tmpFile, $source);
299
+                }
300
+                $handle = fopen($tmpFile, $mode);
301
+                return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
302
+                    $this->writeBack($tmpFile, $path);
303
+                });
304
+        }
305
+        return false;
306
+    }
307
+
308
+    public function file_exists($path) {
309
+        $path = $this->normalizePath($path);
310
+        return (bool)$this->stat($path);
311
+    }
312
+
313
+    public function rename($source, $target) {
314
+        $source = $this->normalizePath($source);
315
+        $target = $this->normalizePath($target);
316
+        $this->remove($target);
317
+        $this->getCache()->move($source, $target);
318
+        $this->touch(dirname($target));
319
+        return true;
320
+    }
321
+
322
+    public function getMimeType($path) {
323
+        $path = $this->normalizePath($path);
324
+        $stat = $this->stat($path);
325
+        if (is_array($stat)) {
326
+            return $stat['mimetype'];
327
+        } else {
328
+            return false;
329
+        }
330
+    }
331
+
332
+    public function touch($path, $mtime = null) {
333
+        if (is_null($mtime)) {
334
+            $mtime = time();
335
+        }
336
+
337
+        $path = $this->normalizePath($path);
338
+        $dirName = dirname($path);
339
+        $parentExists = $this->is_dir($dirName);
340
+        if (!$parentExists) {
341
+            return false;
342
+        }
343
+
344
+        $stat = $this->stat($path);
345
+        if (is_array($stat)) {
346
+            // update existing mtime in db
347
+            $stat['mtime'] = $mtime;
348
+            $this->getCache()->update($stat['fileid'], $stat);
349
+        } else {
350
+            $mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
351
+            // create new file
352
+            $stat = array(
353
+                'etag' => $this->getETag($path),
354
+                'mimetype' => $mimeType,
355
+                'size' => 0,
356
+                'mtime' => $mtime,
357
+                'storage_mtime' => $mtime,
358
+                'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
359
+            );
360
+            $fileId = $this->getCache()->put($path, $stat);
361
+            try {
362
+                //read an empty file from memory
363
+                $this->objectStore->writeObject($this->getURN($fileId), fopen('php://memory', 'r'));
364
+            } catch (\Exception $ex) {
365
+                $this->getCache()->remove($path);
366
+                $this->logger->error('Could not create object ' . $this->getURN($fileId) . ' for ' . $path, ['app' => 'objectstore']);
367
+                $this->logger->logException($ex);
368
+                return false;
369
+            }
370
+        }
371
+        return true;
372
+    }
373
+
374
+    public function writeBack($tmpFile, $path) {
375
+        $stat = $this->stat($path);
376
+        if (empty($stat)) {
377
+            // create new file
378
+            $stat = array(
379
+                'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
380
+            );
381
+        }
382
+        // update stat with new data
383
+        $mTime = time();
384
+        $stat['size'] = filesize($tmpFile);
385
+        $stat['mtime'] = $mTime;
386
+        $stat['storage_mtime'] = $mTime;
387
+        $stat['mimetype'] = \OC::$server->getMimeTypeDetector()->detect($tmpFile);
388
+        $stat['etag'] = $this->getETag($path);
389
+
390
+        $fileId = $this->getCache()->put($path, $stat);
391
+        try {
392
+            //upload to object storage
393
+            $this->objectStore->writeObject($this->getURN($fileId), fopen($tmpFile, 'r'));
394
+        } catch (\Exception $ex) {
395
+            $this->getCache()->remove($path);
396
+            $this->logger->error('Could not create object ' . $this->getURN($fileId) . ' for ' . $path, ['app' => 'objectstore']);
397
+            $this->logger->logException($ex);
398
+            throw $ex; // make this bubble up
399
+        }
400
+    }
401
+
402
+    /**
403
+     * external changes are not supported, exclusive access to the object storage is assumed
404
+     *
405
+     * @param string $path
406
+     * @param int $time
407
+     * @return false
408
+     */
409
+    public function hasUpdated($path, $time) {
410
+        return false;
411
+    }
412 412
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -55,9 +55,9 @@  discard block
 block discarded – undo
55 55
 			throw new \Exception('missing IObjectStore instance');
56 56
 		}
57 57
 		if (isset($params['storageid'])) {
58
-			$this->id = 'object::store:' . $params['storageid'];
58
+			$this->id = 'object::store:'.$params['storageid'];
59 59
 		} else {
60
-			$this->id = 'object::store:' . $this->objectStore->getStorageId();
60
+			$this->id = 'object::store:'.$this->objectStore->getStorageId();
61 61
 		}
62 62
 		if (isset($params['objectPrefix'])) {
63 63
 			$this->objectPrefix = $params['objectPrefix'];
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
 				$this->objectStore->deleteObject($this->getURN($stat['fileid']));
190 190
 			} catch (\Exception $ex) {
191 191
 				if ($ex->getCode() !== 404) {
192
-					$this->logger->error('Could not delete object ' . $this->getURN($stat['fileid']) . ' for ' . $path, ['app' => 'objectstore']);
192
+					$this->logger->error('Could not delete object '.$this->getURN($stat['fileid']).' for '.$path, ['app' => 'objectstore']);
193 193
 					$this->logger->logException($ex);
194 194
 					return false;
195 195
 				} else {
@@ -222,7 +222,7 @@  discard block
 block discarded – undo
222 222
 	 */
223 223
 	protected function getURN($fileId) {
224 224
 		if (is_numeric($fileId)) {
225
-			return $this->objectPrefix . $fileId;
225
+			return $this->objectPrefix.$fileId;
226 226
 		}
227 227
 		return null;
228 228
 	}
@@ -268,7 +268,7 @@  discard block
 block discarded – undo
268 268
 					try {
269 269
 						return $this->objectStore->readObject($this->getURN($stat['fileid']));
270 270
 					} catch (\Exception $ex) {
271
-						$this->logger->error('Count not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path, ['app' => 'objectstore']);
271
+						$this->logger->error('Count not get object '.$this->getURN($stat['fileid']).' for file '.$path, ['app' => 'objectstore']);
272 272
 						$this->logger->logException($ex);
273 273
 						return false;
274 274
 					}
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
 					file_put_contents($tmpFile, $source);
299 299
 				}
300 300
 				$handle = fopen($tmpFile, $mode);
301
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
301
+				return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) {
302 302
 					$this->writeBack($tmpFile, $path);
303 303
 				});
304 304
 		}
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
 
308 308
 	public function file_exists($path) {
309 309
 		$path = $this->normalizePath($path);
310
-		return (bool)$this->stat($path);
310
+		return (bool) $this->stat($path);
311 311
 	}
312 312
 
313 313
 	public function rename($source, $target) {
@@ -363,7 +363,7 @@  discard block
 block discarded – undo
363 363
 				$this->objectStore->writeObject($this->getURN($fileId), fopen('php://memory', 'r'));
364 364
 			} catch (\Exception $ex) {
365 365
 				$this->getCache()->remove($path);
366
-				$this->logger->error('Could not create object ' . $this->getURN($fileId) . ' for ' . $path, ['app' => 'objectstore']);
366
+				$this->logger->error('Could not create object '.$this->getURN($fileId).' for '.$path, ['app' => 'objectstore']);
367 367
 				$this->logger->logException($ex);
368 368
 				return false;
369 369
 			}
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
 			$this->objectStore->writeObject($this->getURN($fileId), fopen($tmpFile, 'r'));
394 394
 		} catch (\Exception $ex) {
395 395
 			$this->getCache()->remove($path);
396
-			$this->logger->error('Could not create object ' . $this->getURN($fileId) . ' for ' . $path, ['app' => 'objectstore']);
396
+			$this->logger->error('Could not create object '.$this->getURN($fileId).' for '.$path, ['app' => 'objectstore']);
397 397
 			$this->logger->logException($ex);
398 398
 			throw $ex; // make this bubble up
399 399
 		}
Please login to merge, or discard this patch.