public function Merge::execute

Runs the query against the database.

Overrides Query::execute

File

drupal/core/lib/Drupal/Core/Database/Query/Merge.php, line 407
Definition of Drupal\Core\Database\Query\Merge

Class

Merge
General class for an abstracted MERGE query operation.

Namespace

Drupal\Core\Database\Query

Code

public function execute() {

  // Wrap multiple queries in a transaction, if the database supports it.
  $transaction = $this->connection
    ->startTransaction();
  try {
    if (!count($this->condition)) {
      throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
    }
    $select = $this->connection
      ->select($this->conditionTable)
      ->condition($this->condition)
      ->forUpdate();
    $select
      ->addExpression('1');
    if (!$select
      ->execute()
      ->fetchField()) {
      try {
        $insert = $this->connection
          ->insert($this->table)
          ->fields($this->insertFields);
        if ($this->defaultFields) {
          $insert
            ->useDefaults($this->defaultFields);
        }
        $insert
          ->execute();
        return self::STATUS_INSERT;
      } catch (IntegrityConstraintViolationException $e) {

        // The insert query failed, maybe it's because a racing insert query
        // beat us in inserting the same row. Retry the select query, if it
        // returns a row, ignore the error and continue with the update
        // query below.
        if (!$select
          ->execute()
          ->fetchField()) {
          throw $e;
        }
      }
    }
    if ($this->needsUpdate) {
      $update = $this->connection
        ->update($this->table)
        ->fields($this->updateFields)
        ->condition($this->condition);
      if ($this->expressionFields) {
        foreach ($this->expressionFields as $field => $data) {
          $update
            ->expression($field, $data['expression'], $data['arguments']);
        }
      }
      $update
        ->execute();
      return self::STATUS_UPDATE;
    }
  } catch (Exception $e) {

    // Something really wrong happened here, bubble up the exception to the
    // caller.
    $transaction
      ->rollback();
    throw $e;
  }

  // Transaction commits here where $transaction looses scope.
}