Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 36 |
| Upsert | |
0.00% |
0 / 1 |
|
0.00% |
0 / 2 |
56 | |
0.00% |
0 / 36 |
| execute | |
0.00% |
0 / 1 |
42 | |
0.00% |
0 / 35 |
|||
| __toString | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\Core\Database\Driver\pgsql\Upsert. | |
| */ | |
| namespace Drupal\Core\Database\Driver\pgsql; | |
| use Drupal\Core\Database\Query\Upsert as QueryUpsert; | |
| /** | |
| * PostgreSQL implementation of \Drupal\Core\Database\Query\Upsert. | |
| */ | |
| class Upsert extends QueryUpsert { | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function execute() { | |
| if (!$this->preExecute()) { | |
| return NULL; | |
| } | |
| // Default options for upsert queries. | |
| $this->queryOptions += array( | |
| 'throw_exception' => TRUE, | |
| ); | |
| // Default fields are always placed first for consistency. | |
| $insert_fields = array_merge($this->defaultFields, $this->insertFields); | |
| $table = $this->connection->escapeTable($this->table); | |
| // We have to execute multiple queries, therefore we wrap everything in a | |
| // transaction so that it is atomic where possible. | |
| $transaction = $this->connection->startTransaction(); | |
| try { | |
| // First, lock the table we're upserting into. | |
| $this->connection->query('LOCK TABLE {' . $table . '} IN SHARE ROW EXCLUSIVE MODE', [], $this->queryOptions); | |
| // Second, delete all items first so we can do one insert. | |
| $unique_key_position = array_search($this->key, $insert_fields); | |
| $delete_ids = []; | |
| foreach ($this->insertValues as $insert_values) { | |
| $delete_ids[] = $insert_values[$unique_key_position]; | |
| } | |
| // Delete in chunks when a large array is passed. | |
| foreach (array_chunk($delete_ids, 1000) as $delete_ids_chunk) { | |
| $this->connection->delete($this->table, $this->queryOptions) | |
| ->condition($this->key, $delete_ids_chunk, 'IN') | |
| ->execute(); | |
| } | |
| // Third, insert all the values. | |
| $insert = $this->connection->insert($this->table, $this->queryOptions) | |
| ->fields($insert_fields); | |
| foreach ($this->insertValues as $insert_values) { | |
| $insert->values($insert_values); | |
| } | |
| $insert->execute(); | |
| } | |
| catch (\Exception $e) { | |
| // One of the queries failed, rollback the whole batch. | |
| $transaction->rollback(); | |
| // Rethrow the exception for the calling code. | |
| throw $e; | |
| } | |
| // Re-initialize the values array so that we can re-use this query. | |
| $this->insertValues = array(); | |
| // Transaction commits here where $transaction looses scope. | |
| return TRUE; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function __toString() { | |
| // Nothing to do. | |
| } | |
| } |