Skip to content

Commit

Permalink
Merge pull request #13721 from oole/bug/12729_postgresql_duplicate_ke…
Browse files Browse the repository at this point in the history
…y_value

Issue 12729 postgresql duplicate key value
  • Loading branch information
MorrisJobke committed Mar 21, 2019
2 parents 5564a30 + f889bea commit f5c0ea8
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 12 deletions.
16 changes: 16 additions & 0 deletions lib/private/DB/Adapter.php
Expand Up @@ -126,4 +126,20 @@ public function insertIfNotExist($table, $input, array $compare = null) {
return 0;
}
}

/**
* @suppress SqlInjectionChecker
*/
public function insertIgnoreConflict(string $table,array $values) : int {
try {
$builder = $this->conn->getQueryBuilder();
$builder->insert($table);
foreach($values as $key => $value) {
$builder->setValue($key, $builder->createNamedParameter($value));
}
return $builder->execute();
} catch(UniqueConstraintViolationException $e) {
return 0;
}
}
}
13 changes: 13 additions & 0 deletions lib/private/DB/AdapterPgSql.php
Expand Up @@ -35,4 +35,17 @@ public function fixupStatement($statement) {
$statement = str_ireplace( 'UNIX_TIMESTAMP()', self::UNIX_TIMESTAMP_REPLACEMENT, $statement );
return $statement;
}

/**
* @suppress SqlInjectionChecker
*/
public function insertIgnoreConflict(string $table,array $values) : int {
$builder = $this->conn->getQueryBuilder();
$builder->insert($table);
foreach($values as $key => $value) {
$builder->setValue($key, $builder->createNamedParameter($value));
}
$queryString = $builder->getSQL() . ' ON CONFLICT DO NOTHING';
return $this->conn->executeUpdate($queryString, $builder->getParameters(), $builder->getParameterTypes());
}
}
4 changes: 4 additions & 0 deletions lib/private/DB/Connection.php
Expand Up @@ -257,6 +257,10 @@ public function insertIfNotExist($table, $input, array $compare = null) {
return $this->adapter->insertIfNotExist($table, $input, $compare);
}

public function insertIgnoreConflict(string $table, array $values) : int {
return $this->adapter->insertIgnoreConflict($table, $values);
}

private function getType($value) {
if (is_bool($value)) {
return IQueryBuilder::PARAM_BOOL;
Expand Down
17 changes: 5 additions & 12 deletions lib/private/Lock/DBLockingProvider.php
Expand Up @@ -131,20 +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();

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
]);
}

/**
Expand Down
14 changes: 14 additions & 0 deletions lib/public/IDBConnection.php
Expand Up @@ -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 $values data that should be inserted into the table (column name => value)
* @return int number of inserted rows
* @since 16.0.0
*/
public function insertIgnoreConflict(string $table,array $values) : int;

/**
* Insert or update a row value
*
Expand Down

0 comments on commit f5c0ea8

Please sign in to comment.