Merge pull request #13721 from oole/bug/12729_postgresql_duplicate_key_value

Issue 12729 postgresql duplicate key value
This commit is contained in:
Morris Jobke 2019-03-21 21:18:32 +01:00 committed by GitHub
commit f5c0ea852e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 12 deletions

View File

@ -126,4 +126,20 @@ class Adapter {
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;
}
}
}

View File

@ -35,4 +35,17 @@ class AdapterPgSql extends Adapter {
$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());
}
}

View File

@ -257,6 +257,10 @@ class Connection extends ReconnectWrapper implements IDBConnection {
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;

View File

@ -131,20 +131,13 @@ class DBLockingProvider extends AbstractLockingProvider {
* @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
]);
}
/**

View File

@ -120,6 +120,20 @@ interface IDBConnection {
*/
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
*