Unverified Commit 9a28ddce authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3185269 by mondrake, daffie, alexpott, andypost: Introduce...

Issue #3185269 by mondrake, daffie, alexpott, andypost: Introduce Connection::lastInsertId and deprecate the 'return' query option and Database::RETURN_* constants

(cherry picked from commit 87dc8f41)
parent ca7158d4
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -626,10 +626,15 @@ function drupal_install_system($install_state) {
  // When the database driver is provided by a module, then install that module.
  // This module must be installed before any other module, as it must be able
  // to override any call to hook_schema() or any "backend_overridable" service.
  // In edge cases, a driver module may extend from another driver module (for
  // instance, a module to provide backward compatibility with a database
  // version no longer supported by core). In order for the extended classes to
  // be autoloadable, the extending module should list the extended module in
  // its dependencies, and here the dependencies will be installed as well.
  if ($provider !== 'core') {
    $autoload = $connection->getConnectionOptions()['autoload'] ?? '';
    if (($pos = strpos($autoload, 'src/Driver/Database/')) !== FALSE) {
      $kernel->getContainer()->get('module_installer')->install([$provider], FALSE);
      $kernel->getContainer()->get('module_installer')->install([$provider], TRUE);
    }
  }

+8 −0
Original line number Diff line number Diff line
@@ -143,6 +143,8 @@ public function write($name, array $data) {
   * @return bool
   */
  protected function doWrite($name, $data) {
    // @todo Remove the 'return' option in Drupal 11.
    // @see https://www.drupal.org/project/drupal/issues/3256524
    $options = ['return' => Database::RETURN_AFFECTED] + $this->options;
    return (bool) $this->connection->merge($this->table, $options)
      ->keys(['collection', 'name'], [$this->collection, $name])
@@ -218,6 +220,8 @@ protected static function schemaDefinition() {
   * @todo Ignore replica targets for data manipulation operations.
   */
  public function delete($name) {
    // @todo Remove the 'return' option in Drupal 11.
    // @see https://www.drupal.org/project/drupal/issues/3256524
    $options = ['return' => Database::RETURN_AFFECTED] + $this->options;
    return (bool) $this->connection->delete($this->table, $options)
      ->condition('collection', $this->collection)
@@ -231,6 +235,8 @@ public function delete($name) {
   * @throws PDOException
   */
  public function rename($name, $new_name) {
    // @todo Remove the 'return' option in Drupal 11.
    // @see https://www.drupal.org/project/drupal/issues/3256524
    $options = ['return' => Database::RETURN_AFFECTED] + $this->options;
    return (bool) $this->connection->update($this->table, $options)
      ->fields(['name' => $new_name])
@@ -280,6 +286,8 @@ public function listAll($prefix = '') {
   */
  public function deleteAll($prefix = '') {
    try {
      // @todo Remove the 'return' option in Drupal 11.
      // @see https://www.drupal.org/project/drupal/issues/3256524
      $options = ['return' => Database::RETURN_AFFECTED] + $this->options;
      return (bool) $this->connection->delete($this->table, $options)
        ->condition('name', $prefix . '%', 'LIKE')
+50 −8
Original line number Diff line number Diff line
@@ -367,12 +367,12 @@ public function __destruct() {
   *   class. If a string is specified, each record will be fetched into a new
   *   object of that class. The behavior of all other values is defined by PDO.
   *   See http://php.net/manual/pdostatement.fetch.php
   * - return: Depending on the type of query, different return values may be
   *   meaningful. This directive instructs the system which type of return
   *   value is desired. The system will generally set the correct value
   *   automatically, so it is extremely rare that a module developer will ever
   *   need to specify this value. Setting it incorrectly will likely lead to
   *   unpredictable results or fatal errors. Legal values include:
   * - return: (deprecated) Depending on the type of query, different return
   *   values may be meaningful. This directive instructs the system which type
   *   of return value is desired. The system will generally set the correct
   *   value automatically, so it is extremely rare that a module developer will
   *   ever need to specify this value. Setting it incorrectly will likely lead
   *   to unpredictable results or fatal errors. Legal values include:
   *   - Database::RETURN_STATEMENT: Return the prepared statement object for
   *     the query. This is usually only meaningful for SELECT queries, where
   *     the statement object is how one accesses the result set returned by the
@@ -414,7 +414,6 @@ public function __destruct() {
  protected function defaultOptions() {
    return [
      'fetch' => \PDO::FETCH_OBJ,
      'return' => Database::RETURN_STATEMENT,
      'allow_delimiter_in_query' => FALSE,
      'allow_square_brackets' => FALSE,
      'pdo' => [],
@@ -616,6 +615,10 @@ public function getFullQualifiedTableName($table) {
   * @throws \Drupal\Core\Database\DatabaseExceptionWrapper
   */
  public function prepareStatement(string $query, array $options, bool $allow_row_count = FALSE): StatementInterface {
    if (isset($options['return'])) {
      @trigger_error('Passing "return" option to ' . __METHOD__ . '() is deprecated in drupal:9.4.0 and is removed in drupal:11.0.0. For data manipulation operations, use dynamic queries instead. See https://www.drupal.org/node/3185520', E_USER_DEPRECATED);
    }

    try {
      $query = $this->preprocessStatement($query, $options);

@@ -914,6 +917,11 @@ protected function filterComment($comment = '') {
  public function query($query, array $args = [], $options = []) {
    // Use default values if not already set.
    $options += $this->defaultOptions();

    if (isset($options['return'])) {
      @trigger_error('Passing "return" option to ' . __METHOD__ . '() is deprecated in drupal:9.4.0 and is removed in drupal:11.0.0. For data manipulation operations, use dynamic queries instead. See https://www.drupal.org/node/3185520', E_USER_DEPRECATED);
    }

    assert(!isset($options['target']), 'Passing "target" option to query() has no effect. See https://www.drupal.org/node/2993033');

    // We allow either a pre-bound statement object (deprecated) or a literal
@@ -946,7 +954,7 @@ public function query($query, array $args = [], $options = []) {
      // Depending on the type of query we may need to return a different value.
      // See DatabaseConnection::defaultOptions() for a description of each
      // value.
      switch ($options['return']) {
      switch ($options['return'] ?? Database::RETURN_STATEMENT) {
        case Database::RETURN_STATEMENT:
          return $stmt;

@@ -1234,6 +1242,40 @@ public function insert($table, array $options = []) {
    return new $class($this, $table, $options);
  }

  /**
   * Returns the ID of the last inserted row or sequence value.
   *
   * This method should normally be used only within database driver code.
   *
   * This is a proxy to invoke lastInsertId() from the wrapped connection.
   * If a sequence name is not specified for the name parameter, this returns a
   * string representing the row ID of the last row that was inserted into the
   * database.
   * If a sequence name is specified for the name parameter, this returns a
   * string representing the last value retrieved from the specified sequence
   * object.
   *
   * @param string|null $name
   *   (Optional) Name of the sequence object from which the ID should be
   *   returned.
   *
   * @return string
   *   The value returned by the wrapped connection.
   *
   * @throws \Drupal\Core\Database\DatabaseExceptionWrapper
   *   In case of failure.
   *
   * @see \PDO::lastInsertId
   *
   * @internal
   */
  public function lastInsertId(?string $name = NULL): string {
    if (($last_insert_id = $this->connection->lastInsertId($name)) === FALSE) {
      throw new DatabaseExceptionWrapper("Could not determine last insert id" . $name === NULL ? '' : " for sequence $name");
    }
    return $last_insert_id;
  }

  /**
   * Prepares and returns a MERGE query object.
   *
+20 −0
Original line number Diff line number Diff line
@@ -19,21 +19,41 @@ abstract class Database {
   *
   * This is used for queries that have no reasonable return value anyway, such
   * as INSERT statements to a table without a serial primary key.
   *
   * @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. There is no
   *   replacement.
   *
   * @see https://www.drupal.org/node/3185520
   */
  const RETURN_NULL = 0;

  /**
   * Flag to indicate a query call should return the prepared statement.
   *
   * @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. There is no
   *   replacement.
   *
   * @see https://www.drupal.org/node/3185520
   */
  const RETURN_STATEMENT = 1;

  /**
   * Flag to indicate a query call should return the number of affected rows.
   *
   * @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. There is no
   *   replacement.
   *
   * @see https://www.drupal.org/node/3185520
   */
  const RETURN_AFFECTED = 2;

  /**
   * Flag to indicate a query call should return the "last insert id".
   *
   * @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. There is no
   *   replacement.
   *
   * @see https://www.drupal.org/node/3185520
   */
  const RETURN_INSERT_ID = 3;

+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ class Delete extends Query implements ConditionInterface {
   *   Array of database options.
   */
  public function __construct(Connection $connection, $table, array $options = []) {
    // @todo Remove $options['return'] in Drupal 11.
    // @see https://www.drupal.org/project/drupal/issues/3256524
    $options['return'] = Database::RETURN_AFFECTED;
    parent::__construct($connection, $options);
    $this->table = $table;
Loading