Change record status: 
Project: 
Introduced in branch: 
10.2.x
Introduced in version: 
10.2.0
Description: 

Extensions for database drivers

The extensions for database drivers have been added. The service for getting the list of database driver extensions is \Drupal::service('extension.list.database_driver'). The extensions are keyed by their namespace and not their driver name as can be multiple drivers for the same database. For instance we have the pgsql database driver that is provided by the core module pgsql. The module pgsql_fallback also provides a pgsql database driver. It does that for older versions of PostgreSQL that are no longer supported by Drupal.

Calling \Drupal::service('extension.list.database_driver')->get($driver_name) with the driver name is deprecated. The correct way of getting the database driver extension is by using the drivers namespace. Like: \Drupal::service('extension.list.database_driver')->get($namespace).

The added method \Drupal::service('extension.list.database_driver')->getFromDriverName($driver_name) is deprecated. The method is helper method to make the previous deprecation possible. The method returns the first available database driver extension for the given driver name.

The Drupal form install_settings_form that lives in the class Drupal\Core\Installer\Form\SiteSettingsForm must use the namespace for the driver field and using the field with the driver name is deprecated.

drupal_get_database_types()

The function drupal_get_database_types() has been deprecated and is being replaced by \Drupal::service('extension.list.database_driver')->getInstallableList();

Before:

// The drivers are keyed by their driver name.
$drivers = drupal_get_database_types();

After:

// The drivers are keyed by their namespace.
$drivers = \Drupal::service('extension.list.database_driver')->getInstallableList();

OR

// The drivers are keyed by their driver name. Will fail when multiple drivers have the same name.
$drivers = [];
foreach (\Drupal::service('extension.list.database_driver')->getInstallableList() as $driver) {
  $drivers[$driver->getDriverName()] = $driver->getInstallTasks();
}

drupal_detect_database_types()

The function drupal_detect_database_types() has been deprecated and is being replaced by \Drupal::service('extension.list.database_driver')->getInstallableList();

Before:

// The drivers are keyed by their driver name.
$drivers = drupal_detect_database_types();

After:

// The drivers are keyed by their namespace.
$drivers = \Drupal::service('extension.list.database_driver')->getInstallableList();

OR

// The drivers are keyed by their driver name. Will fail when multiple drivers have the same name.
$drivers = [];
foreach (\Drupal::service('extension.list.database_driver')->getInstallableList() as $driver) {
  $drivers[$driver->getDriverName()] = $driver->getInstallTasks()->name();
}

Drupal\Core\Database\Database::findDriverAutoloadDirectory()

The method Drupal\Core\Database\Database::findDriverAutoloadDirectory() has been deprecated and is being replaced by \Drupal::service('extension.list.database_driver')->get($namespace)->getAutoloadInfo().

Before:
$autoload_data = Drupal\Core\Database\Database::findDriverAutoloadDirectory($namespace, DRUPAL_ROOT))

After:

$autoload_data = \Drupal::service('extension.list.database_driver')->get($namespace)->getAutoloadInfo()['autoload']

// Autoload data on which the current database driver is dependent.
$autoload_data_dependencies = \Drupal::service('extension.list.database_driver')->get($namespace)->getAutoloadInfo()['dependencies']

Settings.php

During the installation process, database drivers that have dependencies will have the autoloading information for the dependencies added in the settings.php file. This is necessary to allow ensuring access to the extended classes very early during the request, before the container is actually available.

For most (> 99%) sites this will not be the case. There are at the moment only 2 database drivers that are dependent on another database driver. Those are: https://www.drupal.org/project/mysql56 and https://www.drupal.org/project/pgsql_fallback.

When a new site is created the database driver data in settings.php will have an additional key named "dependencies". That key will contain the dependency data for the database driver. Something like:

$databases['default']['default'] = [
  'driver' => 'my_driver',
  'namespace' => 'Drupal\my_module\Driver\Database\my_driver',
  'autoload' => 'modules/my_module/src/Driver/Database/my_driver/',
  'database' => 'databasename',
  'username' => 'sqlusername',
  'password' => 'sqlpassword',
  'host' => 'localhost',
  'prefix' => '',
  'dependencies' => [
    'parent_module' => [
      'namespace' => 'Drupal\parent_module',
      'autoload' => 'core/modules/parent_module/src/',
    ],
  ],
];
Impacts: 
Site builders, administrators, editors
Module developers

Comments

greg.1.anderson’s picture

At the time of this writing, Pantheon does not support injecting the new database settings introduced in this change record into the $databases array. Note that the two drivers that need this feature today are not necessary on Pantheon. Tracking internally as CMSP-783.

Excerpt from the internal ticket:

Possible things we could do:

  • The change record shows how to get the information that the installer injects into the $databases array. We could use an internal job to query this information, and then write it back into our internal storage so that we can correctly populate the $databases record. Note that the difficulty here is that we probably can’t make these calls until after Drupal has been installed, and also, the info injected by the installer could change in future Drupal releases, making our code out of date.
  • We could look for other methods we might call that are already in use by the installer that provides all of the information that should go in the $databases record.
  • We could collaborate with the Drupal community and try to determine ways that Pantheon could signal the installer to call back to Pantheon with the info it would like to write into the $databases record, so that we can store it in C*.