Passed
Push — master ( dcf686...9e1ec0 )
by Morris
11:38
created
lib/private/Lock/DBLockingProvider.php 2 patches
Indentation   +258 added lines, -258 removed lines patch added patch discarded remove patch
@@ -39,286 +39,286 @@
 block discarded – undo
39 39
  * Locking provider that stores the locks in the database
40 40
  */
41 41
 class DBLockingProvider extends AbstractLockingProvider {
42
-	/**
43
-	 * @var \OCP\IDBConnection
44
-	 */
45
-	private $connection;
42
+    /**
43
+     * @var \OCP\IDBConnection
44
+     */
45
+    private $connection;
46 46
 
47
-	/**
48
-	 * @var \OCP\ILogger
49
-	 */
50
-	private $logger;
47
+    /**
48
+     * @var \OCP\ILogger
49
+     */
50
+    private $logger;
51 51
 
52
-	/**
53
-	 * @var \OCP\AppFramework\Utility\ITimeFactory
54
-	 */
55
-	private $timeFactory;
52
+    /**
53
+     * @var \OCP\AppFramework\Utility\ITimeFactory
54
+     */
55
+    private $timeFactory;
56 56
 
57
-	private $sharedLocks = [];
57
+    private $sharedLocks = [];
58 58
 
59
-	/**
60
-	 * @var bool
61
-	 */
62
-	private $cacheSharedLocks;
59
+    /**
60
+     * @var bool
61
+     */
62
+    private $cacheSharedLocks;
63 63
 
64
-	/**
65
-	 * Check if we have an open shared lock for a path
66
-	 *
67
-	 * @param string $path
68
-	 * @return bool
69
-	 */
70
-	protected function isLocallyLocked(string $path): bool {
71
-		return isset($this->sharedLocks[$path]) && $this->sharedLocks[$path];
72
-	}
64
+    /**
65
+     * Check if we have an open shared lock for a path
66
+     *
67
+     * @param string $path
68
+     * @return bool
69
+     */
70
+    protected function isLocallyLocked(string $path): bool {
71
+        return isset($this->sharedLocks[$path]) && $this->sharedLocks[$path];
72
+    }
73 73
 
74
-	/**
75
-	 * Mark a locally acquired lock
76
-	 *
77
-	 * @param string $path
78
-	 * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
79
-	 */
80
-	protected function markAcquire(string $path, int $type) {
81
-		parent::markAcquire($path, $type);
82
-		if ($this->cacheSharedLocks) {
83
-			if ($type === self::LOCK_SHARED) {
84
-				$this->sharedLocks[$path] = true;
85
-			}
86
-		}
87
-	}
74
+    /**
75
+     * Mark a locally acquired lock
76
+     *
77
+     * @param string $path
78
+     * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
79
+     */
80
+    protected function markAcquire(string $path, int $type) {
81
+        parent::markAcquire($path, $type);
82
+        if ($this->cacheSharedLocks) {
83
+            if ($type === self::LOCK_SHARED) {
84
+                $this->sharedLocks[$path] = true;
85
+            }
86
+        }
87
+    }
88 88
 
89
-	/**
90
-	 * Change the type of an existing tracked lock
91
-	 *
92
-	 * @param string $path
93
-	 * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
94
-	 */
95
-	protected function markChange(string $path, int $targetType) {
96
-		parent::markChange($path, $targetType);
97
-		if ($this->cacheSharedLocks) {
98
-			if ($targetType === self::LOCK_SHARED) {
99
-				$this->sharedLocks[$path] = true;
100
-			} else if ($targetType === self::LOCK_EXCLUSIVE) {
101
-				$this->sharedLocks[$path] = false;
102
-			}
103
-		}
104
-	}
89
+    /**
90
+     * Change the type of an existing tracked lock
91
+     *
92
+     * @param string $path
93
+     * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
94
+     */
95
+    protected function markChange(string $path, int $targetType) {
96
+        parent::markChange($path, $targetType);
97
+        if ($this->cacheSharedLocks) {
98
+            if ($targetType === self::LOCK_SHARED) {
99
+                $this->sharedLocks[$path] = true;
100
+            } else if ($targetType === self::LOCK_EXCLUSIVE) {
101
+                $this->sharedLocks[$path] = false;
102
+            }
103
+        }
104
+    }
105 105
 
106
-	/**
107
-	 * @param \OCP\IDBConnection $connection
108
-	 * @param \OCP\ILogger $logger
109
-	 * @param \OCP\AppFramework\Utility\ITimeFactory $timeFactory
110
-	 * @param int $ttl
111
-	 * @param bool $cacheSharedLocks
112
-	 */
113
-	public function __construct(
114
-		IDBConnection $connection,
115
-		ILogger $logger,
116
-		ITimeFactory $timeFactory,
117
-		int $ttl = 3600,
118
-		$cacheSharedLocks = true
119
-	) {
120
-		$this->connection = $connection;
121
-		$this->logger = $logger;
122
-		$this->timeFactory = $timeFactory;
123
-		$this->ttl = $ttl;
124
-		$this->cacheSharedLocks = $cacheSharedLocks;
125
-	}
106
+    /**
107
+     * @param \OCP\IDBConnection $connection
108
+     * @param \OCP\ILogger $logger
109
+     * @param \OCP\AppFramework\Utility\ITimeFactory $timeFactory
110
+     * @param int $ttl
111
+     * @param bool $cacheSharedLocks
112
+     */
113
+    public function __construct(
114
+        IDBConnection $connection,
115
+        ILogger $logger,
116
+        ITimeFactory $timeFactory,
117
+        int $ttl = 3600,
118
+        $cacheSharedLocks = true
119
+    ) {
120
+        $this->connection = $connection;
121
+        $this->logger = $logger;
122
+        $this->timeFactory = $timeFactory;
123
+        $this->ttl = $ttl;
124
+        $this->cacheSharedLocks = $cacheSharedLocks;
125
+    }
126 126
 
127
-	/**
128
-	 * Insert a file locking row if it does not exists.
129
-	 *
130
-	 * @param string $path
131
-	 * @param int $lock
132
-	 * @return int number of inserted rows
133
-	 */
127
+    /**
128
+     * Insert a file locking row if it does not exists.
129
+     *
130
+     * @param string $path
131
+     * @param int $lock
132
+     * @return int number of inserted rows
133
+     */
134 134
 
135
-	protected function initLockField(string $path, int $lock = 0): int {
136
-		$expire = $this->getExpireTime();
135
+    protected function initLockField(string $path, int $lock = 0): int {
136
+        $expire = $this->getExpireTime();
137 137
 
138
-		try {
139
-			$builder = $this->connection->getQueryBuilder();
140
-			return $builder->insert('file_locks')
141
-				->setValue('key', $builder->createNamedParameter($path))
142
-				->setValue('lock', $builder->createNamedParameter($lock))
143
-				->setValue('ttl', $builder->createNamedParameter($expire))
144
-				->execute();
145
-		} catch(UniqueConstraintViolationException $e) {
146
-			return 0;
147
-		}
148
-	}
138
+        try {
139
+            $builder = $this->connection->getQueryBuilder();
140
+            return $builder->insert('file_locks')
141
+                ->setValue('key', $builder->createNamedParameter($path))
142
+                ->setValue('lock', $builder->createNamedParameter($lock))
143
+                ->setValue('ttl', $builder->createNamedParameter($expire))
144
+                ->execute();
145
+        } catch(UniqueConstraintViolationException $e) {
146
+            return 0;
147
+        }
148
+    }
149 149
 
150
-	/**
151
-	 * @return int
152
-	 */
153
-	protected function getExpireTime(): int {
154
-		return $this->timeFactory->getTime() + $this->ttl;
155
-	}
150
+    /**
151
+     * @return int
152
+     */
153
+    protected function getExpireTime(): int {
154
+        return $this->timeFactory->getTime() + $this->ttl;
155
+    }
156 156
 
157
-	/**
158
-	 * @param string $path
159
-	 * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
160
-	 * @return bool
161
-	 */
162
-	public function isLocked(string $path, int $type): bool {
163
-		if ($this->hasAcquiredLock($path, $type)) {
164
-			return true;
165
-		}
166
-		$query = $this->connection->prepare('SELECT `lock` from `*PREFIX*file_locks` WHERE `key` = ?');
167
-		$query->execute([$path]);
168
-		$lockValue = (int)$query->fetchColumn();
169
-		if ($type === self::LOCK_SHARED) {
170
-			if ($this->isLocallyLocked($path)) {
171
-				// if we have a shared lock we kept open locally but it's released we always have at least 1 shared lock in the db
172
-				return $lockValue > 1;
173
-			} else {
174
-				return $lockValue > 0;
175
-			}
176
-		} else if ($type === self::LOCK_EXCLUSIVE) {
177
-			return $lockValue === -1;
178
-		} else {
179
-			return false;
180
-		}
181
-	}
157
+    /**
158
+     * @param string $path
159
+     * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
160
+     * @return bool
161
+     */
162
+    public function isLocked(string $path, int $type): bool {
163
+        if ($this->hasAcquiredLock($path, $type)) {
164
+            return true;
165
+        }
166
+        $query = $this->connection->prepare('SELECT `lock` from `*PREFIX*file_locks` WHERE `key` = ?');
167
+        $query->execute([$path]);
168
+        $lockValue = (int)$query->fetchColumn();
169
+        if ($type === self::LOCK_SHARED) {
170
+            if ($this->isLocallyLocked($path)) {
171
+                // if we have a shared lock we kept open locally but it's released we always have at least 1 shared lock in the db
172
+                return $lockValue > 1;
173
+            } else {
174
+                return $lockValue > 0;
175
+            }
176
+        } else if ($type === self::LOCK_EXCLUSIVE) {
177
+            return $lockValue === -1;
178
+        } else {
179
+            return false;
180
+        }
181
+    }
182 182
 
183
-	/**
184
-	 * @param string $path
185
-	 * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
186
-	 * @throws \OCP\Lock\LockedException
187
-	 */
188
-	public function acquireLock(string $path, int $type) {
189
-		$expire = $this->getExpireTime();
190
-		if ($type === self::LOCK_SHARED) {
191
-			if (!$this->isLocallyLocked($path)) {
192
-				$result = $this->initLockField($path, 1);
193
-				if ($result <= 0) {
194
-					$result = $this->connection->executeUpdate(
195
-						'UPDATE `*PREFIX*file_locks` SET `lock` = `lock` + 1, `ttl` = ? WHERE `key` = ? AND `lock` >= 0',
196
-						[$expire, $path]
197
-					);
198
-				}
199
-			} else {
200
-				$result = 1;
201
-			}
202
-		} else {
203
-			$existing = 0;
204
-			if ($this->hasAcquiredLock($path, ILockingProvider::LOCK_SHARED) === false && $this->isLocallyLocked($path)) {
205
-				$existing = 1;
206
-			}
207
-			$result = $this->initLockField($path, -1);
208
-			if ($result <= 0) {
209
-				$result = $this->connection->executeUpdate(
210
-					'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = ?',
211
-					[$expire, $path, $existing]
212
-				);
213
-			}
214
-		}
215
-		if ($result !== 1) {
216
-			throw new LockedException($path);
217
-		}
218
-		$this->markAcquire($path, $type);
219
-	}
183
+    /**
184
+     * @param string $path
185
+     * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
186
+     * @throws \OCP\Lock\LockedException
187
+     */
188
+    public function acquireLock(string $path, int $type) {
189
+        $expire = $this->getExpireTime();
190
+        if ($type === self::LOCK_SHARED) {
191
+            if (!$this->isLocallyLocked($path)) {
192
+                $result = $this->initLockField($path, 1);
193
+                if ($result <= 0) {
194
+                    $result = $this->connection->executeUpdate(
195
+                        'UPDATE `*PREFIX*file_locks` SET `lock` = `lock` + 1, `ttl` = ? WHERE `key` = ? AND `lock` >= 0',
196
+                        [$expire, $path]
197
+                    );
198
+                }
199
+            } else {
200
+                $result = 1;
201
+            }
202
+        } else {
203
+            $existing = 0;
204
+            if ($this->hasAcquiredLock($path, ILockingProvider::LOCK_SHARED) === false && $this->isLocallyLocked($path)) {
205
+                $existing = 1;
206
+            }
207
+            $result = $this->initLockField($path, -1);
208
+            if ($result <= 0) {
209
+                $result = $this->connection->executeUpdate(
210
+                    'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = ?',
211
+                    [$expire, $path, $existing]
212
+                );
213
+            }
214
+        }
215
+        if ($result !== 1) {
216
+            throw new LockedException($path);
217
+        }
218
+        $this->markAcquire($path, $type);
219
+    }
220 220
 
221
-	/**
222
-	 * @param string $path
223
-	 * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
224
-	 *
225
-	 * @suppress SqlInjectionChecker
226
-	 */
227
-	public function releaseLock(string $path, int $type) {
228
-		$this->markRelease($path, $type);
221
+    /**
222
+     * @param string $path
223
+     * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
224
+     *
225
+     * @suppress SqlInjectionChecker
226
+     */
227
+    public function releaseLock(string $path, int $type) {
228
+        $this->markRelease($path, $type);
229 229
 
230
-		// we keep shared locks till the end of the request so we can re-use them
231
-		if ($type === self::LOCK_EXCLUSIVE) {
232
-			$this->connection->executeUpdate(
233
-				'UPDATE `*PREFIX*file_locks` SET `lock` = 0 WHERE `key` = ? AND `lock` = -1',
234
-				[$path]
235
-			);
236
-		} else if (!$this->cacheSharedLocks) {
237
-			$query = $this->connection->getQueryBuilder();
238
-			$query->update('file_locks')
239
-				->set('lock', $query->func()->subtract('lock', $query->createNamedParameter(1)))
240
-				->where($query->expr()->eq('key', $query->createNamedParameter($path)))
241
-				->andWhere($query->expr()->gt('lock', $query->createNamedParameter(0)));
242
-			$query->execute();
243
-		}
244
-	}
230
+        // we keep shared locks till the end of the request so we can re-use them
231
+        if ($type === self::LOCK_EXCLUSIVE) {
232
+            $this->connection->executeUpdate(
233
+                'UPDATE `*PREFIX*file_locks` SET `lock` = 0 WHERE `key` = ? AND `lock` = -1',
234
+                [$path]
235
+            );
236
+        } else if (!$this->cacheSharedLocks) {
237
+            $query = $this->connection->getQueryBuilder();
238
+            $query->update('file_locks')
239
+                ->set('lock', $query->func()->subtract('lock', $query->createNamedParameter(1)))
240
+                ->where($query->expr()->eq('key', $query->createNamedParameter($path)))
241
+                ->andWhere($query->expr()->gt('lock', $query->createNamedParameter(0)));
242
+            $query->execute();
243
+        }
244
+    }
245 245
 
246
-	/**
247
-	 * Change the type of an existing lock
248
-	 *
249
-	 * @param string $path
250
-	 * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
251
-	 * @throws \OCP\Lock\LockedException
252
-	 */
253
-	public function changeLock(string $path, int $targetType) {
254
-		$expire = $this->getExpireTime();
255
-		if ($targetType === self::LOCK_SHARED) {
256
-			$result = $this->connection->executeUpdate(
257
-				'UPDATE `*PREFIX*file_locks` SET `lock` = 1, `ttl` = ? WHERE `key` = ? AND `lock` = -1',
258
-				[$expire, $path]
259
-			);
260
-		} else {
261
-			// since we only keep one shared lock in the db we need to check if we have more then one shared lock locally manually
262
-			if (isset($this->acquiredLocks['shared'][$path]) && $this->acquiredLocks['shared'][$path] > 1) {
263
-				throw new LockedException($path);
264
-			}
265
-			$result = $this->connection->executeUpdate(
266
-				'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = 1',
267
-				[$expire, $path]
268
-			);
269
-		}
270
-		if ($result !== 1) {
271
-			throw new LockedException($path);
272
-		}
273
-		$this->markChange($path, $targetType);
274
-	}
246
+    /**
247
+     * Change the type of an existing lock
248
+     *
249
+     * @param string $path
250
+     * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
251
+     * @throws \OCP\Lock\LockedException
252
+     */
253
+    public function changeLock(string $path, int $targetType) {
254
+        $expire = $this->getExpireTime();
255
+        if ($targetType === self::LOCK_SHARED) {
256
+            $result = $this->connection->executeUpdate(
257
+                'UPDATE `*PREFIX*file_locks` SET `lock` = 1, `ttl` = ? WHERE `key` = ? AND `lock` = -1',
258
+                [$expire, $path]
259
+            );
260
+        } else {
261
+            // since we only keep one shared lock in the db we need to check if we have more then one shared lock locally manually
262
+            if (isset($this->acquiredLocks['shared'][$path]) && $this->acquiredLocks['shared'][$path] > 1) {
263
+                throw new LockedException($path);
264
+            }
265
+            $result = $this->connection->executeUpdate(
266
+                'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = 1',
267
+                [$expire, $path]
268
+            );
269
+        }
270
+        if ($result !== 1) {
271
+            throw new LockedException($path);
272
+        }
273
+        $this->markChange($path, $targetType);
274
+    }
275 275
 
276
-	/**
277
-	 * cleanup empty locks
278
-	 */
279
-	public function cleanExpiredLocks() {
280
-		$expire = $this->timeFactory->getTime();
281
-		try {
282
-			$this->connection->executeUpdate(
283
-				'DELETE FROM `*PREFIX*file_locks` WHERE `ttl` < ?',
284
-				[$expire]
285
-			);
286
-		} catch (\Exception $e) {
287
-			// If the table is missing, the clean up was successful
288
-			if ($this->connection->tableExists('file_locks')) {
289
-				throw $e;
290
-			}
291
-		}
292
-	}
276
+    /**
277
+     * cleanup empty locks
278
+     */
279
+    public function cleanExpiredLocks() {
280
+        $expire = $this->timeFactory->getTime();
281
+        try {
282
+            $this->connection->executeUpdate(
283
+                'DELETE FROM `*PREFIX*file_locks` WHERE `ttl` < ?',
284
+                [$expire]
285
+            );
286
+        } catch (\Exception $e) {
287
+            // If the table is missing, the clean up was successful
288
+            if ($this->connection->tableExists('file_locks')) {
289
+                throw $e;
290
+            }
291
+        }
292
+    }
293 293
 
294
-	/**
295
-	 * release all lock acquired by this instance which were marked using the mark* methods
296
-	 *
297
-	 * @suppress SqlInjectionChecker
298
-	 */
299
-	public function releaseAll() {
300
-		parent::releaseAll();
294
+    /**
295
+     * release all lock acquired by this instance which were marked using the mark* methods
296
+     *
297
+     * @suppress SqlInjectionChecker
298
+     */
299
+    public function releaseAll() {
300
+        parent::releaseAll();
301 301
 
302
-		if (!$this->cacheSharedLocks) {
303
-			return;
304
-		}
305
-		// since we keep shared locks we need to manually clean those
306
-		$lockedPaths = array_keys($this->sharedLocks);
307
-		$lockedPaths = array_filter($lockedPaths, function ($path) {
308
-			return $this->sharedLocks[$path];
309
-		});
302
+        if (!$this->cacheSharedLocks) {
303
+            return;
304
+        }
305
+        // since we keep shared locks we need to manually clean those
306
+        $lockedPaths = array_keys($this->sharedLocks);
307
+        $lockedPaths = array_filter($lockedPaths, function ($path) {
308
+            return $this->sharedLocks[$path];
309
+        });
310 310
 
311
-		$chunkedPaths = array_chunk($lockedPaths, 100);
311
+        $chunkedPaths = array_chunk($lockedPaths, 100);
312 312
 
313
-		foreach ($chunkedPaths as $chunk) {
314
-			$builder = $this->connection->getQueryBuilder();
313
+        foreach ($chunkedPaths as $chunk) {
314
+            $builder = $this->connection->getQueryBuilder();
315 315
 
316
-			$query = $builder->update('file_locks')
317
-				->set('lock', $builder->createFunction('`lock` -1'))
318
-				->where($builder->expr()->in('key', $builder->createNamedParameter($chunk, IQueryBuilder::PARAM_STR_ARRAY)))
319
-				->andWhere($builder->expr()->gt('lock', new Literal(0)));
316
+            $query = $builder->update('file_locks')
317
+                ->set('lock', $builder->createFunction('`lock` -1'))
318
+                ->where($builder->expr()->in('key', $builder->createNamedParameter($chunk, IQueryBuilder::PARAM_STR_ARRAY)))
319
+                ->andWhere($builder->expr()->gt('lock', new Literal(0)));
320 320
 
321
-			$query->execute();
322
-		}
323
-	}
321
+            $query->execute();
322
+        }
323
+    }
324 324
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
 				->setValue('lock', $builder->createNamedParameter($lock))
143 143
 				->setValue('ttl', $builder->createNamedParameter($expire))
144 144
 				->execute();
145
-		} catch(UniqueConstraintViolationException $e) {
145
+		} catch (UniqueConstraintViolationException $e) {
146 146
 			return 0;
147 147
 		}
148 148
 	}
@@ -165,7 +165,7 @@  discard block
 block discarded – undo
165 165
 		}
166 166
 		$query = $this->connection->prepare('SELECT `lock` from `*PREFIX*file_locks` WHERE `key` = ?');
167 167
 		$query->execute([$path]);
168
-		$lockValue = (int)$query->fetchColumn();
168
+		$lockValue = (int) $query->fetchColumn();
169 169
 		if ($type === self::LOCK_SHARED) {
170 170
 			if ($this->isLocallyLocked($path)) {
171 171
 				// if we have a shared lock we kept open locally but it's released we always have at least 1 shared lock in the db
@@ -304,7 +304,7 @@  discard block
 block discarded – undo
304 304
 		}
305 305
 		// since we keep shared locks we need to manually clean those
306 306
 		$lockedPaths = array_keys($this->sharedLocks);
307
-		$lockedPaths = array_filter($lockedPaths, function ($path) {
307
+		$lockedPaths = array_filter($lockedPaths, function($path) {
308 308
 			return $this->sharedLocks[$path];
309 309
 		});
310 310
 
Please login to merge, or discard this patch.