Change record status: 
Project: 
Introduced in branch: 
8.0.x
Introduced in version: 
8.0.0
Description: 

All of the db_* procedural functions part of the Database API layer have been deprecated.

The recommended way to call database API functions is now to obtain the database connection object and execute operations on it.

In most of the cases (that is when the code is executing on a fully bootstrapped Drupal where the container is available), the database connection should be injected as a service through the constructor like for example:

...

use Drupal\Core\Database\Connection;

...

class MyController {

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $connection;

  /**
   * Constructs this factory object.
   *
   * @param \Drupal\Core\Database\Connection $connection
   *   The Connection object.
   */
  public function __construct(Connection $connection) {
    $this->connection = $connection;
  }

  ...

  public function myMethod() {
    return $this->connection->nextId();
  }

  ...

}

where it is not possible to inject the service, the \Drupal::database() helper can be used, for example:

...

public function myProceduralFunction() {
  $connection = \Drupal::database();
  return $connection->nextId();
}

...

If code needs to access database in contexts where the container is not yet available, call the static getConnection() method from the Database class, for example:

...

use Drupal\Core\Database\Database;

...

class MyController {

  ...

  public function myMethod() {
    $connection = Database::getConnection();
    return $connection->nextId();
  }

  ...

}

The recommended way to access to database API in PHPUnit tests is still under discussion at #2991337: Document the recommended ways to obtain the database connection object.

See below the table of the deprecated functions with their new alternatives.

Deprecated function New method
db_add_field $injected_database->schema()->addField($table, $field, $spec, $keys_new)
db_add_index $injected_database->schema()->addIndex($table, $name, $fields, $spec)
db_add_primary_key $injected_database->schema()->addPrimaryKey($table, $fields)
db_add_unique_key $injected_database->schema()->addUniqueKey($table, $name, $fields)
db_and Create a \Drupal\Core\Database\Query\Condition object, specifying an AND conjunction: new Condition('AND');
db_change_field $injected_database->schema()->changeField($table, $field, $field_new, $spec, $keys_new)
db_close \Drupal\Core\Database\Database::closeConnection($target)
db_condition Create a \Drupal\Core\Database\Query\Condition object, specifying the desired conjunction: new Condition($conjunction);
db_create_table $injected_database->schema()->createTable($name, $table)
db_delete $injected_database->delete($table, $options)
db_driver $injected_database->driver()
db_drop_field $injected_database->schema()->dropField($table, $field)
db_drop_index $injected_database->schema()->dropIndex($table, $name)
db_drop_primary_key $injected_database->schema()->dropPrimaryKey($table)
db_drop_table $injected_database->schema()->dropTable($table)
db_drop_unique_key $injected_database->schema()->dropUniqueKey($table, $name)
db_escape_field $injected_database->escapeField($field)
db_escape_table $injected_database->escapeTable($table)
db_field_exists $injected_database->schema()->fieldExists($table, $field)
db_field_names $injected_database->schema()->fieldNames($fields)
db_field_set_default use $injected_database->schema()->changeField($table, $field, $field_new, $spec, $keys_new) passing a full field specification
db_field_set_no_default use $injected_database->schema()->changeField($table, $field, $field_new, $spec, $keys_new) passing a full field specification
db_find_tables $injected_database->schema()->findTables($table_expression)
db_index_exists $injected_database->schema()->indexExists($table, $name)
db_insert $injected_database->insert($table, $options)
db_like $injected_database->escapeLike($string)
db_merge $injected_database->merge($table, $options)
db_next_id $injected_database->nextId($existing_id)
db_or Create a \Drupal\Core\Database\Query\Condition object, specifying an OR conjunction: new Condition('OR');
db_query $injected_database->query($query, $args, $options)
db_query_range $injected_database->queryRange($query, $from, $count, $args, $options)
db_query_temporary $injected_database->queryTemporary($query, $args, $options)
db_rename_table $injected_database->schema()->renameTable($table, $new_name)
db_select $injected_database->select($table, $alias, $options)
db_set_active \Drupal\Core\Database\Database::setActiveConnection($key)
db_table_exists $injected_database->schema()->tableExists($table)
db_transaction $injected_database->startTransaction($name)
db_truncate $injected_database->truncate($table, $options)
db_update $injected_database->update($table, $options)
db_xor Create a \Drupal\Core\Database\Query\Condition object, specifying an XOR conjunction: new Condition('XOR');

'target' entry in the $options array for DB API methods is no longer supported.

Also note that passing ['target' => 'replica'] entries to the options array in calls to DB API methods is no longer supported. Instead, the required replica connection needs to be identified beforehand using the database.replica service, and the operation executed on it.

Before:

...
      $query = db_select('search_index', 'i', ['target' => 'replica']);
...

After:

...
    $database_replica = \Drupal::service('database.replica');
    $query = $database_replica->select('search_index', 'i'):
...
Impacts: 
Module developers

Comments

mlncn’s picture