diff options
author | Morris Jobke <hey@morrisjobke.de> | 2018-11-13 15:04:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-13 15:04:12 +0100 |
commit | 40f5f124a4f9074c3cad4d1b79d246b3f7213123 (patch) | |
tree | ba2f7be55cc131128da9397d52528f41d0c111fb | |
parent | 655b7f047cf88e731360932b13d7a08ff5933d84 (diff) | |
parent | ec5c11d28458fd2cddbebc7bce24313ea51ce2c0 (diff) | |
download | nextcloud-server-40f5f124a4f9074c3cad4d1b79d246b3f7213123.tar.gz nextcloud-server-40f5f124a4f9074c3cad4d1b79d246b3f7213123.zip |
Merge pull request #12433 from nextcloud/backport/12411-12413/unique-constraint-fix
[stable14] Unique contraint and deadlock fixes for filecache and file_locks
-rw-r--r-- | lib/private/Files/Cache/Cache.php | 25 | ||||
-rw-r--r-- | lib/private/Lock/DBLockingProvider.php | 13 |
2 files changed, 30 insertions, 8 deletions
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index 007bccf0a54..1cb11c70a40 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -37,6 +37,7 @@ namespace OC\Files\Cache; +use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use OCP\DB\QueryBuilder\IQueryBuilder; use Doctrine\DBAL\Driver\Statement; use OCP\Files\Cache\ICache; @@ -238,6 +239,8 @@ class Cache implements ICache { * * @return int file id * @throws \RuntimeException + * + * @suppress SqlInjectionChecker */ public function insert($file, array $data) { // normalize file @@ -268,12 +271,20 @@ class Cache implements ICache { return trim($item, "`"); }, $queryParts); $values = array_combine($queryParts, $params); - if (\OC::$server->getDatabaseConnection()->insertIfNotExist('*PREFIX*filecache', $values, [ - 'storage', - 'path_hash', - ]) - ) { - return (int)$this->connection->lastInsertId('*PREFIX*filecache'); + + try { + $builder = $this->connection->getQueryBuilder(); + $builder->insert('filecache'); + + foreach ($values as $column => $value) { + $builder->setValue($column, $builder->createNamedParameter($value)); + } + + if ($builder->execute()) { + return (int)$this->connection->lastInsertId('*PREFIX*filecache'); + } + } catch(UniqueConstraintViolationException $e) { + // entry exists already } // The file was created in the mean time @@ -281,7 +292,7 @@ class Cache implements ICache { $this->update($id, $data); return $id; } else { - throw new \RuntimeException('File entry could not be inserted with insertIfNotExist() but could also not be selected with getId() in order to perform an update. Please try again.'); + 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.'); } } diff --git a/lib/private/Lock/DBLockingProvider.php b/lib/private/Lock/DBLockingProvider.php index 6adb7488217..79f2ff274cf 100644 --- a/lib/private/Lock/DBLockingProvider.php +++ b/lib/private/Lock/DBLockingProvider.php @@ -26,6 +26,7 @@ namespace OC\Lock; +use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use OC\DB\QueryBuilder\Literal; use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\QueryBuilder\IQueryBuilder; @@ -133,7 +134,17 @@ class DBLockingProvider extends AbstractLockingProvider { protected function initLockField(string $path, int $lock = 0): int { $expire = $this->getExpireTime(); - return $this->connection->insertIfNotExist('*PREFIX*file_locks', ['key' => $path, 'lock' => $lock, 'ttl' => $expire], ['key']); + + try { + $builder = $this->connection->getQueryBuilder(); + return $builder->insert('file_locks') + ->setValue('key', $builder->createNamedParameter($path)) + ->setValue('lock', $builder->createNamedParameter($lock)) + ->setValue('ttl', $builder->createNamedParameter($expire)) + ->execute(); + } catch(UniqueConstraintViolationException $e) { + return 0; + } } /** |