From a48ea8cffa68540b704bead86456008d6978a91b Mon Sep 17 00:00:00 2001 From: Ole Ostergaard Date: Mon, 21 Jan 2019 17:54:16 +0100 Subject: [PATCH 1/6] Add insertIgnoreConflict to Adapter and use it for for executing the file locking. Signed-off-by: Ole Ostergaard --- lib/private/DB/Adapter.php | 13 +++++++++++++ lib/private/DB/Connection.php | 4 ++++ lib/private/Lock/DBLockingProvider.php | 12 +----------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/private/DB/Adapter.php b/lib/private/DB/Adapter.php index b9a5f272c576c..139b7828596c6 100644 --- a/lib/private/DB/Adapter.php +++ b/lib/private/DB/Adapter.php @@ -126,4 +126,17 @@ public function insertIfNotExist($table, $input, array $compare = null) { return 0; } } + + public function insertIgnoreConflict($table, $input) : int { + try { + $builder = $this->conn->getQueryBuilder(); + $builder->insert($table); + foreach($input as $key => $value) { + $builder->setValue($key, $builder->createNamedParameter($value)); + } + return $builder->execute(); + } catch(UniqueConstraintViolationException $e) { + return 0; + } + } } diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php index c63ef0067c128..12a0af6121ef5 100644 --- a/lib/private/DB/Connection.php +++ b/lib/private/DB/Connection.php @@ -257,6 +257,10 @@ public function insertIfNotExist($table, $input, array $compare = null) { return $this->adapter->insertIfNotExist($table, $input, $compare); } + public function insertIgnoreConflict($table, $input) : int { + return $this->adapter->insertIgnoreConflict($table, $input); + } + private function getType($value) { if (is_bool($value)) { return IQueryBuilder::PARAM_BOOL; diff --git a/lib/private/Lock/DBLockingProvider.php b/lib/private/Lock/DBLockingProvider.php index 6d9c8f1b3d1a9..a1859047fe644 100644 --- a/lib/private/Lock/DBLockingProvider.php +++ b/lib/private/Lock/DBLockingProvider.php @@ -134,17 +134,7 @@ public function __construct( protected function initLockField(string $path, int $lock = 0): int { $expire = $this->getExpireTime(); - - 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; - } + return $this->connection->insertIgnoreConflict('file_locks', ['key' => $path, 'lock' => $lock, 'ttl' => $expire]); } /** From c9b6487393f1272f554cd54ea5707a43bd80d953 Mon Sep 17 00:00:00 2001 From: Ole Ostergaard Date: Mon, 21 Jan 2019 17:54:40 +0100 Subject: [PATCH 2/6] Add PostgreSQL specific implementation for includeIgnoreConflict. Signed-off-by: Ole Ostergaard --- lib/private/DB/AdapterPgSql.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/private/DB/AdapterPgSql.php b/lib/private/DB/AdapterPgSql.php index 47ef4dff0378d..86f2fe2e38423 100644 --- a/lib/private/DB/AdapterPgSql.php +++ b/lib/private/DB/AdapterPgSql.php @@ -35,4 +35,16 @@ public function fixupStatement($statement) { $statement = str_ireplace( 'UNIX_TIMESTAMP()', self::UNIX_TIMESTAMP_REPLACEMENT, $statement ); return $statement; } + + public function insertIgnoreConflict($table, $input) : int { + $builder = $this->conn->getQueryBuilder(); + $builder->insert($table) + ->values($input); + foreach($input as $key => $value) { + $builder->setValue($key, $builder->createNamedParameter($value)); + } + $queryString = $builder->getSQL() . ' ON CONFLICT DO NOTHING'; + $inserts = array_values($input); + return $this->conn->executeUpdate($queryString, $inserts); + } } From d62da82bf9e44d62aff287dcf64dccef35c2d693 Mon Sep 17 00:00:00 2001 From: Ole Ostergaard Date: Tue, 26 Feb 2019 14:08:39 +0100 Subject: [PATCH 3/6] Add supression of SqlInjectionChecker. Signed-off-by: Ole Ostergaard --- lib/private/DB/Adapter.php | 3 +++ lib/private/DB/AdapterPgSql.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/lib/private/DB/Adapter.php b/lib/private/DB/Adapter.php index 139b7828596c6..a9c20c735e08b 100644 --- a/lib/private/DB/Adapter.php +++ b/lib/private/DB/Adapter.php @@ -127,6 +127,9 @@ public function insertIfNotExist($table, $input, array $compare = null) { } } + /* + * @suppress SqlInjectionChecker + */ public function insertIgnoreConflict($table, $input) : int { try { $builder = $this->conn->getQueryBuilder(); diff --git a/lib/private/DB/AdapterPgSql.php b/lib/private/DB/AdapterPgSql.php index 86f2fe2e38423..de4fca3ebf4b0 100644 --- a/lib/private/DB/AdapterPgSql.php +++ b/lib/private/DB/AdapterPgSql.php @@ -36,6 +36,9 @@ public function fixupStatement($statement) { return $statement; } + /* + * @suppress SqlInjectionChecker + */ public function insertIgnoreConflict($table, $input) : int { $builder = $this->conn->getQueryBuilder(); $builder->insert($table) From 63350423d48b1d4fef842666ae3b7627396ca8d1 Mon Sep 17 00:00:00 2001 From: Ole Ostergaard Date: Tue, 26 Feb 2019 16:27:25 +0100 Subject: [PATCH 4/6] Add insertIgnoreConflict to IDBConnection interface. Signed-off-by: Ole Ostergaard --- lib/public/IDBConnection.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/public/IDBConnection.php b/lib/public/IDBConnection.php index b3abe46484596..f640ec126f04d 100644 --- a/lib/public/IDBConnection.php +++ b/lib/public/IDBConnection.php @@ -120,6 +120,20 @@ public function lastInsertId($table = null); */ public function insertIfNotExist($table, $input, array $compare = null); + + /** + * + * Insert a row if the row does not exist. Eventual conflicts during insert will be ignored. + * + * Implementation is not fully finished and should not be used! + * + * @param string $table The table name (will replace *PREFIX* with the actual prefix) + * @param array $input data that should be inserted into the table (column name => value) + * @return int number of inserted rows + * @since 17.0.0 + */ + public function insertIgnoreConflict($table, $input) : int; + /** * Insert or update a row value * From 0d778fcc4e489f541271fa25087777a9253d129e Mon Sep 17 00:00:00 2001 From: Ole Ostergaard Date: Tue, 26 Feb 2019 14:08:55 +0100 Subject: [PATCH 5/6] Code cleanup. Signed-off-by: Ole Ostergaard --- lib/private/DB/Adapter.php | 4 ++-- lib/private/DB/AdapterPgSql.php | 10 ++++------ lib/private/DB/Connection.php | 4 ++-- lib/private/Lock/DBLockingProvider.php | 7 +++++-- lib/public/IDBConnection.php | 6 +++--- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/private/DB/Adapter.php b/lib/private/DB/Adapter.php index a9c20c735e08b..0df2e0769f72e 100644 --- a/lib/private/DB/Adapter.php +++ b/lib/private/DB/Adapter.php @@ -130,11 +130,11 @@ public function insertIfNotExist($table, $input, array $compare = null) { /* * @suppress SqlInjectionChecker */ - public function insertIgnoreConflict($table, $input) : int { + public function insertIgnoreConflict(string $table,array $values) : int { try { $builder = $this->conn->getQueryBuilder(); $builder->insert($table); - foreach($input as $key => $value) { + foreach($values as $key => $value) { $builder->setValue($key, $builder->createNamedParameter($value)); } return $builder->execute(); diff --git a/lib/private/DB/AdapterPgSql.php b/lib/private/DB/AdapterPgSql.php index de4fca3ebf4b0..b7b473f37c228 100644 --- a/lib/private/DB/AdapterPgSql.php +++ b/lib/private/DB/AdapterPgSql.php @@ -39,15 +39,13 @@ public function fixupStatement($statement) { /* * @suppress SqlInjectionChecker */ - public function insertIgnoreConflict($table, $input) : int { + public function insertIgnoreConflict(string $table,array $values) : int { $builder = $this->conn->getQueryBuilder(); - $builder->insert($table) - ->values($input); - foreach($input as $key => $value) { + $builder->insert($table); + foreach($values as $key => $value) { $builder->setValue($key, $builder->createNamedParameter($value)); } $queryString = $builder->getSQL() . ' ON CONFLICT DO NOTHING'; - $inserts = array_values($input); - return $this->conn->executeUpdate($queryString, $inserts); + return $this->conn->executeUpdate($queryString, $builder->getParameters(), $builder->getParameterTypes()); } } diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php index 12a0af6121ef5..506f4bcd4c9d8 100644 --- a/lib/private/DB/Connection.php +++ b/lib/private/DB/Connection.php @@ -257,8 +257,8 @@ public function insertIfNotExist($table, $input, array $compare = null) { return $this->adapter->insertIfNotExist($table, $input, $compare); } - public function insertIgnoreConflict($table, $input) : int { - return $this->adapter->insertIgnoreConflict($table, $input); + public function insertIgnoreConflict(string $table, array $values) : int { + return $this->adapter->insertIgnoreConflict($table, $values); } private function getType($value) { diff --git a/lib/private/Lock/DBLockingProvider.php b/lib/private/Lock/DBLockingProvider.php index a1859047fe644..bd76385d85dd3 100644 --- a/lib/private/Lock/DBLockingProvider.php +++ b/lib/private/Lock/DBLockingProvider.php @@ -131,10 +131,13 @@ public function __construct( * @param int $lock * @return int number of inserted rows */ - protected function initLockField(string $path, int $lock = 0): int { $expire = $this->getExpireTime(); - return $this->connection->insertIgnoreConflict('file_locks', ['key' => $path, 'lock' => $lock, 'ttl' => $expire]); + return $this->connection->insertIgnoreConflict('file_locks', [ + 'key' => $path, + 'lock' => $lock, + 'ttl' => $expire + ]); } /** diff --git a/lib/public/IDBConnection.php b/lib/public/IDBConnection.php index f640ec126f04d..4c66896a2fe89 100644 --- a/lib/public/IDBConnection.php +++ b/lib/public/IDBConnection.php @@ -128,11 +128,11 @@ public function insertIfNotExist($table, $input, array $compare = null); * Implementation is not fully finished and should not be used! * * @param string $table The table name (will replace *PREFIX* with the actual prefix) - * @param array $input data that should be inserted into the table (column name => value) + * @param array $values data that should be inserted into the table (column name => value) * @return int number of inserted rows - * @since 17.0.0 + * @since 16.0.0 */ - public function insertIgnoreConflict($table, $input) : int; + public function insertIgnoreConflict(string $table,array $values) : int; /** * Insert or update a row value From f889beae7eb3c55a28a6d9798a7aadfd0f2336ad Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Thu, 21 Mar 2019 17:05:57 +0100 Subject: [PATCH 6/6] Fix PHPDoc Signed-off-by: Morris Jobke --- lib/private/DB/Adapter.php | 2 +- lib/private/DB/AdapterPgSql.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/DB/Adapter.php b/lib/private/DB/Adapter.php index 0df2e0769f72e..5c822dda0806b 100644 --- a/lib/private/DB/Adapter.php +++ b/lib/private/DB/Adapter.php @@ -127,7 +127,7 @@ public function insertIfNotExist($table, $input, array $compare = null) { } } - /* + /** * @suppress SqlInjectionChecker */ public function insertIgnoreConflict(string $table,array $values) : int { diff --git a/lib/private/DB/AdapterPgSql.php b/lib/private/DB/AdapterPgSql.php index b7b473f37c228..af1978d051c22 100644 --- a/lib/private/DB/AdapterPgSql.php +++ b/lib/private/DB/AdapterPgSql.php @@ -36,7 +36,7 @@ public function fixupStatement($statement) { return $statement; } - /* + /** * @suppress SqlInjectionChecker */ public function insertIgnoreConflict(string $table,array $values) : int {