Verified Commit ea261a9d authored by Dave Long's avatar Dave Long
Browse files

Issue #2005626 by sukr_s, gold, jhedstrom, neelam_wadhwani, neslee canil...

Issue #2005626 by sukr_s, gold, jhedstrom, neelam_wadhwani, neslee canil pinto, jweowu, Mixologic, quietone, daffie, smustgrave, longwave, mondrake: Implement \Drupal\Core\Database\Query\Update::arguments
parent 0e07179f
Loading
Loading
Loading
Loading
Loading
+47 −21
Original line number Diff line number Diff line
@@ -116,27 +116,9 @@ public function expression($field, $expression, ?array $arguments = NULL) {
   *   actually didn't have to be updated because the values didn't change.
   */
  public function execute() {
    // Expressions take priority over literal fields, so we process those first
    // and remove any literal fields that conflict.
    $fields = $this->fields;
    $update_values = [];
    foreach ($this->expressionFields as $field => $data) {
      if (!empty($data['arguments'])) {
        $update_values += $data['arguments'];
      }
      if ($data['expression'] instanceof SelectInterface) {
        $data['expression']->compile($this->connection, $this);
        $update_values += $data['expression']->arguments();
      }
      unset($fields[$field]);
    }

    // Because we filter $fields the same way here and in __toString(), the
    // placeholders will all match up properly.
    $max_placeholder = 0;
    foreach ($fields as $value) {
      $update_values[':db_update_placeholder_' . ($max_placeholder++)] = $value;
    }
    [$args, $update_values] = $this->getQueryArguments();
    $update_values += $args;

    if (count($this->condition)) {
      $this->condition->compile($this->connection, $this);
@@ -178,8 +160,10 @@ public function __toString() {
    }

    $max_placeholder = 0;
    [$args] = $this->getQueryArguments();
    $placeholders = array_keys($args);
    foreach ($fields as $field => $value) {
      $update_fields[] = $this->connection->escapeField($field) . '=:db_update_placeholder_' . ($max_placeholder++);
      $update_fields[] = $this->connection->escapeField($field) . '=' . $placeholders[$max_placeholder++];
    }

    $query = $comments . 'UPDATE {' . $this->connection->escapeTable($this->table) . '} SET ' . implode(', ', $update_fields);
@@ -193,4 +177,46 @@ public function __toString() {
    return $query;
  }

  /**
   * {@inheritdoc}
   */
  public function arguments() {
    [$args] = $this->getQueryArguments();
    return $this->condition->arguments() + $args;
  }

  /**
   * Returns the query arguments with placeholders mapped to their values.
   *
   * @return array
   *   An array containing arguments and update values.
   *   Both arguments and update values are associative array where the keys
   *   are the placeholder names and the values are the placeholder values.
   */
  protected function getQueryArguments(): array {
    // Expressions take priority over literal fields, so we process those first
    // and remove any literal fields that conflict.
    $fields = $this->fields;
    $update_values = [];
    foreach ($this->expressionFields as $field => $data) {
      if (!empty($data['arguments'])) {
        $update_values += $data['arguments'];
      }
      if ($data['expression'] instanceof SelectInterface) {
        $data['expression']->compile($this->connection, $this);
        $update_values += $data['expression']->arguments();
      }
      unset($fields[$field]);
    }

    // Because we filter $fields the same way here and in __toString(), the
    // placeholders will all match up properly.
    $max_placeholder = 0;
    $args = [];
    foreach ($fields as $value) {
      $args[':db_update_placeholder_' . ($max_placeholder++)] = $value;
    }
    return [$args, $update_values];
  }

}
+26 −0
Original line number Diff line number Diff line
@@ -172,4 +172,30 @@ public function testUpdateValueInSerial(): void {
      ->execute();
  }

  /**
   * Tests the Update::__toString() method.
   */
  public function testToString(): void {
    // Prepare query for testing.
    $query = $this->connection->update('test')
      ->fields(['a' => 27, 'b' => 42])
      ->condition('c', [1, 2], 'IN');

    // Confirm placeholders are present.
    $query_string = (string) $query;
    $this->assertStringContainsString(':db_update_placeholder_0', $query_string);
    $this->assertStringContainsString(':db_update_placeholder_1', $query_string);
    $this->assertStringContainsString(':db_condition_placeholder_0', $query_string);
    $this->assertStringContainsString(':db_condition_placeholder_1', $query_string);

    // Test arguments.
    $expected = [
      ':db_update_placeholder_0' => 27,
      ':db_update_placeholder_1' => 42,
      ':db_condition_placeholder_0' => 1,
      ':db_condition_placeholder_1' => 2,
    ];
    $this->assertEquals($expected, $query->arguments());
  }

}