diff --git a/core/includes/database.inc b/core/includes/database.inc index e5927fa65b..9d28ef4e6c 100644 --- a/core/includes/database.inc +++ b/core/includes/database.inc @@ -53,11 +53,7 @@ * @see \Drupal\Core\Database\Connection::defaultOptions() */ function db_query($query, array $args = [], array $options = []) { - if (empty($options['target'])) { - $options['target'] = 'default'; - } - - return Database::getConnection($options['target'])->query($query, $args, $options); + return Database::getConnection(Database::getTarget($options))->query($query, $args, $options); } /** @@ -92,11 +88,7 @@ function db_query($query, array $args = [], array $options = []) { */ function db_query_range($query, $from, $count, array $args = [], array $options = []) { @trigger_error('db_query_range() is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call queryRange() on it. For example, $injected_database->queryRange($query, $from, $count, $args, $options). See https://www.drupal.org/node/2993033', E_USER_DEPRECATED); - if (empty($options['target'])) { - $options['target'] = 'default'; - } - - return Database::getConnection($options['target'])->queryRange($query, $from, $count, $args, $options); + return Database::getConnection(Database::getTarget($options))->queryRange($query, $from, $count, $args, $options); } /** @@ -129,11 +121,7 @@ function db_query_range($query, $from, $count, array $args = [], array $options */ function db_query_temporary($query, array $args = [], array $options = []) { @trigger_error('db_query_temporary() is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call queryTemporary() on it. For example, $injected_database->queryTemporary($query, $args, $options). See https://www.drupal.org/node/2993033', E_USER_DEPRECATED); - if (empty($options['target'])) { - $options['target'] = 'default'; - } - - return Database::getConnection($options['target'])->queryTemporary($query, $args, $options); + return Database::getConnection(Database::getTarget($options))->queryTemporary($query, $args, $options); } /** @@ -157,10 +145,7 @@ function db_query_temporary($query, array $args = [], array $options = []) { */ function db_insert($table, array $options = []) { @trigger_error('db_insert() is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call insert() on it. For example, $injected_database->insert($table, $options); See https://www.drupal.org/node/2993033', E_USER_DEPRECATED); - if (empty($options['target']) || $options['target'] == 'replica') { - $options['target'] = 'default'; - } - return Database::getConnection($options['target'])->insert($table, $options); + return Database::getConnection(Database::getTarget($options, 'default', ['replica']))->insert($table, $options); } /** @@ -184,12 +169,7 @@ function db_insert($table, array $options = []) { */ function db_merge($table, array $options = []) { @trigger_error('db_merge() is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call merge() on it. For example, $injected_database->merge($table, $options). See https://www.drupal.org/node/2993033', E_USER_DEPRECATED); - // @todo Move away from here setting default target connection, - // https://www.drupal.org/node/2947775 - if (empty($options['target']) || $options['target'] == 'replica') { - $options['target'] = 'default'; - } - return Database::getConnection($options['target'])->merge($table, $options); + return Database::getConnection(Database::getTarget($options, 'default', ['replica']))->merge($table, $options); } /** @@ -213,10 +193,7 @@ function db_merge($table, array $options = []) { */ function db_update($table, array $options = []) { @trigger_error('db_update() is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call call update() on it. For example, $injected_database->update($table, $options); See https://www.drupal.org/node/2993033', E_USER_DEPRECATED); - if (empty($options['target']) || $options['target'] == 'replica') { - $options['target'] = 'default'; - } - return Database::getConnection($options['target'])->update($table, $options); + return Database::getConnection(Database::getTarget($options, 'default', ['replica']))->update($table, $options); } /** @@ -240,12 +217,7 @@ function db_update($table, array $options = []) { */ function db_delete($table, array $options = []) { @trigger_error('db_delete is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call delete() on it. For example, $injected_database->delete($table, $options). See https://www.drupal.org/node/2993033', E_USER_DEPRECATED); - // @todo Move away from here setting default target connection, - // https://www.drupal.org/node/2947775 - if (empty($options['target']) || $options['target'] == 'replica') { - $options['target'] = 'default'; - } - return Database::getConnection($options['target'])->delete($table, $options); + return Database::getConnection(Database::getTarget($options, 'default', ['replica']))->delete($table, $options); } /** @@ -269,10 +241,7 @@ function db_delete($table, array $options = []) { */ function db_truncate($table, array $options = []) { @trigger_error('db_truncate() is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call truncate() on it. For example, $injected_database->truncate($table, $options). See https://www.drupal.org/node/2993033', E_USER_DEPRECATED); - if (empty($options['target']) || $options['target'] == 'replica') { - $options['target'] = 'default'; - } - return Database::getConnection($options['target'])->truncate($table, $options); + return Database::getConnection(Database::getTarget($options, 'default', ['replica']))->truncate($table, $options); } /** @@ -300,10 +269,7 @@ function db_truncate($table, array $options = []) { */ function db_select($table, $alias = NULL, array $options = []) { @trigger_error('db_select() is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call call select() on it. For example, $injected_database->db_select($table, $alias, $options); See https://www.drupal.org/node/2993033', E_USER_DEPRECATED); - if (empty($options['target'])) { - $options['target'] = 'default'; - } - return Database::getConnection($options['target'])->select($table, $alias, $options); + return Database::getConnection(Database::getTarget($options))->select($table, $alias, $options); } /** @@ -328,12 +294,7 @@ function db_select($table, $alias = NULL, array $options = []) { */ function db_transaction($name = NULL, array $options = []) { @trigger_error('db_transaction is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call startTransaction() on it. For example, $injected_database->startTransaction($name). See https://www.drupal.org/node/2993033', E_USER_DEPRECATED); - // @todo Move away from here setting default target connection, - // https://www.drupal.org/node/2947775 - if (empty($options['target'])) { - $options['target'] = 'default'; - } - return Database::getConnection($options['target'])->startTransaction($name); + return Database::getConnection(Database::getTarget($options))->startTransaction($name); } /** @@ -472,10 +433,7 @@ function db_driver() { */ function db_close(array $options = []) { @trigger_error('db_close() is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Use \Drupal\Core\Database\Database::closeConnection() instead. See https://www.drupal.org/node/2993033.', E_USER_DEPRECATED); - if (empty($options['target'])) { - $options['target'] = NULL; - } - Database::closeConnection($options['target']); + Database::closeConnection(Database::getTarget($options, NULL)); } /** diff --git a/core/lib/Drupal/Core/Database/Connection.php b/core/lib/Drupal/Core/Database/Connection.php index e0a5d59d39..f45c359fd8 100644 --- a/core/lib/Drupal/Core/Database/Connection.php +++ b/core/lib/Drupal/Core/Database/Connection.php @@ -212,12 +212,6 @@ public function destroy() { * * A given query can be customized with a number of option flags in an * associative array: - * - target: The database "target" against which to execute a query. Valid - * values are "default" or "replica". The system will first try to open a - * connection to a database specified with the user-supplied key. If one - * is not available, it will silently fall back to the "default" target. - * If multiple databases connections are specified with the same target, - * one will be selected at random for the duration of the request. * - fetch: This element controls how rows from a result set will be * returned. Legal values include PDO::FETCH_ASSOC, PDO::FETCH_BOTH, * PDO::FETCH_OBJ, PDO::FETCH_NUM, or a string representing the name of a @@ -260,7 +254,6 @@ public function destroy() { */ protected function defaultOptions() { return [ - 'target' => 'default', 'fetch' => \PDO::FETCH_OBJ, 'return' => Database::RETURN_STATEMENT, 'throw_exception' => TRUE, @@ -606,6 +599,9 @@ protected function filterComment($comment = '') { public function query($query, array $args = [], $options = []) { // Use default values if not already set. $options += $this->defaultOptions(); + if (isset($options['target'])) { + @trigger_error('Passing a \'target\' key to \\Drupal\\Core\\Database\\Connection::query $options argument is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, use \\Drupal\\Core\\Database\\Database::getConnection($target)->query(). See https://www.drupal.org/node/2993033.', E_USER_DEPRECATED); + } try { // We allow either a pre-bound statement object or a literal string. diff --git a/core/lib/Drupal/Core/Database/Database.php b/core/lib/Drupal/Core/Database/Database.php index d13ea80862..b1cda71323 100644 --- a/core/lib/Drupal/Core/Database/Database.php +++ b/core/lib/Drupal/Core/Database/Database.php @@ -511,4 +511,39 @@ protected static function getDatabaseDriverNamespace(array $connection_info) { return 'Drupal\\Core\\Database\\Driver\\' . $connection_info['driver']; } + /** + * Get target helper. + * + * Helps get "target" database from the query options. + * + * @param array $options + * An array of options to control how the query operates. + * @param string|null $default + * The default database target name. + * @param string[] $default_aliases + * Aliases for the target that should be recognized as a default target. + * For cases like target "replica" that should be changed to the "default". + * + * @return mixed|string + * The target database for the database connection. + */ + public static function getTarget(array &$options, $default = 'default', array $default_aliases = []) { + if (empty($options['target'])) { + $target = $default; + } + else { + $target = $options['target']; + if (!empty($default_aliases)) { + foreach ($default_aliases as $alias) { + if ($target === $alias) { + $target = $default; + break; + } + } + } + } + unset($options['target']); + return $target; + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Database/DatabaseLegacyTest.php b/core/tests/Drupal/KernelTests/Core/Database/DatabaseLegacyTest.php index dd80305f1e..becc74e001 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/DatabaseLegacyTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/DatabaseLegacyTest.php @@ -428,6 +428,24 @@ public function testDbTruncate() { $this->assertInstanceOf(Truncate::class, db_truncate('test')); } + /** + * Tests deprecation of the $options 'target' key in Connection::query. + * + * @expectedDeprecation Passing a 'target' key to \Drupal\Core\Database\Connection::query $options argument is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, use \Drupal\Core\Database\Database::getConnection($target)->query(). See https://www.drupal.org/node/2993033. + */ + public function testDbOptionsTarget() { + $this->assertNotNull($this->connection->query('SELECT * FROM {test}', [], ['target' => 'bar'])); + } + + /** + * Tests deprecation of the $options 'target' key in Select. + * + * @expectedDeprecation Passing a 'target' key to \Drupal\Core\Database\Connection::query $options argument is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, use \Drupal\Core\Database\Database::getConnection($target)->query(). See https://www.drupal.org/node/2993033. + */ + public function testDbOptionsTargetInSelect() { + $this->assertNotNull($this->connection->select('test', 't', ['target' => 'bar'])->fields('t')->execute()); + } + /** * Tests deprecation of the db_query_temporary() function. *