Issue #3256524 by mondrake: [11.x] Adjust Database API to remove deprecated Drupal 10 code in Drupal 11

merge-requests/6513/merge
catch 2024-03-01 12:27:10 +00:00
parent bb733ec667
commit 6490db8069
99 changed files with 115 additions and 4588 deletions

View File

@ -958,16 +958,7 @@ function install_get_form($form_id, array &$install_state) {
// values taken from the installation state.
$install_form_id = $form_builder->getFormId($form_id, $form_state);
if (!empty($install_state['forms'][$install_form_id])) {
$values = $install_state['forms'][$install_form_id];
if ($install_form_id === 'install_settings_form' && isset($values['driver']) && !str_contains($values['driver'], "\\")) {
@trigger_error("Passing a database driver name '{$values['driver']}' to " . __FUNCTION__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Pass a database driver namespace instead. See https://www.drupal.org/node/3258175', E_USER_DEPRECATED);
$driverExtension = Database::getDriverList()->getFromDriverName($values['driver']);
$tmp = [];
$tmp['driver'] = $driverExtension->getName();
$tmp[$driverExtension->getName()] = $values[$values['driver']];
$values = $tmp;
}
$form_state->setValues($values);
$form_state->setValues($install_state['forms'][$install_form_id]);
}
$form_builder->submitForm($form_id, $form_state);

View File

@ -141,109 +141,6 @@ function drupal_install_profile_distribution_version() {
}
}
/**
* Detects all supported databases that are compiled into PHP.
*
* @return array
* An array of database types compiled into PHP.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* DatabaseDriverList::getList() instead.
*
* @see https://www.drupal.org/node/3258175
*/
function drupal_detect_database_types() {
@trigger_error('drupal_detect_database_types() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use DatabaseDriverList::getList() instead. See https://www.drupal.org/node/3258175', E_USER_DEPRECATED);
$databases = drupal_get_database_types();
foreach ($databases as $driver => $installer) {
$databases[$driver] = $installer->name();
}
return $databases;
}
/**
* Returns all supported database driver installer objects.
*
* @return \Drupal\Core\Database\Install\Tasks[]
* An array of available database driver installer objects.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* DatabaseDriverList::getList() instead.
*
* @see https://www.drupal.org/node/3258175
*/
function drupal_get_database_types() {
@trigger_error('drupal_get_database_types() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use DatabaseDriverList::getList() instead. See https://www.drupal.org/node/3258175', E_USER_DEPRECATED);
$databases = [];
$drivers = [];
// The internal database driver name is any valid PHP identifier.
$mask = ExtensionDiscovery::PHP_FUNCTION_PATTERN;
// Find drivers in the Drupal\Driver namespace.
// @todo remove discovering in the Drupal\Driver namespace in D10.
/** @var \Drupal\Core\File\FileSystemInterface $file_system */
$file_system = \Drupal::service('file_system');
$files = [];
if (is_dir(DRUPAL_ROOT . '/drivers/lib/Drupal/Driver/Database')) {
$files = $file_system->scanDirectory(DRUPAL_ROOT . '/drivers/lib/Drupal/Driver/Database/', $mask, ['recurse' => FALSE]);
}
foreach ($files as $file) {
if (file_exists($file->uri . '/Install/Tasks.php')) {
// The namespace doesn't need to be added here, because
// db_installer_object() will find it.
$drivers[$file->filename] = NULL;
}
}
// Find drivers in Drupal module namespaces.
/** @var \Composer\Autoload\ClassLoader $class_loader */
$class_loader = \Drupal::service('class_loader');
// We cannot use the file cache because it does not always exist.
$extension_discovery = new ExtensionDiscovery(DRUPAL_ROOT, FALSE, []);
$modules = $extension_discovery->scan('module');
foreach ($modules as $module) {
$module_driver_path = DRUPAL_ROOT . '/' . $module->getPath() . '/src/Driver/Database';
if (is_dir($module_driver_path)) {
$driver_files = $file_system->scanDirectory($module_driver_path, $mask, ['recurse' => FALSE]);
foreach ($driver_files as $driver_file) {
$tasks_file = $module_driver_path . '/' . $driver_file->filename . '/Install/Tasks.php';
if (file_exists($tasks_file)) {
$namespace = 'Drupal\\' . $module->getName() . '\\Driver\\Database\\' . $driver_file->filename;
// Add the driver with its own classes' namespace.
$drivers[$driver_file->filename] = $namespace;
// The directory needs to be added to the autoloader, because this is
// early in the installation process: the module hasn't been enabled
// yet and the database connection info array (including its 'autoload'
// key) hasn't been created yet.
$class_loader->addPsr4($namespace . '\\', $module->getPath() . '/src/Driver/Database/' . $driver_file->filename);
}
}
}
}
foreach ($drivers as $driver => $namespace) {
$installer_class = $namespace . "\\Install\\Tasks";
$installer = new $installer_class();
if ($installer->installable()) {
$databases[$driver] = $installer;
}
}
// Usability: unconditionally put the MySQL driver on top.
if (isset($databases['mysql'])) {
$mysql_database = $databases['mysql'];
unset($databases['mysql']);
$databases = ['mysql' => $mysql_database] + $databases;
}
return $databases;
}
/**
* Replaces values in settings.php with values in the submitted array.
*
@ -1080,46 +977,3 @@ function install_profile_info($profile, $langcode = 'en') {
}
return $cache[$profile][$langcode];
}
/**
* Returns a database installer object.
*
* Before calling this function it is important the database installer object
* is autoloadable. Database drivers provided by contributed modules are added
* to the autoloader in drupal_get_database_types() and Settings::initialize().
*
* @param $driver
* The name of the driver.
* @param string $namespace
* (optional) The database driver namespace.
*
* @return \Drupal\Core\Database\Install\Tasks
* A class defining the requirements and tasks for installing the database.
*
* @deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is no
* replacement.
*
* @see https://www.drupal.org/node/3256641
* @see drupal_get_database_types()
* @see \Drupal\Core\Site\Settings::initialize()
*/
function db_installer_object($driver, $namespace = NULL) {
@trigger_error('db_installer_object() is deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3256641', E_USER_DEPRECATED);
// We cannot use Database::getConnection->getDriverClass() here, because
// the connection object is not yet functional.
if ($namespace) {
$task_class = $namespace . "\\Install\\Tasks";
return new $task_class();
}
// Old Drupal 8 style contrib namespace.
$task_class = "Drupal\\Driver\\Database\\{$driver}\\Install\\Tasks";
if (class_exists($task_class)) {
return new $task_class();
}
else {
// Core provided driver.
$task_class = "Drupal\\Core\\Database\\Driver\\{$driver}\\Install\\Tasks";
return new $task_class();
}
}

View File

@ -131,6 +131,7 @@ class InstallCommand extends Command {
* The command exit status.
*/
protected function install($class_loader, SymfonyStyle $io, $profile, $langcode, $site_path, $site_name) {
$sqliteDriverNamespace = 'Drupal\\sqlite\\Driver\\Database\\sqlite';
$password = Crypt::randomBytesBase64(12);
$parameters = [
'interactive' => FALSE,
@ -141,8 +142,8 @@ class InstallCommand extends Command {
],
'forms' => [
'install_settings_form' => [
'driver' => 'sqlite',
'sqlite' => [
'driver' => $sqliteDriverNamespace,
$sqliteDriverNamespace => [
'database' => $site_path . '/files/.sqlite',
],
],

View File

@ -2,7 +2,6 @@
namespace Drupal\Core\Config;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\DatabaseException;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
@ -152,10 +151,7 @@ class DatabaseStorage implements StorageInterface {
* @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)
return (bool) $this->connection->merge($this->table, $this->options)
->keys(['collection', 'name'], [$this->collection, $name])
->fields(['data' => $data])
->execute();
@ -229,10 +225,7 @@ class DatabaseStorage implements StorageInterface {
* @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)
return (bool) $this->connection->delete($this->table, $this->options)
->condition('collection', $this->collection)
->condition('name', $name)
->execute();
@ -244,10 +237,7 @@ class DatabaseStorage implements StorageInterface {
* @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)
return (bool) $this->connection->update($this->table, $this->options)
->fields(['name' => $new_name])
->condition('name', $name)
->condition('collection', $this->collection)
@ -300,10 +290,7 @@ class DatabaseStorage implements StorageInterface {
*/
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)
return (bool) $this->connection->delete($this->table, $this->options)
->condition('name', $prefix . '%', 'LIKE')
->condition('collection', $this->collection)
->execute();

View File

@ -55,22 +55,6 @@ abstract class Connection {
*/
protected $logger = NULL;
/**
* Tracks the number of "layers" of transactions currently active.
*
* On many databases transactions cannot nest. Instead, we track
* nested calls to transactions and collapse them into a single
* transaction.
*
* @var array
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. The
* transaction stack is now managed by TransactionManager.
*
* @see https://www.drupal.org/node/3381002
*/
protected $transactionLayers = [];
/**
* Index of what driver-specific class to use for various operations.
*
@ -134,54 +118,6 @@ abstract class Connection {
*/
protected array $tablePlaceholderReplacements;
/**
* The prefixes used by this database connection.
*
* @var array
*
* @deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is
* no replacement.
*
* @see https://www.drupal.org/node/3257198
*/
protected $prefixes = [];
/**
* List of search values for use in prefixTables().
*
* @var array
*
* @deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is
* no replacement.
*
* @see https://www.drupal.org/node/3257198
*/
protected $prefixSearch = [];
/**
* List of replacement values for use in prefixTables().
*
* @var array
*
* @deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is
* no replacement.
*
* @see https://www.drupal.org/node/3257198
*/
protected $prefixReplace = [];
/**
* List of un-prefixed table names, keyed by prefixed table names.
*
* @var array
*
* @deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is
* no replacement.
*
* @see https://www.drupal.org/node/3257198
*/
protected $unprefixedTablesMap = [];
/**
* List of escaped table names, keyed by unescaped names.
*
@ -206,18 +142,6 @@ abstract class Connection {
*/
protected $escapedAliases = [];
/**
* Post-root (non-nested) transaction commit callbacks.
*
* @var callable[]
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. The
* transaction end callbacks are now managed by TransactionManager.
*
* @see https://www.drupal.org/node/3381002
*/
protected $rootTransactionEndCallbacks = [];
/**
* The identifier quote characters for the database type.
*
@ -240,7 +164,7 @@ abstract class Connection {
/**
* The transaction manager.
*/
protected TransactionManagerInterface|FALSE $transactionManager;
protected TransactionManagerInterface $transactionManager;
/**
* Constructs a Connection object.
@ -302,19 +226,9 @@ abstract class Connection {
*/
public function commitAll() {
$manager = $this->transactionManager();
if ($manager && $manager->inTransaction() && method_exists($manager, 'commitAll')) {
if ($manager->inTransaction() && method_exists($manager, 'commitAll')) {
$this->transactionManager()->commitAll();
}
// BC layer.
// @phpstan-ignore-next-line
if (!empty($this->transactionLayers)) {
// Make all transactions committable.
// @phpstan-ignore-next-line
$this->transactionLayers = array_fill_keys(array_keys($this->transactionLayers), FALSE);
// @phpstan-ignore-next-line
$this->popCommittableTransactions();
}
}
/**
@ -342,27 +256,6 @@ abstract class Connection {
* 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: (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
* query.
* - Database::RETURN_AFFECTED: Return the number of rows found (matched) by
* the WHERE clause of an UPDATE or DELETE query (not the number of rows
* actually changed). Note that although named RETURN_AFFECTED for
* historical reasons, the number of rows matched is returned for
* consistency across database engines.
* - Database::RETURN_INSERT_ID: Return the sequence ID (primary key)
* created by an INSERT statement on a table that contains a serial
* column.
* - Database::RETURN_NULL: Do not return anything, as there is no
* meaningful value to return. That is the case for INSERT queries on
* tables that do not contain a serial column.
* - allow_delimiter_in_query: By default, queries which have the ; delimiter
* any place in them will cause an exception. This reduces the chance of SQL
* injection attacks that terminate the original query and add one or more
@ -496,42 +389,6 @@ abstract class Connection {
return str_replace(['[', ']'], $this->identifierQuotes, $sql);
}
/**
* Find the prefix for a table.
*
* This function is for when you want to know the prefix of a table. This
* is not used in prefixTables due to performance reasons.
*
* @param string $table
* (optional) The table to find the prefix for.
*
* @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0.
* Instead, you should just use Connection::getPrefix().
*
* @see https://www.drupal.org/node/3260849
*/
public function tablePrefix($table = 'default') {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Instead, you should just use Connection::getPrefix(). See https://www.drupal.org/node/3260849', E_USER_DEPRECATED);
return $this->prefix;
}
/**
* Gets a list of individually prefixed table names.
*
* @return array
* An array of un-prefixed table names, keyed by their fully qualified table
* names (i.e. prefix + table_name).
*
* @deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is
* no replacement.
*
* @see https://www.drupal.org/node/3257198
*/
public function getUnprefixedTablesMap() {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3257198', E_USER_DEPRECATED);
return $this->unprefixedTablesMap;
}
/**
* Get a fully qualified table name.
*
@ -573,9 +430,7 @@ abstract class Connection {
* @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);
}
assert(!isset($options['return']), 'Passing "return" option to prepareStatement() has no effect. See https://www.drupal.org/node/3185520');
try {
$query = $this->preprocessStatement($query, $options);
@ -704,39 +559,6 @@ abstract class Connection {
return $this->logger;
}
/**
* Creates the appropriate sequence name for a given table and serial field.
*
* This information is exposed to all database drivers, although it is only
* useful on some of them. This method is table prefix-aware.
*
* Note that if a sequence was generated automatically by the database, its
* name might not match the one returned by this function. Therefore, in those
* cases, it is generally advised to use a database-specific way of retrieving
* the name of an auto-created sequence. For example, PostgreSQL provides a
* dedicated function for this purpose: pg_get_serial_sequence().
*
* @param string $table
* The table name to use for the sequence.
* @param string $field
* The field name to use for the sequence.
*
* @return string
* A table prefix-parsed string for the sequence name.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. There is
* no replacement.
*
* @see https://www.drupal.org/node/3377046
*/
public function makeSequenceName($table, $field) {
@trigger_error(__METHOD__ . "() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3377046", E_USER_DEPRECATED);
$sequence_name = $this->prefixTables('{' . $table . '}_' . $field . '_seq');
// Remove identifier quotes as we are constructing a new name from a
// prefixed and quoted table name.
return str_replace($this->identifierQuotes, '', $sequence_name);
}
/**
* Flatten an array of query comments into a single comment string.
*
@ -814,17 +636,8 @@ abstract class Connection {
* Typically, $options['return'] will be set by a default or by a query
* builder, and should not be set by a user.
*
* @return \Drupal\Core\Database\StatementInterface|int|string|null
* This method will return one of the following:
* - If either $options['return'] === self::RETURN_STATEMENT, or
* $options['return'] is not set (due to self::defaultOptions()),
* returns the executed statement.
* - If $options['return'] === self::RETURN_AFFECTED,
* returns the number of rows matched by the query
* (not the number affected).
* - If $options['return'] === self::RETURN_INSERT_ID,
* returns the generated insert ID of the last query as a string.
* - If $options['return'] === self::RETURN_NULL, returns NULL.
* @return \Drupal\Core\Database\StatementInterface|null
* The executed statement.
*
* @throws \Drupal\Core\Database\DatabaseExceptionWrapper
* @throws \Drupal\Core\Database\IntegrityConstraintViolationException
@ -834,54 +647,22 @@ abstract class Connection {
*/
public function query($query, array $args = [], $options = []) {
assert(is_string($query), 'The \'$query\' argument to ' . __METHOD__ . '() must be a string');
assert(!isset($options['return']), 'Passing "return" option to query() has no effect. See https://www.drupal.org/node/3185520');
assert(!isset($options['target']), 'Passing "target" option to query() has no effect. See https://www.drupal.org/node/2993033');
// 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');
$this->expandArguments($query, $args);
$stmt = $this->prepareStatement($query, $options);
$statement = $this->prepareStatement($query, $options);
try {
$stmt->execute($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.
// @todo the block below is deprecated and as of Drupal 11 will be
// removed, query() will only return a StatementInterface object.
// @see https://www.drupal.org/project/drupal/issues/3256524
switch ($options['return'] ?? Database::RETURN_STATEMENT) {
case Database::RETURN_STATEMENT:
return $stmt;
// Database::RETURN_AFFECTED should not be used; enable row counting
// by passing the appropriate argument to the constructor instead.
// @see https://www.drupal.org/node/3186368
case Database::RETURN_AFFECTED:
$stmt->allowRowCount = TRUE;
return $stmt->rowCount();
case Database::RETURN_INSERT_ID:
$sequence_name = $options['sequence_name'] ?? NULL;
return $this->lastInsertId($sequence_name);
case Database::RETURN_NULL:
return NULL;
default:
throw new \PDOException('Invalid return directive: ' . $options['return']);
}
$result = $statement->execute($args, $options);
}
catch (\Exception $e) {
$this->exceptionHandler()->handleExecutionException($e, $stmt, $args, $options);
$this->exceptionHandler()->handleExecutionException($e, $statement, $args, $options);
$result = FALSE;
}
return $result ? $statement : NULL;
}
/**
@ -972,7 +753,7 @@ abstract class Connection {
'Truncate',
'Schema',
'Condition',
'Transaction' => @trigger_error('Calling ' . __METHOD__ . '() for \'' . $class . '\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use standard autoloading in the methods that return database operations. See https://www.drupal.org/node/3217534', E_USER_DEPRECATED),
'Transaction' => throw new InvalidQueryException('Calling ' . __METHOD__ . '() for \'' . $class . '\' is not supported. Use standard autoloading in the methods that return database operations. See https://www.drupal.org/node/3217534'),
default => NULL,
};
if (empty($this->driverClasses[$class])) {
@ -1039,12 +820,9 @@ abstract class Connection {
*
* @return \Drupal\Core\Database\ExceptionHandler
* The database exceptions handler.
*
* @todo in drupal:11.0.0, return a new ExceptionHandler instance directly.
*/
public function exceptionHandler() {
$class = $this->getDriverClass('ExceptionHandler');
return new $class();
return new ExceptionHandler();
}
/**
@ -1065,13 +843,10 @@ abstract class Connection {
* driver.
*
* @see \Drupal\Core\Database\Query\Select
*
* @todo in drupal:11.0.0, return a new Query\Select instance directly.
*/
public function select($table, $alias = NULL, array $options = []) {
assert(is_string($alias) || $alias === NULL, 'The \'$alias\' argument to ' . __METHOD__ . '() must be a string or NULL');
$class = $this->getDriverClass('Select');
return new $class($this, $table, $alias, $options);
return new Select($this, $table, $alias, $options);
}
/**
@ -1089,12 +864,9 @@ abstract class Connection {
*
* @see \Drupal\Core\Database\Query\Insert
* @see \Drupal\Core\Database\Connection::defaultOptions()
*
* @todo in drupal:11.0.0, return a new Query\Insert instance directly.
*/
public function insert($table, array $options = []) {
$class = $this->getDriverClass('Insert');
return new $class($this, $table, $options);
return new Insert($this, $table, $options);
}
/**
@ -1139,12 +911,9 @@ abstract class Connection {
* A new Merge query object.
*
* @see \Drupal\Core\Database\Query\Merge
*
* @todo in drupal:11.0.0, return a new Query\Merge instance directly.
*/
public function merge($table, array $options = []) {
$class = $this->getDriverClass('Merge');
return new $class($this, $table, $options);
return new Merge($this, $table, $options);
}
/**
@ -1159,14 +928,8 @@ abstract class Connection {
* A new Upsert query object.
*
* @see \Drupal\Core\Database\Query\Upsert
*
* @todo in drupal:11.0.0, make this method abstract since Query\Upsert is
* an abstract class.
*/
public function upsert($table, array $options = []) {
$class = $this->getDriverClass('Upsert');
return new $class($this, $table, $options);
}
abstract public function upsert($table, array $options = []);
/**
* Prepares and returns an UPDATE query object.
@ -1183,12 +946,9 @@ abstract class Connection {
*
* @see \Drupal\Core\Database\Query\Update
* @see \Drupal\Core\Database\Connection::defaultOptions()
*
* @todo in drupal:11.0.0, return a new Query\Update instance directly.
*/
public function update($table, array $options = []) {
$class = $this->getDriverClass('Update');
return new $class($this, $table, $options);
return new Update($this, $table, $options);
}
/**
@ -1206,12 +966,9 @@ abstract class Connection {
*
* @see \Drupal\Core\Database\Query\Delete
* @see \Drupal\Core\Database\Connection::defaultOptions()
*
* @todo in drupal:11.0.0, return a new Query\Delete instance directly.
*/
public function delete($table, array $options = []) {
$class = $this->getDriverClass('Delete');
return new $class($this, $table, $options);
return new Delete($this, $table, $options);
}
/**
@ -1226,12 +983,9 @@ abstract class Connection {
* A new Truncate query object.
*
* @see \Drupal\Core\Database\Query\Truncate
*
* @todo in drupal:11.0.0, return a new Query\Truncate instance directly.
*/
public function truncate($table, array $options = []) {
$class = $this->getDriverClass('Truncate');
return new $class($this, $table, $options);
return new Truncate($this, $table, $options);
}
/**
@ -1241,17 +995,8 @@ abstract class Connection {
*
* @return \Drupal\Core\Database\Schema
* The database Schema object for this connection.
*
* @todo in drupal:11.0.0, make this method abstract since Schema is
* an abstract class.
*/
public function schema() {
if (empty($this->schema)) {
$class = $this->getDriverClass('Schema');
$this->schema = new $class($this);
}
return $this->schema;
}
abstract public function schema();
/**
* Prepares and returns a CONDITION query object.
@ -1263,15 +1008,12 @@ abstract class Connection {
* A new Condition query object.
*
* @see \Drupal\Core\Database\Query\Condition
*
* @todo in drupal:11.0.0, return a new Condition instance directly.
*/
public function condition($conjunction) {
$class = $this->getDriverClass('Condition');
// Creating an instance of the class Drupal\Core\Database\Query\Condition
// should only be created from the database layer. This will allow database
// drivers to override the default Condition class.
return new $class($conjunction);
return new Condition($conjunction);
}
/**
@ -1395,17 +1137,15 @@ abstract class Connection {
/**
* Returns the transaction manager.
*
* @return \Drupal\Core\Database\Transaction\TransactionManagerInterface|false
* @return \Drupal\Core\Database\Transaction\TransactionManagerInterface
* The transaction manager, or FALSE if not available.
*
* @throws \LogicException
* If the transaction manager is undefined or unavailable.
*/
public function transactionManager(): TransactionManagerInterface|FALSE {
public function transactionManager(): TransactionManagerInterface {
if (!isset($this->transactionManager)) {
try {
$this->transactionManager = $this->driverTransactionManager();
}
catch (\LogicException $e) {
$this->transactionManager = FALSE;
}
$this->transactionManager = $this->driverTransactionManager();
}
return $this->transactionManager;
}
@ -1434,32 +1174,7 @@ abstract class Connection {
* TRUE if we're currently in a transaction, FALSE otherwise.
*/
public function inTransaction() {
if ($this->transactionManager()) {
return $this->transactionManager()->inTransaction();
}
// Start of BC layer.
// @phpstan-ignore-next-line
return ($this->transactionDepth() > 0);
// End of BC layer.
}
/**
* Determines the current transaction depth.
*
* @return int
* The current transaction depth.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Do not
* access the transaction stack depth, it is an implementation detail.
*
* @see https://www.drupal.org/node/3381002
*/
public function transactionDepth() {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Do not access the transaction stack depth, it is an implementation detail. See https://www.drupal.org/node/3381002', E_USER_DEPRECATED);
if ($this->transactionManager()) {
return $this->transactionManager()->stackDepth();
}
return count($this->transactionLayers);
return $this->transactionManager()->inTransaction();
}
/**
@ -1472,248 +1187,9 @@ abstract class Connection {
* A Transaction object.
*
* @see \Drupal\Core\Database\Transaction
*
* @todo in drupal:11.0.0, push to the TransactionManager directly.
*/
public function startTransaction($name = '') {
if ($this->transactionManager()) {
return $this->transactionManager()->push($name);
}
$class = $this->getDriverClass('Transaction');
return new $class($this, $name);
}
/**
* Rolls back the transaction entirely or to a named savepoint.
*
* This method throws an exception if no transaction is active.
*
* @param string $savepoint_name
* (optional) The name of the savepoint. The default, 'drupal_transaction',
* will roll the entire transaction back.
*
* @throws \Drupal\Core\Database\TransactionOutOfOrderException
* @throws \Drupal\Core\Database\TransactionNoActiveException
*
* @see \Drupal\Core\Database\Transaction::rollBack()
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Do not
* rollback the connection, roll back the Transaction objects instead.
*
* @see https://www.drupal.org/node/3381002
*/
public function rollBack($savepoint_name = 'drupal_transaction') {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Do not rollback the connection, roll back the Transaction objects instead. See https://www.drupal.org/node/3381002', E_USER_DEPRECATED);
if ($this->transactionManager()) {
$this->transactionManager()->rollback($savepoint_name, 'bc-force-rollback');
return;
}
if (!$this->inTransaction()) {
throw new TransactionNoActiveException();
}
// A previous rollback to an earlier savepoint may mean that the savepoint
// in question has already been accidentally committed.
if (!isset($this->transactionLayers[$savepoint_name])) {
throw new TransactionNoActiveException();
}
// We need to find the point we're rolling back to, all other savepoints
// before are no longer needed. If we rolled back other active savepoints,
// we need to throw an exception.
$rolled_back_other_active_savepoints = FALSE;
while ($savepoint = array_pop($this->transactionLayers)) {
if ($savepoint == $savepoint_name) {
// If it is the last the transaction in the stack, then it is not a
// savepoint, it is the transaction itself so we will need to roll back
// the transaction rather than a savepoint.
if (empty($this->transactionLayers)) {
break;
}
$this->query('ROLLBACK TO SAVEPOINT ' . $savepoint);
$this->popCommittableTransactions();
if ($rolled_back_other_active_savepoints) {
throw new TransactionOutOfOrderException();
}
return;
}
else {
$rolled_back_other_active_savepoints = TRUE;
}
}
// Notify the callbacks about the rollback.
$callbacks = $this->rootTransactionEndCallbacks;
$this->rootTransactionEndCallbacks = [];
foreach ($callbacks as $callback) {
call_user_func($callback, FALSE);
}
$this->connection->rollBack();
if ($rolled_back_other_active_savepoints) {
throw new TransactionOutOfOrderException();
}
}
/**
* Increases the depth of transaction nesting.
*
* If no transaction is already active, we begin a new transaction.
*
* @param string $name
* The name of the transaction.
*
* @throws \Drupal\Core\Database\TransactionNameNonUniqueException
*
* @see \Drupal\Core\Database\Transaction
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* TransactionManagerInterface methods instead.
*
* @see https://www.drupal.org/node/3381002
*/
public function pushTransaction($name) {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface methods instead. See https://www.drupal.org/node/3381002', E_USER_DEPRECATED);
if (isset($this->transactionLayers[$name])) {
throw new TransactionNameNonUniqueException($name . " is already in use.");
}
// If we're already in a transaction then we want to create a savepoint
// rather than try to create another transaction.
if ($this->inTransaction()) {
$this->query('SAVEPOINT ' . $name);
}
else {
$this->connection->beginTransaction();
}
$this->transactionLayers[$name] = $name;
}
/**
* Decreases the depth of transaction nesting.
*
* If we pop off the last transaction layer, then we either commit or roll
* back the transaction as necessary. If no transaction is active, we return
* because the transaction may have manually been rolled back.
*
* @param string $name
* The name of the savepoint.
*
* @throws \Drupal\Core\Database\TransactionNoActiveException
* @throws \Drupal\Core\Database\TransactionCommitFailedException
*
* @see \Drupal\Core\Database\Transaction
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* TransactionManagerInterface methods instead.
*
* @see https://www.drupal.org/node/3381002
*/
public function popTransaction($name) {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface methods instead. See https://www.drupal.org/node/3381002', E_USER_DEPRECATED);
// The transaction has already been committed earlier. There is nothing we
// need to do. If this transaction was part of an earlier out-of-order
// rollback, an exception would already have been thrown by
// Database::rollBack().
if (!isset($this->transactionLayers[$name])) {
return;
}
// Mark this layer as committable.
$this->transactionLayers[$name] = FALSE;
$this->popCommittableTransactions();
}
/**
* Adds a root transaction end callback.
*
* These callbacks are invoked immediately after the transaction has been
* committed.
*
* It can for example be used to avoid deadlocks on write-heavy tables that
* do not need to be part of the transaction, like cache tag invalidations.
*
* Another use case is that services using alternative backends like Redis and
* Memcache cache implementations can replicate the transaction-behavior of
* the database cache backend and avoid race conditions.
*
* An argument is passed to the callbacks that indicates whether the
* transaction was successful or not.
*
* @param callable $callback
* The callback to invoke.
*
* @see \Drupal\Core\Database\Connection::doCommit()
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* TransactionManagerInterface::addPostTransactionCallback() instead.
*
* @see https://www.drupal.org/node/3381002
*/
public function addRootTransactionEndCallback(callable $callback) {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface::addPostTransactionCallback() instead. See https://www.drupal.org/node/3381002', E_USER_DEPRECATED);
if ($this->transactionManager()) {
$this->transactionManager()->addPostTransactionCallback($callback);
return;
}
if (!$this->transactionLayers) {
throw new \LogicException('Root transaction end callbacks can only be added when there is an active transaction.');
}
$this->rootTransactionEndCallbacks[] = $callback;
}
/**
* Commit all the transaction layers that can commit.
*
* @internal
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* TransactionManagerInterface methods instead.
*
* @see https://www.drupal.org/node/3381002
*/
protected function popCommittableTransactions() {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface methods instead. See https://www.drupal.org/node/3381002', E_USER_DEPRECATED);
// Commit all the committable layers.
foreach (array_reverse($this->transactionLayers) as $name => $active) {
// Stop once we found an active transaction.
if ($active) {
break;
}
// If there are no more layers left then we should commit.
unset($this->transactionLayers[$name]);
if (empty($this->transactionLayers)) {
$this->doCommit();
}
else {
$this->query('RELEASE SAVEPOINT ' . $name);
}
}
}
/**
* Do the actual commit, invoke post-commit callbacks.
*
* @internal
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* TransactionManagerInterface methods instead.
*
* @see https://www.drupal.org/node/3381002
*/
protected function doCommit() {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface methods instead. See https://www.drupal.org/node/3381002', E_USER_DEPRECATED);
$success = $this->connection->commit();
if (!empty($this->rootTransactionEndCallbacks)) {
$callbacks = $this->rootTransactionEndCallbacks;
$this->rootTransactionEndCallbacks = [];
foreach ($callbacks as $callback) {
call_user_func($callback, $success);
}
}
if (!$success) {
throw new TransactionCommitFailedException();
}
return $this->transactionManager()->push($name);
}
/**
@ -1828,52 +1304,6 @@ abstract class Connection {
*/
abstract public function mapConditionOperator($operator);
/**
* Throws an exception to deny direct access to transaction commits.
*
* We do not want to allow users to commit transactions at any time, only
* by destroying the transaction object or allowing it to go out of scope.
* A direct commit bypasses all of the safety checks we've built on top of
* the database client's transaction routines.
*
* @throws \Drupal\Core\Database\TransactionExplicitCommitNotAllowedException
*
* @see \Drupal\Core\Database\Transaction
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Do not
* commit the connection, void the Transaction objects instead.
*
* @see https://www.drupal.org/node/3381002
*/
public function commit() {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Do not commit the connection, void the Transaction objects instead. See https://www.drupal.org/node/3381002', E_USER_DEPRECATED);
throw new TransactionExplicitCommitNotAllowedException();
}
/**
* Retrieves a unique ID from a given sequence.
*
* Use this function if for some reason you can't use a serial field. For
* example, MySQL has no ways of reading of the current value of a sequence
* and PostgreSQL can not advance the sequence to be larger than a given
* value. Or sometimes you just need a unique integer.
*
* @param $existing_id
* (optional) After a database import, it might be that the sequences table
* is behind, so by passing in the maximum existing ID, it can be assured
* that we never issue the same ID.
*
* @return int|string
* An integer number larger than any number returned by earlier calls and
* also larger than the $existing_id if one was passed in.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Modules
* should use instead the keyvalue storage for the last used id.
*
* @see https://www.drupal.org/node/3349345
*/
abstract public function nextId($existing_id = 0);
/**
* Quotes a string for use in a query.
*

View File

@ -16,49 +16,6 @@ use Drupal\Core\Cache\NullBackend;
*/
abstract class Database {
/**
* Flag to indicate a query call should simply return NULL.
*
* 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 matched 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;
/**
* A nested array of active connections, keyed by database name and target.
*
@ -621,75 +578,6 @@ abstract class Database {
}
}
/**
* Finds the directory to add to the autoloader for the driver's namespace.
*
* For Drupal sites that manage their codebase with Composer, the package
* that provides the database driver should add the driver's namespace to
* Composer's autoloader. However, to support sites that add Drupal modules
* without Composer, and because the database connection must be established
* before Drupal adds the module's entire namespace to the autoloader, the
* database connection info array can include an "autoload" key containing
* the autoload directory for the driver's namespace. For requests that
* connect to the database via a connection info array, the value of the
* "autoload" key is automatically added to the autoloader.
*
* This method can be called to find the default value of that key when the
* database connection info array isn't available. This includes:
* - Console commands and test runners that connect to a database specified
* by a database URL rather than a connection info array.
* - During installation, prior to the connection info array being written to
* settings.php.
*
* This method returns the directory that must be added to the autoloader for
* the given namespace.
* - If the namespace is a sub-namespace of a Drupal module, then this method
* returns the autoload directory for that namespace, allowing Drupal
* modules containing database drivers to be added to a Drupal website
* without Composer.
* - If the namespace is a sub-namespace of Drupal\Core or Drupal\Driver,
* then this method returns FALSE, because Drupal core's autoloader already
* includes these namespaces, so no additional autoload directory is
* required for any code within them.
* - If the namespace is anything else, then this method returns FALSE,
* because neither drupal_get_database_types() nor
* static::convertDbUrlToConnectionInfo() support that anyway. One can
* manually edit the connection info array in settings.php to reference
* any arbitrary namespace, but requests using that would use the
* corresponding 'autoload' key in that connection info rather than calling
* this method.
*
* @param string $namespace
* The database driver's namespace.
* @param string $root
* The root directory of the Drupal installation.
* @param bool|null $include_test_drivers
* (optional) Whether to include test extensions. If FALSE, all 'tests'
* directories are excluded in the search. When NULL will be determined by
* the extension_discovery_scan_tests setting.
*
* @return string|false
* The PSR-4 directory to add to the autoloader for the namespace if the
* namespace is a sub-namespace of a Drupal module. FALSE otherwise, as
* explained above.
*
* @throws \RuntimeException
* Exception thrown when a module provided database driver does not exist.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* DatabaseDriverList::getList() instead.
*
* @see https://www.drupal.org/node/3258175
*/
public static function findDriverAutoloadDirectory($namespace, $root, ?bool $include_test_drivers = NULL) {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use DatabaseDriverList::getList() instead. See https://www.drupal.org/node/3258175', E_USER_DEPRECATED);
$autoload_info = static::getDriverList()
->includeTestDrivers($include_test_drivers)
->get($namespace)
->getAutoloadInfo();
return $autoload_info['autoload'] ?? FALSE;
}
/**
* Gets database connection info as a URL.
*
@ -708,46 +596,14 @@ abstract class Database {
throw new \RuntimeException("Database connection $key not defined or missing the 'default' settings");
}
$namespace = $db_info['default']['namespace'];
// If the driver namespace is within a Drupal module, add the module name
// to the connection options to make it easy for the connection class's
// createUrlFromConnectionOptions() method to add it to the URL.
if (static::isWithinModuleNamespace($namespace)) {
$db_info['default']['module'] = explode('\\', $namespace)[1];
}
// Add the module name to the connection options to make it easy for the
// connection class's createUrlFromConnectionOptions() method to add it to
// the URL.
$db_info['default']['module'] = explode('\\', $namespace)[1];
$connection_class = $namespace . '\\Connection';
return $connection_class::createUrlFromConnectionOptions($db_info['default']);
}
/**
* Checks whether a namespace is within the namespace of a Drupal module.
*
* This can be used to determine if a database driver's namespace is provided
* by a Drupal module.
*
* @param string $namespace
* The namespace (for example, of a database driver) to check.
*
* @return bool
* TRUE if the passed in namespace is a sub-namespace of a Drupal module's
* namespace.
*
* @todo remove in Drupal 11.
*
* @see https://www.drupal.org/node/3256524
*/
private static function isWithinModuleNamespace(string $namespace) {
[$first, $second] = explode('\\', $namespace, 3);
// The namespace for Drupal modules is Drupal\MODULE_NAME, and the module
// name must be all lowercase. Second-level namespaces containing uppercase
// letters (e.g., "Core", "Component", "Driver") are not modules.
// @see \Drupal\Core\DrupalKernel::getModuleNamespacesPsr4()
// @see https://www.drupal.org/docs/8/creating-custom-modules/naming-and-placing-your-drupal-8-module#s-name-your-module
return ($first === 'Drupal' && strtolower($second) === $second);
}
/**
* Calls commitAll() on all the open connections.
*

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\mysql;
use Drupal\mysql\Driver\Database\mysql\Connection as MysqlConnection;
@trigger_error('\Drupal\Core\Database\Driver\mysql\Connection is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* MySQL implementation of \Drupal\Core\Database\Connection.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL
* database driver has been moved to the mysql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Connection extends MysqlConnection {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\mysql;
use Drupal\mysql\Driver\Database\mysql\ExceptionHandler as MysqlExceptionHandler;
@trigger_error('\Drupal\Core\Database\Driver\mysql\ExceptionHandler is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* MySql database exception handler class.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL
* database driver has been moved to the mysql module.
*
* @see https://www.drupal.org/node/3129492
*/
class ExceptionHandler extends MysqlExceptionHandler {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\mysql;
use Drupal\mysql\Driver\Database\mysql\Insert as MysqlInsert;
@trigger_error('\Drupal\Core\Database\Driver\mysql\Insert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* MySQL implementation of \Drupal\Core\Database\Query\Insert.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL
* database driver has been moved to the mysql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Insert extends MysqlInsert {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\mysql\Install;
use Drupal\mysql\Driver\Database\mysql\Install\Tasks as MysqlTasks;
@trigger_error('\Drupal\Core\Database\Driver\mysql\Install\Tasks is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* Specifies installation tasks for MySQL and equivalent databases.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL
* database driver has been moved to the mysql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Tasks extends MysqlTasks {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\mysql;
use Drupal\mysql\Driver\Database\mysql\Schema as MysqlSchema;
@trigger_error('\Drupal\Core\Database\Driver\mysql\Schema is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* MySQL implementation of \Drupal\Core\Database\Schema.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL
* database driver has been moved to the mysql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Schema extends MysqlSchema {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\mysql;
use Drupal\mysql\Driver\Database\mysql\Upsert as MysqlUpsert;
@trigger_error('\Drupal\Core\Database\Driver\mysql\Upsert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* MySQL implementation of \Drupal\Core\Database\Query\Upsert.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL
* database driver has been moved to the mysql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Upsert extends MysqlUpsert {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\pgsql;
use Drupal\pgsql\Driver\Database\pgsql\Connection as PgsqlConnection;
@trigger_error('\Drupal\Core\Database\Driver\pgsql\Connection is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* PostgreSQL implementation of \Drupal\Core\Database\Connection.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL
* database driver has been moved to the pgsql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Connection extends PgsqlConnection {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\pgsql;
use Drupal\pgsql\Driver\Database\pgsql\Delete as PgsqlDelete;
@trigger_error('\Drupal\Core\Database\Driver\pgsql\Delete is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* PostgreSQL implementation of \Drupal\Core\Database\Query\Delete.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL
* database driver has been moved to the pgsql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Delete extends PgsqlDelete {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\pgsql;
use Drupal\pgsql\Driver\Database\pgsql\Insert as PgsqlInsert;
@trigger_error('\Drupal\Core\Database\Driver\pgsql\Insert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* PostgreSQL implementation of \Drupal\Core\Database\Query\Insert.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL
* database driver has been moved to the pgsql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Insert extends PgsqlInsert {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\pgsql\Install;
use Drupal\pgsql\Driver\Database\pgsql\Install\Tasks as PgsqlTasks;
@trigger_error('\Drupal\Core\Database\Driver\pgsql\Install\Tasks is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* Specifies installation tasks for PostgreSQL databases.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL
* database driver has been moved to the pgsql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Tasks extends PgsqlTasks {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\pgsql;
use Drupal\pgsql\Driver\Database\pgsql\Schema as PgsqlSchema;
@trigger_error('\Drupal\Core\Database\Driver\pgsql\Schema is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* PostgreSQL implementation of \Drupal\Core\Database\Schema.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL
* database driver has been moved to the pgsql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Schema extends PgsqlSchema {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\pgsql;
use Drupal\pgsql\Driver\Database\pgsql\Select as PgsqlSelect;
@trigger_error('\Drupal\Core\Database\Driver\pgsql\Select is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* PostgreSQL implementation of \Drupal\Core\Database\Query\Select.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL
* database driver has been moved to the pgsql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Select extends PgsqlSelect {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\pgsql;
use Drupal\pgsql\Driver\Database\pgsql\Truncate as PgsqlTruncate;
@trigger_error('\Drupal\Core\Database\Driver\pgsql\Truncate is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* PostgreSQL implementation of \Drupal\Core\Database\Query\Truncate.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL
* database driver has been moved to the pgsql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Truncate extends PgsqlTruncate {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\pgsql;
use Drupal\pgsql\Driver\Database\pgsql\Update as PgsqlUpdate;
@trigger_error('\Drupal\Core\Database\Driver\pgsql\Update is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* PostgreSQL implementation of \Drupal\Core\Database\Query\Update.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL
* database driver has been moved to the pgsql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Update extends PgsqlUpdate {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\pgsql;
use Drupal\pgsql\Driver\Database\pgsql\Upsert as PgsqlUpsert;
@trigger_error('\Drupal\Core\Database\Driver\pgsql\Upsert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* PostgreSQL implementation of \Drupal\Core\Database\Query\Upsert.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL
* database driver has been moved to the pgsql module.
*
* @see https://www.drupal.org/node/3129492
*/
class Upsert extends PgsqlUpsert {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\sqlite;
use Drupal\sqlite\Driver\Database\sqlite\Connection as SqliteConnection;
@trigger_error('\Drupal\Core\Database\Driver\sqlite\Connection is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Connection.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite
* database driver has been moved to the sqlite module.
*
* @see https://www.drupal.org/node/3129492
*/
class Connection extends SqliteConnection {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\sqlite;
use Drupal\sqlite\Driver\Database\sqlite\Insert as SqliteInsert;
@trigger_error('\Drupal\Core\Database\Driver\sqlite\Insert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Query\Insert.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite
* database driver has been moved to the sqlite module.
*
* @see https://www.drupal.org/node/3129492
*/
class Insert extends SqliteInsert {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\sqlite\Install;
use Drupal\sqlite\Driver\Database\sqlite\Install\Tasks as SqliteTasks;
@trigger_error('\Drupal\Core\Database\Driver\sqlite\Install\Tasks is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* Specifies installation tasks for SQLite databases.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite
* database driver has been moved to the sqlite module.
*
* @see https://www.drupal.org/node/3129492
*/
class Tasks extends SqliteTasks {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\sqlite;
use Drupal\sqlite\Driver\Database\sqlite\Schema as SqliteSchema;
@trigger_error('\Drupal\Core\Database\Driver\sqlite\Schema is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Schema.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite
* database driver has been moved to the sqlite module.
*
* @see https://www.drupal.org/node/3129492
*/
class Schema extends SqliteSchema {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\sqlite;
use Drupal\sqlite\Driver\Database\sqlite\Select as SqliteSelect;
@trigger_error('\Drupal\Core\Database\Driver\sqlite\Select is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Query\Select.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite
* database driver has been moved to the sqlite module.
*
* @see https://www.drupal.org/node/3129492
*/
class Select extends SqliteSelect {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\sqlite;
use Drupal\sqlite\Driver\Database\sqlite\Statement as SqliteStatement;
@trigger_error('\Drupal\Core\Database\Driver\sqlite\Statement is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Statement.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite
* database driver has been moved to the sqlite module.
*
* @see https://www.drupal.org/node/3129492
*/
class Statement extends SqliteStatement {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\sqlite;
use Drupal\sqlite\Driver\Database\sqlite\Truncate as SqliteTruncate;
@trigger_error('\Drupal\Core\Database\Driver\sqlite\Truncate is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Query\Truncate.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite
* database driver has been moved to the sqlite module.
*
* @see https://www.drupal.org/node/3129492
*/
class Truncate extends SqliteTruncate {}

View File

@ -1,17 +0,0 @@
<?php
namespace Drupal\Core\Database\Driver\sqlite;
use Drupal\sqlite\Driver\Database\sqlite\Upsert as SqliteUpsert;
@trigger_error('\Drupal\Core\Database\Driver\sqlite\Upsert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Query\Upsert.
*
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite
* database driver has been moved to the sqlite module.
*
* @see https://www.drupal.org/node/3129492
*/
class Upsert extends SqliteUpsert {}

View File

@ -42,27 +42,6 @@ trait FetchModeTrait {
\PDO::FETCH_OBJ,
];
/**
* Converts a row of data in FETCH_ASSOC format to FETCH_BOTH.
*
* @param array $rowAssoc
* A row of data in FETCH_ASSOC format.
*
* @return array
* The row in FETCH_BOTH format.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* supported modes only.
*
* @see https://www.drupal.org/node/3377999
*/
protected function assocToBoth(array $rowAssoc): array {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999', E_USER_DEPRECATED);
// \PDO::FETCH_BOTH returns an array indexed by both the column name
// and the column number.
return $rowAssoc + array_values($rowAssoc);
}
/**
* Converts a row of data in FETCH_ASSOC format to FETCH_NUM.
*
@ -110,52 +89,6 @@ trait FetchModeTrait {
return $classObj;
}
/**
* Converts a row of data to FETCH_CLASS | FETCH_CLASSTYPE.
*
* @param array $rowAssoc
* A row of data in FETCH_ASSOC format.
* @param array $constructorArguments
* Elements of this array are passed to the constructor.
*
* @return object
* The row in FETCH_CLASS format.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* supported modes only.
*
* @see https://www.drupal.org/node/3377999
*/
protected function assocToClassType(array $rowAssoc, array $constructorArguments): object {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999', E_USER_DEPRECATED);
$className = array_shift($rowAssoc);
return $this->assocToClass($rowAssoc, $className, $constructorArguments);
}
/**
* Fills an object with data from a FETCH_ASSOC row.
*
* @param array $rowAssoc
* A row of data in FETCH_ASSOC format.
* @param object $object
* The object receiving the data.
*
* @return object
* The object receiving the data.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* supported modes only.
*
* @see https://www.drupal.org/node/3377999
*/
protected function assocIntoObject(array $rowAssoc, object $object): object {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999', E_USER_DEPRECATED);
foreach ($rowAssoc as $column => $value) {
$object->$column = $value;
}
return $object;
}
/**
* Converts a row of data in FETCH_ASSOC format to FETCH_COLUMN.
*

View File

@ -121,124 +121,4 @@ class Log {
}
}
/**
* Log a query to all active logging keys.
*
* @param \Drupal\Core\Database\StatementInterface $statement
* The prepared statement object to log.
* @param array $args
* The arguments passed to the statement object.
* @param float $time
* The time the query took to execute as a float (in seconds with
* microsecond precision).
* @param float $start
* The time the query started as a float (in seconds since the Unix epoch
* with microsecond precision).
*
* @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use
* ::logFromEvent().
*
* @see https://www.drupal.org/node/3328053
*/
public function log(StatementInterface $statement, $args, $time, float $start = NULL) {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use ::logFromEvent(). See https://www.drupal.org/node/3328053', E_USER_DEPRECATED);
foreach (array_keys($this->queryLog) as $key) {
$this->queryLog[$key][] = [
'query' => $statement->getQueryString(),
'args' => $args,
'target' => $statement->getConnectionTarget(),
'caller' => $this->findCaller(),
'time' => $time,
'start' => $start,
];
}
}
/**
* Determine the routine that called this query.
*
* Traversing the call stack from the very first call made during the
* request, we define "the routine that called this query" as the last entry
* in the call stack that is not any method called from the namespace of the
* database driver, is not inside the Drupal\Core\Database namespace and does
* have a file (which excludes call_user_func_array(), anonymous functions
* and similar). That makes the climbing logic very simple, and handles the
* variable stack depth caused by the query builders.
*
* See the @link http://php.net/debug_backtrace debug_backtrace() @endlink
* function.
*
* @return array|null
* This method returns a stack trace entry similar to that generated by
* debug_backtrace(). However, it flattens the trace entry and the trace
* entry before it so that we get the function and args of the function that
* called into the database system, not the function and args of the
* database call itself.
*
* @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use
* Connection::findCallerFromDebugBacktrace().
*
* @see https://www.drupal.org/node/3328053
*/
public function findCaller() {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use Connection::findCallerFromDebugBacktrace(). See https://www.drupal.org/node/3328053', E_USER_DEPRECATED);
$driver_namespace = Database::getConnectionInfo($this->connectionKey)['default']['namespace'];
$stack = static::removeDatabaseEntries($this->getDebugBacktrace(), $driver_namespace);
// Return the first function call whose stack entry has a 'file' key, that
// is, it is not a callback or a closure.
for ($i = 0; $i < count($stack); $i++) {
if (!empty($stack[$i]['file'])) {
return [
'file' => $stack[$i]['file'],
'line' => $stack[$i]['line'],
'function' => $stack[$i + 1]['function'],
'class' => $stack[$i + 1]['class'] ?? NULL,
'type' => $stack[$i + 1]['type'] ?? NULL,
'args' => $stack[$i + 1]['args'] ?? [],
];
}
}
}
/**
* Removes database related calls from a backtrace array.
*
* @param array $backtrace
* A standard PHP backtrace. Passed by reference.
* @param string $driver_namespace
* The PHP namespace of the database driver.
*
* @return array
* The cleaned backtrace array.
*
* @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use
* Connection::removeDatabaseEntriesFromDebugBacktrace().
*
* @see https://www.drupal.org/node/3328053
*/
public static function removeDatabaseEntries(array $backtrace, string $driver_namespace): array {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use Connection::removeDatabaseEntriesFromDebugBacktrace(). See https://www.drupal.org/node/3328053', E_USER_DEPRECATED);
return Connection::removeDatabaseEntriesFromDebugBacktrace($backtrace, $driver_namespace);
}
/**
* Gets the debug backtrace.
*
* Wraps the debug_backtrace function to allow mocking results in PHPUnit
* tests.
*
* @return array[]
* The debug backtrace.
*
* @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is
* no replacement.
*
* @see https://www.drupal.org/node/3328053
*/
protected function getDebugBacktrace() {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3328053', E_USER_DEPRECATED);
return debug_backtrace();
}
}

View File

@ -111,8 +111,7 @@ class Condition implements ConditionInterface, \Countable {
throw new InvalidQueryException(sprintf("Query condition '%s %s %s' must have an array compatible operator.", $field, $operator, $value));
}
else {
$value = $value[0];
@trigger_error('Calling ' . __METHOD__ . '() without an array compatible operator is deprecated in drupal:10.1.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3350985', E_USER_DEPRECATED);
throw new InvalidQueryException('Calling ' . __METHOD__ . '() without an array compatible operator is not supported. See https://www.drupal.org/node/3350985');
}
}

View File

@ -2,7 +2,6 @@
namespace Drupal\Core\Database\Query;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Connection;
/**
@ -32,9 +31,6 @@ 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;

View File

@ -2,8 +2,6 @@
namespace Drupal\Core\Database\Query;
use Drupal\Core\Database\Database;
/**
* General class for an abstracted INSERT query.
*
@ -31,11 +29,6 @@ class Insert extends Query implements \Countable {
* Array of database options.
*/
public function __construct($connection, $table, array $options = []) {
// @todo Remove $options['return'] in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
if (!isset($options['return'])) {
$options['return'] = Database::RETURN_INSERT_ID;
}
parent::__construct($connection, $options);
$this->table = $table;
}

View File

@ -2,7 +2,6 @@
namespace Drupal\Core\Database\Query;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\IntegrityConstraintViolationException;
@ -134,9 +133,6 @@ class Merge 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;
$this->conditionTable = $table;
@ -331,14 +327,8 @@ class Merge extends Query implements ConditionInterface {
* @see \Drupal\Core\Database\Query\Merge::keys()
*/
public function key($field, $value = NULL) {
// @todo D9: Remove this backwards-compatibility shim.
if (is_array($field)) {
@trigger_error("Passing an array to the \$field argument of " . __METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. See https://www.drupal.org/node/2205327', E_USER_DEPRECATED);
$this->keys($field, $value ?? []);
}
else {
$this->keys([$field => $value]);
}
assert(is_string($field));
$this->keys([$field => $value]);
return $this;
}

View File

@ -2,7 +2,6 @@
namespace Drupal\Core\Database\Query;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Connection;
/**
@ -142,9 +141,6 @@ class Select extends Query implements SelectInterface {
* Array of query options.
*/
public function __construct(Connection $connection, $table, $alias = NULL, $options = []) {
// @todo Remove $options['return'] in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
$options['return'] = Database::RETURN_STATEMENT;
parent::__construct($connection, $options);
$conjunction = $options['conjunction'] ?? 'AND';
$this->condition = $this->connection->condition($conjunction);

View File

@ -2,7 +2,6 @@
namespace Drupal\Core\Database\Query;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Connection;
/**
@ -28,9 +27,6 @@ class Truncate extends Query {
* 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;
}

View File

@ -2,7 +2,6 @@
namespace Drupal\Core\Database\Query;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Connection;
/**
@ -61,9 +60,6 @@ class Update 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;

View File

@ -3,7 +3,6 @@
namespace Drupal\Core\Database\Query;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Database;
/**
* General class for an abstracted "Upsert" (UPDATE or INSERT) query operation.
@ -35,9 +34,6 @@ abstract class Upsert extends Query implements \Countable {
* (optional) An 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;
}

View File

@ -117,21 +117,16 @@ interface StatementInterface extends \Traversable {
* The object will be of the class specified by StatementInterface::setFetchMode()
* or stdClass if not specified.
*
* phpcs:disable Drupal.Commenting
* @todo Uncomment new method parameters before drupal:11.0.0.
* @see https://www.drupal.org/project/drupal/issues/3354672
*
* @param string|null $class_name
* Name of the created class.
* @param array $constructor_arguments
* Elements of this array are passed to the constructor.
* phpcs:enable
*
* @return mixed
* The object of specified class or \stdClass if not specified. Returns
* FALSE or NULL if there is no next row.
*/
public function fetchObject(/* string $class_name = NULL, array $constructor_arguments = [] */);
public function fetchObject(string $class_name = NULL, array $constructor_arguments = []);
/**
* Fetches the next row and returns it as an associative array.

View File

@ -105,10 +105,9 @@ trait StatementIteratorTrait {
public function rewind(): void {
// Nothing to do: our DatabaseStatement can't be rewound. Error out when
// attempted.
// @todo convert the error to an exception in Drupal 11.
if ($this->resultsetKey >= 0) {
trigger_error('Attempted rewinding a StatementInterface object when fetching has already started. Refactor your code to avoid rewinding statement objects.', E_USER_WARNING);
$this->markResultsetIterable(FALSE);
throw new DatabaseExceptionWrapper('Attempted rewinding a StatementInterface object when fetching has already started. Refactor your code to avoid rewinding statement objects.');
}
}

View File

@ -1,602 +0,0 @@
<?php
namespace Drupal\Core\Database;
@trigger_error('\Drupal\Core\Database\StatementPrefetch is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use \Drupal\Core\Database\StatementPrefetchIterator instead. See https://www.drupal.org/node/3265938', E_USER_DEPRECATED);
use Drupal\Core\Database\Event\StatementExecutionEndEvent;
use Drupal\Core\Database\Event\StatementExecutionStartEvent;
/**
* An implementation of StatementInterface that pre-fetches all data.
*
* This class behaves very similar to a StatementWrapper of a \PDOStatement
* but as it always fetches every row it is possible to manipulate those
* results.
*
* @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use
* \Drupal\Core\Database\StatementPrefetchIterator instead.
*
* @see https://www.drupal.org/node/3265938
*/
class StatementPrefetch implements \Iterator, StatementInterface {
/**
* The query string.
*
* @var string
*/
protected $queryString;
/**
* Driver-specific options. Can be used by child classes.
*
* @var array
*/
protected $driverOptions;
/**
* The Drupal database connection object.
*
* @var \Drupal\Core\Database\Connection
*/
protected $connection;
/**
* Reference to the PDO connection object for this statement.
*
* @var \PDO
*/
protected $pdoConnection;
/**
* Main data store.
*
* @var array
*/
protected $data = [];
/**
* The current row, retrieved in \PDO::FETCH_ASSOC format.
*
* @var array
*/
protected $currentRow = NULL;
/**
* The key of the current row.
*
* @var int
*/
protected $currentKey = NULL;
/**
* The list of column names in this result set.
*
* @var array
*/
protected $columnNames = NULL;
/**
* The number of rows matched by the last query.
*
* @var int
*/
protected $rowCount = NULL;
/**
* The number of rows in this result set.
*
* @var int
*/
protected $resultRowCount = 0;
/**
* Holds the current fetch style (which will be used by the next fetch).
* @see \PDOStatement::fetch()
*
* @var int
*/
protected $fetchStyle = \PDO::FETCH_OBJ;
/**
* Holds supplementary current fetch options (which will be used by the next fetch).
*
* @var array
*/
protected $fetchOptions = [
'class' => 'stdClass',
'constructor_args' => [],
'object' => NULL,
'column' => 0,
];
/**
* Holds the default fetch style.
*
* @var int
*/
protected $defaultFetchStyle = \PDO::FETCH_OBJ;
/**
* Holds supplementary default fetch options.
*
* @var array
*/
protected $defaultFetchOptions = [
'class' => 'stdClass',
'constructor_args' => [],
'object' => NULL,
'column' => 0,
];
/**
* Is rowCount() execution allowed.
*
* @var bool
*/
protected $rowCountEnabled = FALSE;
/**
* Constructs a StatementPrefetch object.
*
* @param \PDO $pdo_connection
* An object of the PDO class representing a database connection.
* @param \Drupal\Core\Database\Connection $connection
* The database connection.
* @param string $query
* The query string.
* @param array $driver_options
* Driver-specific options.
* @param bool $row_count_enabled
* (optional) Enables counting the rows matched. Defaults to FALSE.
*/
public function __construct(\PDO $pdo_connection, Connection $connection, $query, array $driver_options = [], bool $row_count_enabled = FALSE) {
$this->pdoConnection = $pdo_connection;
$this->connection = $connection;
$this->queryString = $query;
$this->driverOptions = $driver_options;
$this->rowCountEnabled = $row_count_enabled;
}
/**
* {@inheritdoc}
*/
public function getConnectionTarget(): string {
return $this->connection->getTarget();
}
/**
* {@inheritdoc}
*/
public function execute($args = [], $options = []) {
if (isset($options['fetch'])) {
if (is_string($options['fetch'])) {
// Default to an object. Note: db fields will be added to the object
// before the constructor is run. If you need to assign fields after
// the constructor is run. See https://www.drupal.org/node/315092.
$this->setFetchMode(\PDO::FETCH_CLASS, $options['fetch']);
}
else {
$this->setFetchMode($options['fetch']);
}
}
if ($this->connection->isEventEnabled(StatementExecutionStartEvent::class)) {
$startEvent = new StatementExecutionStartEvent(
spl_object_id($this),
$this->connection->getKey(),
$this->connection->getTarget(),
$this->getQueryString(),
$args ?? [],
$this->connection->findCallerFromDebugBacktrace()
);
$this->connection->dispatchEvent($startEvent);
}
// Prepare the query.
$statement = $this->getStatement($this->queryString, $args);
if (!$statement) {
$this->throwPDOException();
}
$return = $statement->execute($args);
if (!$return) {
$this->throwPDOException();
}
if ($this->rowCountEnabled) {
$this->rowCount = $statement->rowCount();
}
// Fetch all the data from the reply, in order to release any lock
// as soon as possible.
$this->data = $statement->fetchAll(\PDO::FETCH_ASSOC);
// Destroy the statement as soon as possible. See the documentation of
// \Drupal\sqlite\Driver\Database\sqlite\Statement for an explanation.
unset($statement);
$this->resultRowCount = count($this->data);
if ($this->resultRowCount) {
$this->columnNames = array_keys($this->data[0]);
}
else {
$this->columnNames = [];
}
if (isset($startEvent) && $this->connection->isEventEnabled(StatementExecutionEndEvent::class)) {
$this->connection->dispatchEvent(new StatementExecutionEndEvent(
$startEvent->statementObjectId,
$startEvent->key,
$startEvent->target,
$startEvent->queryString,
$startEvent->args,
$startEvent->caller,
$startEvent->time
));
}
// Initialize the first row in $this->currentRow.
$this->next();
return $return;
}
/**
* Throw a PDO Exception based on the last PDO error.
*/
protected function throwPDOException() {
$error_info = $this->connection->errorInfo();
// We rebuild a message formatted in the same way as PDO.
$exception = new \PDOException("SQLSTATE[" . $error_info[0] . "]: General error " . $error_info[1] . ": " . $error_info[2]);
$exception->errorInfo = $error_info;
throw $exception;
}
/**
* Grab a PDOStatement object from a given query and its arguments.
*
* Some drivers (including SQLite) will need to perform some preparation
* themselves to get the statement right.
*
* @param $query
* The query.
* @param array|null $args
* An array of arguments. This can be NULL.
*
* @return \PDOStatement
* A PDOStatement object.
*/
protected function getStatement($query, &$args = []) {
return $this->connection->prepare($query, $this->driverOptions);
}
/**
* {@inheritdoc}
*/
public function getQueryString() {
return $this->queryString;
}
/**
* {@inheritdoc}
*/
public function setFetchMode($mode, $a1 = NULL, $a2 = []) {
$this->defaultFetchStyle = $mode;
switch ($mode) {
case \PDO::FETCH_CLASS:
$this->defaultFetchOptions['class'] = $a1;
if ($a2) {
$this->defaultFetchOptions['constructor_args'] = $a2;
}
break;
case \PDO::FETCH_COLUMN:
$this->defaultFetchOptions['column'] = $a1;
break;
case \PDO::FETCH_INTO:
$this->defaultFetchOptions['object'] = $a1;
break;
}
// Set the values for the next fetch.
$this->fetchStyle = $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
}
/**
* Return the current row formatted according to the current fetch style.
*
* This is the core method of this class. It grabs the value at the current
* array position in $this->data and format it according to $this->fetchStyle
* and $this->fetchMode.
*
* @return mixed
* The current row formatted as requested.
*/
#[\ReturnTypeWillChange]
public function current() {
if (isset($this->currentRow)) {
switch ($this->fetchStyle) {
case \PDO::FETCH_ASSOC:
return $this->currentRow;
case \PDO::FETCH_BOTH:
// \PDO::FETCH_BOTH returns an array indexed by both the column name
// and the column number.
return $this->currentRow + array_values($this->currentRow);
case \PDO::FETCH_NUM:
return array_values($this->currentRow);
case \PDO::FETCH_LAZY:
// We do not do lazy as everything is fetched already. Fallback to
// \PDO::FETCH_OBJ.
case \PDO::FETCH_OBJ:
return (object) $this->currentRow;
case \PDO::FETCH_CLASS | \PDO::FETCH_CLASSTYPE:
$class_name = array_shift($this->currentRow);
// Deliberate no break.
case \PDO::FETCH_CLASS:
if (!isset($class_name)) {
$class_name = $this->fetchOptions['class'];
}
if (count($this->fetchOptions['constructor_args'])) {
$reflector = new \ReflectionClass($class_name);
$result = $reflector->newInstanceArgs($this->fetchOptions['constructor_args']);
}
else {
$result = new $class_name();
}
foreach ($this->currentRow as $k => $v) {
$result->$k = $v;
}
return $result;
case \PDO::FETCH_INTO:
foreach ($this->currentRow as $k => $v) {
$this->fetchOptions['object']->$k = $v;
}
return $this->fetchOptions['object'];
case \PDO::FETCH_COLUMN:
if (isset($this->columnNames[$this->fetchOptions['column']])) {
return $this->currentRow[$this->columnNames[$this->fetchOptions['column']]];
}
else {
return;
}
}
}
}
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function key() {
return $this->currentKey;
}
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function rewind() {
// Nothing to do: our DatabaseStatement can't be rewound.
}
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function next() {
if (!empty($this->data)) {
$this->currentRow = reset($this->data);
$this->currentKey = key($this->data);
unset($this->data[$this->currentKey]);
}
else {
$this->currentRow = NULL;
}
}
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function valid() {
return isset($this->currentRow);
}
/**
* {@inheritdoc}
*/
public function rowCount() {
// SELECT query should not use the method.
if ($this->rowCountEnabled) {
return $this->rowCount;
}
else {
throw new RowCountException();
}
}
/**
* {@inheritdoc}
*/
public function fetch($fetch_style = NULL, $cursor_orientation = \PDO::FETCH_ORI_NEXT, $cursor_offset = NULL) {
if (isset($this->currentRow)) {
// Set the fetch parameter.
$this->fetchStyle = $fetch_style ?? $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
// Grab the row in the format specified above.
$return = $this->current();
// Advance the cursor.
$this->next();
// Reset the fetch parameters to the value stored using setFetchMode().
$this->fetchStyle = $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
return $return;
}
else {
return FALSE;
}
}
public function fetchColumn($index = 0) {
if (isset($this->currentRow) && isset($this->columnNames[$index])) {
// We grab the value directly from $this->data, and format it.
$return = $this->currentRow[$this->columnNames[$index]];
$this->next();
return $return;
}
else {
return FALSE;
}
}
/**
* {@inheritdoc}
*/
public function fetchField($index = 0) {
return $this->fetchColumn($index);
}
/**
* {@inheritdoc}
*/
public function fetchObject(string $class_name = NULL, array $constructor_arguments = []) {
if (isset($this->currentRow)) {
if (!isset($class_name)) {
// Directly cast to an object to avoid a function call.
$result = (object) $this->currentRow;
}
else {
$this->fetchStyle = \PDO::FETCH_CLASS;
$this->fetchOptions = [
'class' => $class_name,
'constructor_args' => $constructor_arguments,
];
// Grab the row in the format specified above.
$result = $this->current();
// Reset the fetch parameters to the value stored using setFetchMode().
$this->fetchStyle = $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
}
$this->next();
return $result;
}
else {
return FALSE;
}
}
/**
* {@inheritdoc}
*/
public function fetchAssoc() {
if (isset($this->currentRow)) {
$result = $this->currentRow;
$this->next();
return $result;
}
else {
return FALSE;
}
}
/**
* {@inheritdoc}
*/
public function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL) {
$this->fetchStyle = $mode ?? $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
if (isset($column_index)) {
$this->fetchOptions['column'] = $column_index;
}
if (isset($constructor_arguments)) {
$this->fetchOptions['constructor_args'] = $constructor_arguments;
}
$result = [];
// Traverse the array as PHP would have done.
while (isset($this->currentRow)) {
// Grab the row in the format specified above.
$result[] = $this->current();
$this->next();
}
// Reset the fetch parameters to the value stored using setFetchMode().
$this->fetchStyle = $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
return $result;
}
/**
* {@inheritdoc}
*/
public function fetchCol($index = 0) {
if (isset($this->columnNames[$index])) {
$result = [];
// Traverse the array as PHP would have done.
while (isset($this->currentRow)) {
$result[] = $this->currentRow[$this->columnNames[$index]];
$this->next();
}
return $result;
}
else {
return [];
}
}
/**
* {@inheritdoc}
*/
public function fetchAllKeyed($key_index = 0, $value_index = 1) {
if (!isset($this->columnNames[$key_index]) || !isset($this->columnNames[$value_index])) {
return [];
}
$key = $this->columnNames[$key_index];
$value = $this->columnNames[$value_index];
$result = [];
// Traverse the array as PHP would have done.
while (isset($this->currentRow)) {
$result[$this->currentRow[$key]] = $this->currentRow[$value];
$this->next();
}
return $result;
}
/**
* {@inheritdoc}
*/
public function fetchAllAssoc($key, $fetch_style = NULL) {
$this->fetchStyle = $fetch_style ?? $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
$result = [];
// Traverse the array as PHP would have done.
while (isset($this->currentRow)) {
// Grab the row in its raw \PDO::FETCH_ASSOC format.
$result_row = $this->current();
$result[$this->currentRow[$key]] = $result_row;
$this->next();
}
// Reset the fetch parameters to the value stored using setFetchMode().
$this->fetchStyle = $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
return $result;
}
}

View File

@ -161,23 +161,6 @@ class StatementPrefetchIterator implements \Iterator, StatementInterface {
return $return;
}
/**
* Throw a PDO Exception based on the last PDO error.
*
* @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is
* no replacement.
*
* @see https://www.drupal.org/node/3410663
*/
protected function throwPDOException(): void {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3410663', E_USER_DEPRECATED);
$error_info = $this->connection->errorInfo();
// We rebuild a message formatted in the same way as PDO.
$exception = new \PDOException("SQLSTATE[" . $error_info[0] . "]: General error " . $error_info[1] . ": " . $error_info[2]);
$exception->errorInfo = $error_info;
throw $exception;
}
/**
* Grab a PDOStatement object from a given query and its arguments.
*
@ -207,9 +190,8 @@ class StatementPrefetchIterator implements \Iterator, StatementInterface {
* {@inheritdoc}
*/
public function setFetchMode($mode, $a1 = NULL, $a2 = []) {
if (!in_array($mode, $this->supportedFetchModes)) {
@trigger_error('Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999', E_USER_DEPRECATED);
}
assert(in_array($mode, $this->supportedFetchModes), 'Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is not supported. Use supported modes only.');
$this->defaultFetchStyle = $mode;
switch ($mode) {
case \PDO::FETCH_CLASS:
@ -259,23 +241,15 @@ class StatementPrefetchIterator implements \Iterator, StatementInterface {
// Now, format the next prefetched record according to the required fetch
// style.
// @todo in Drupal 11, remove arms for deprecated fetch modes.
$rowAssoc = $this->data[$currentKey];
$row = match($fetch_style ?? $this->defaultFetchStyle) {
$mode = $fetch_style ?? $this->defaultFetchStyle;
$row = match($mode) {
\PDO::FETCH_ASSOC => $rowAssoc,
// @phpstan-ignore-next-line
\PDO::FETCH_BOTH => $this->assocToBoth($rowAssoc),
\PDO::FETCH_NUM => $this->assocToNum($rowAssoc),
\PDO::FETCH_LAZY, \PDO::FETCH_OBJ => $this->assocToObj($rowAssoc),
// @phpstan-ignore-next-line
\PDO::FETCH_CLASS | \PDO::FETCH_CLASSTYPE => $this->assocToClassType($rowAssoc, $this->fetchOptions['constructor_args']),
\PDO::FETCH_CLASS => $this->assocToClass($rowAssoc, $this->fetchOptions['class'], $this->fetchOptions['constructor_args']),
// @phpstan-ignore-next-line
\PDO::FETCH_INTO => $this->assocIntoObject($rowAssoc, $this->fetchOptions['object']),
\PDO::FETCH_CLASS, \PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE => $this->assocToClass($rowAssoc, $this->fetchOptions['class'], $this->fetchOptions['constructor_args']),
\PDO::FETCH_COLUMN => $this->assocToColumn($rowAssoc, $this->columnNames, $this->fetchOptions['column']),
// @todo in Drupal 11, throw an exception if the fetch style cannot be
// matched.
default => FALSE,
\PDO::FETCH_NUM => $this->assocToNum($rowAssoc),
\PDO::FETCH_OBJ => $this->assocToObj($rowAssoc),
default => throw new DatabaseExceptionWrapper('Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is not supported. Use supported modes only.'),
};
$this->setResultsetCurrentRow($row);
return $row;
@ -323,10 +297,10 @@ class StatementPrefetchIterator implements \Iterator, StatementInterface {
* {@inheritdoc}
*/
public function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL) {
if (isset($mode) && !in_array($mode, $this->supportedFetchModes)) {
@trigger_error('Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999', E_USER_DEPRECATED);
}
$fetchStyle = $mode ?? $this->defaultFetchStyle;
assert(in_array($fetchStyle, $this->supportedFetchModes), 'Fetch mode ' . ($this->fetchModeLiterals[$fetchStyle] ?? $fetchStyle) . ' is not supported. Use supported modes only.');
if (isset($column_index)) {
$this->fetchOptions['column'] = $column_index;
}

View File

@ -1,290 +0,0 @@
<?php
namespace Drupal\Core\Database;
use Drupal\Core\Database\Event\StatementExecutionEndEvent;
use Drupal\Core\Database\Event\StatementExecutionStartEvent;
// cSpell:ignore maxlen driverdata INOUT
@trigger_error('\Drupal\Core\Database\StatementWrapper is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use \Drupal\Core\Database\StatementWrapperIterator instead. See https://www.drupal.org/node/3265938', E_USER_DEPRECATED);
/**
* Implementation of StatementInterface encapsulating PDOStatement.
*
* @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use
* \Drupal\Core\Database\StatementWrapperIterator instead.
*
* @see https://www.drupal.org/node/3265938
*/
class StatementWrapper implements \IteratorAggregate, StatementInterface {
/**
* The Drupal database connection object.
*
* @var \Drupal\Core\Database\Connection
*/
protected $connection;
/**
* The client database Statement object.
*
* For a \PDO client connection, this will be a \PDOStatement object.
*
* @var object
*/
protected $clientStatement;
/**
* Is rowCount() execution allowed.
*
* @var bool
*/
protected $rowCountEnabled = FALSE;
/**
* Constructs a StatementWrapper object.
*
* @param \Drupal\Core\Database\Connection $connection
* Drupal database connection object.
* @param object $client_connection
* Client database connection object, for example \PDO.
* @param string $query
* The SQL query string.
* @param array $options
* Array of query options.
* @param bool $row_count_enabled
* (optional) Enables counting the rows matched. Defaults to FALSE.
*/
public function __construct(Connection $connection, $client_connection, string $query, array $options, bool $row_count_enabled = FALSE) {
$this->connection = $connection;
$this->clientStatement = $client_connection->prepare($query, $options);
$this->rowCountEnabled = $row_count_enabled;
$this->setFetchMode(\PDO::FETCH_OBJ);
}
/**
* Returns the client-level database statement object.
*
* This method should normally be used only within database driver code.
*
* @return object
* The client-level database statement, for example \PDOStatement.
*/
public function getClientStatement() {
return $this->clientStatement;
}
/**
* {@inheritdoc}
*/
public function getConnectionTarget(): string {
return $this->connection->getTarget();
}
/**
* {@inheritdoc}
*/
public function execute($args = [], $options = []) {
if (isset($options['fetch'])) {
if (is_string($options['fetch'])) {
// \PDO::FETCH_PROPS_LATE tells __construct() to run before properties
// are added to the object.
$this->setFetchMode(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, $options['fetch']);
}
else {
$this->setFetchMode($options['fetch']);
}
}
if ($this->connection->isEventEnabled(StatementExecutionStartEvent::class)) {
$startEvent = new StatementExecutionStartEvent(
spl_object_id($this),
$this->connection->getKey(),
$this->connection->getTarget(),
$this->getQueryString(),
$args ?? [],
$this->connection->findCallerFromDebugBacktrace()
);
$this->connection->dispatchEvent($startEvent);
}
$return = $this->clientStatement->execute($args);
if (isset($startEvent) && $this->connection->isEventEnabled(StatementExecutionEndEvent::class)) {
$this->connection->dispatchEvent(new StatementExecutionEndEvent(
$startEvent->statementObjectId,
$startEvent->key,
$startEvent->target,
$startEvent->queryString,
$startEvent->args,
$startEvent->caller,
$startEvent->time
));
}
return $return;
}
/**
* {@inheritdoc}
*/
public function getQueryString() {
return $this->clientStatement->queryString;
}
/**
* {@inheritdoc}
*/
public function fetchCol($index = 0) {
return $this->fetchAll(\PDO::FETCH_COLUMN, $index);
}
/**
* {@inheritdoc}
*/
public function fetchAllAssoc($key, $fetch = NULL) {
$return = [];
if (isset($fetch)) {
if (is_string($fetch)) {
$this->setFetchMode(\PDO::FETCH_CLASS, $fetch);
}
else {
$this->setFetchMode($fetch);
}
}
foreach ($this as $record) {
$record_key = is_object($record) ? $record->$key : $record[$key];
$return[$record_key] = $record;
}
return $return;
}
/**
* {@inheritdoc}
*/
public function fetchAllKeyed($key_index = 0, $value_index = 1) {
$return = [];
$this->setFetchMode(\PDO::FETCH_NUM);
foreach ($this as $record) {
$return[$record[$key_index]] = $record[$value_index];
}
return $return;
}
/**
* {@inheritdoc}
*/
public function fetchField($index = 0) {
// Call \PDOStatement::fetchColumn to fetch the field.
return $this->clientStatement->fetchColumn($index);
}
/**
* {@inheritdoc}
*/
public function fetchAssoc() {
// Call \PDOStatement::fetch to fetch the row.
return $this->fetch(\PDO::FETCH_ASSOC);
}
/**
* {@inheritdoc}
*/
public function fetchObject(string $class_name = NULL, array $constructor_arguments = []) {
if ($class_name) {
return $this->clientStatement->fetchObject($class_name, $constructor_arguments);
}
return $this->clientStatement->fetchObject();
}
/**
* {@inheritdoc}
*/
public function rowCount() {
// SELECT query should not use the method.
if ($this->rowCountEnabled) {
return $this->clientStatement->rowCount();
}
else {
throw new RowCountException();
}
}
/**
* {@inheritdoc}
*/
public function setFetchMode($mode, $a1 = NULL, $a2 = []) {
// Call \PDOStatement::setFetchMode to set fetch mode.
// \PDOStatement is picky about the number of arguments in some cases so we
// need to be pass the exact number of arguments we where given.
switch (func_num_args()) {
case 1:
return $this->clientStatement->setFetchMode($mode);
case 2:
return $this->clientStatement->setFetchMode($mode, $a1);
case 3:
default:
return $this->clientStatement->setFetchMode($mode, $a1, $a2);
}
}
/**
* {@inheritdoc}
*/
public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset = NULL) {
// Call \PDOStatement::fetchAll to fetch all rows.
// \PDOStatement is picky about the number of arguments in some cases so we
// need to be pass the exact number of arguments we where given.
switch (func_num_args()) {
case 0:
return $this->clientStatement->fetch();
case 1:
return $this->clientStatement->fetch($mode);
case 2:
return $this->clientStatement->fetch($mode, $cursor_orientation);
case 3:
default:
return $this->clientStatement->fetch($mode, $cursor_orientation, $cursor_offset);
}
}
/**
* {@inheritdoc}
*/
public function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL) {
// Call \PDOStatement::fetchAll to fetch all rows.
// \PDOStatement is picky about the number of arguments in some cases so we
// need to be pass the exact number of arguments we where given.
switch (func_num_args()) {
case 0:
return $this->clientStatement->fetchAll();
case 1:
return $this->clientStatement->fetchAll($mode);
case 2:
return $this->clientStatement->fetchAll($mode, $column_index);
case 3:
default:
return $this->clientStatement->fetchAll($mode, $column_index, $constructor_arguments);
}
}
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function getIterator() {
return new \ArrayIterator($this->fetchAll());
}
}

View File

@ -269,9 +269,8 @@ class StatementWrapperIterator implements \Iterator, StatementInterface {
* {@inheritdoc}
*/
public function setFetchMode($mode, $a1 = NULL, $a2 = []) {
if (!in_array($mode, $this->supportedFetchModes)) {
@trigger_error('Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999', E_USER_DEPRECATED);
}
assert(in_array($mode, $this->supportedFetchModes), 'Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is not supported. Use supported modes only.');
// Call \PDOStatement::setFetchMode to set fetch mode.
// \PDOStatement is picky about the number of arguments in some cases so we
// need to be pass the exact number of arguments we where given.
@ -286,9 +285,8 @@ class StatementWrapperIterator implements \Iterator, StatementInterface {
* {@inheritdoc}
*/
public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset = NULL) {
if (isset($mode) && !in_array($mode, $this->supportedFetchModes)) {
@trigger_error('Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999', E_USER_DEPRECATED);
}
assert(!isset($mode) || in_array($mode, $this->supportedFetchModes), 'Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is not supported. Use supported modes only.');
// Call \PDOStatement::fetchAll to fetch all rows.
// \PDOStatement is picky about the number of arguments in some cases so we
// need to pass the exact number of arguments we were given.
@ -312,9 +310,8 @@ class StatementWrapperIterator implements \Iterator, StatementInterface {
* {@inheritdoc}
*/
public function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL) {
if (isset($mode) && !in_array($mode, $this->supportedFetchModes)) {
@trigger_error('Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999', E_USER_DEPRECATED);
}
assert(!isset($mode) || in_array($mode, $this->supportedFetchModes), 'Fetch mode ' . ($this->fetchModeLiterals[$mode] ?? $mode) . ' is not supported. Use supported modes only.');
// Call \PDOStatement::fetchAll to fetch all rows.
// \PDOStatement is picky about the number of arguments in some cases so we
// need to be pass the exact number of arguments we where given.

View File

@ -23,84 +23,19 @@ namespace Drupal\Core\Database;
*/
class Transaction {
/**
* The connection object for this transaction.
*
* @var \Drupal\Core\Database\Connection
*/
protected $connection;
/**
* A boolean value to indicate whether this transaction has been rolled back.
*
* @var bool
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. There is
* no replacement.
*
* @see https://www.drupal.org/node/3381002
*/
protected $rolledBack = FALSE;
/**
* The name of the transaction.
*
* This is used to label the transaction savepoint. It will be overridden to
* 'drupal_transaction' if there is no transaction depth.
*
* @var string
*/
protected $name;
public function __construct(
Connection $connection,
$name = NULL,
protected readonly string $id = '',
protected readonly Connection $connection,
protected readonly string $name,
protected readonly string $id,
) {
// Transactions rely on objects being destroyed in order to be committed.
// PHP makes no guarantee about the order in which objects are destroyed so
// ensure all transactions are committed on shutdown.
Database::commitAllOnShutdown();
if ($connection->transactionManager()) {
$this->connection = $connection;
$this->name = $name;
return;
}
// Start of BC layer.
$this->connection = $connection;
// If there is no transaction depth, then no transaction has started. Name
// the transaction 'drupal_transaction'.
// @phpstan-ignore-next-line
if (!$depth = $connection->transactionDepth()) {
$this->name = 'drupal_transaction';
}
// Within transactions, savepoints are used. Each savepoint requires a
// name. So if no name is present we need to create one.
elseif (!$name) {
$this->name = 'savepoint_' . $depth;
}
else {
$this->name = $name;
}
// @phpstan-ignore-next-line
$this->connection->pushTransaction($this->name);
// End of BC layer.
}
public function __destruct() {
if ($this->connection->transactionManager()) {
$this->connection->transactionManager()->unpile($this->name, $this->id);
return;
}
// Start of BC layer.
// If we rolled back then the transaction would have already been popped.
// @phpstan-ignore-next-line
if (!$this->rolledBack) {
// @phpstan-ignore-next-line
$this->connection->popTransaction($this->name);
}
// End of BC layer.
$this->connection->transactionManager()->unpile($this->name, $this->id);
}
/**
@ -121,16 +56,7 @@ class Transaction {
* @see \Drupal\Core\Database\Connection::rollBack()
*/
public function rollBack() {
if ($this->connection->transactionManager()) {
$this->connection->transactionManager()->rollback($this->name, $this->id);
return;
}
// Start of BC layer.
// @phpstan-ignore-next-line
$this->rolledBack = TRUE;
// @phpstan-ignore-next-line
$this->connection->rollBack($this->name);
// End of BC layer.
$this->connection->transactionManager()->rollback($this->name, $this->id);
}
}

View File

@ -308,21 +308,6 @@ abstract class TransactionManagerBase implements TransactionManagerInterface {
* {@inheritdoc}
*/
public function rollback(string $name, string $id): void {
// @todo remove in drupal:11.0.0.
// Start of BC layer.
if ($id === 'bc-force-rollback') {
foreach ($this->stack() as $stackId => $item) {
if ($item->name === $name) {
$id = $stackId;
break;
}
}
if ($id === 'bc-force-rollback') {
throw new TransactionOutOfOrderException();
}
}
// End of BC layer.
// Rolled back item should match the last one in stack.
if ($id != array_key_last($this->stack()) || $name !== $this->stack()[$id]->name) {
throw new TransactionOutOfOrderException("Error attempting rollback of {$id}\\{$name}. Active stack: " . $this->dumpStackItemsAsString());

View File

@ -5,7 +5,6 @@ namespace Drupal\Core\Entity\Sql;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\MemoryCache\MemoryCacheInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Database\SchemaException;
use Drupal\Core\Entity\ContentEntityInterface;
@ -940,10 +939,8 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
}
}
else {
// @todo Remove the 'return' option in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
$insert_id = $this->database
->insert($this->baseTable, ['return' => Database::RETURN_INSERT_ID])
->insert($this->baseTable)
->fields((array) $record)
->execute();
// Even if this is a new entity the ID key might have been set, in which
@ -1145,10 +1142,8 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
$entity->preSaveRevision($this, $record);
if ($entity->isNewRevision()) {
// @todo Remove the 'return' option in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
$insert_id = $this->database
->insert($this->revisionTable, ['return' => Database::RETURN_INSERT_ID])
->insert($this->revisionTable)
->fields((array) $record)
->execute();
// Even if this is a new revision, the revision ID key might have been

View File

@ -8,7 +8,6 @@ use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseException;
use Drupal\Core\Database\Query\SelectInterface;
@ -289,10 +288,7 @@ class MenuTreeStorage implements MenuTreeStorageInterface {
$transaction = $this->connection->startTransaction();
if (!$original) {
// Generate a new mlid.
// @todo Remove the 'return' option in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
$options = ['return' => Database::RETURN_INSERT_ID] + $this->options;
$link['mlid'] = $this->connection->insert($this->table, $options)
$link['mlid'] = $this->connection->insert($this->table, $this->options)
->fields(['id' => $link['id'], 'menu_name' => $link['menu_name']])
->execute();
$fields = $this->preSave($link, []);

View File

@ -174,7 +174,7 @@ class MigrateSqlIdMapEnsureTablesTest extends MigrateTestCase {
->method('schema')
->willReturn($schema);
$database->expects($this->any())
->method('tablePrefix')
->method('getPrefix')
->willReturn('');
$migration = $this->getMigration();
$plugin = $this->createMock('Drupal\migrate\Plugin\MigrateSourceInterface');

View File

@ -6,9 +6,7 @@ use Drupal\Core\Database\Connection as DatabaseConnection;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseAccessDeniedException;
use Drupal\Core\Database\DatabaseConnectionRefusedException;
use Drupal\Core\Database\DatabaseException;
use Drupal\Core\Database\DatabaseNotFoundException;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\StatementWrapperIterator;
use Drupal\Core\Database\SupportsTemporaryTablesInterface;
use Drupal\Core\Database\Transaction\TransactionManagerInterface;
@ -58,18 +56,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
*/
protected $statementWrapperClass = StatementWrapperIterator::class;
/**
* Flag to indicate if the cleanup function in __destruct() should run.
*
* @var bool
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. There's no
* replacement.
*
* @see https://www.drupal.org/node/3349345
*/
protected $needsCleanup = FALSE;
/**
* Stores the server version after it has been retrieved from the database.
*
@ -251,16 +237,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return $pdo;
}
/**
* {@inheritdoc}
*/
public function __destruct() {
if ($this->needsCleanup) {
$this->nextIdDelete();
}
parent::__destruct();
}
public function queryRange($query, $from, $count, array $args = [], array $options = []) {
return $this->query($query . ' LIMIT ' . (int) $from . ', ' . (int) $count, $args, $options);
}
@ -359,55 +335,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return NULL;
}
/**
* {@inheritdoc}
*/
public function nextId($existing_id = 0) {
@trigger_error('Drupal\Core\Database\Connection::nextId() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Modules should use instead the keyvalue storage for the last used id. See https://www.drupal.org/node/3349345', E_USER_DEPRECATED);
$this->query('INSERT INTO {sequences} () VALUES ()');
$new_id = $this->lastInsertId();
// This should only happen after an import or similar event.
if ($existing_id >= $new_id) {
// If we INSERT a value manually into the sequences table, on the next
// INSERT, MySQL will generate a larger value. However, there is no way
// of knowing whether this value already exists in the table. MySQL
// provides an INSERT IGNORE which would work, but that can mask problems
// other than duplicate keys. Instead, we use INSERT ... ON DUPLICATE KEY
// UPDATE in such a way that the UPDATE does not do anything. This way,
// duplicate keys do not generate errors but everything else does.
$this->query('INSERT INTO {sequences} (value) VALUES (:value) ON DUPLICATE KEY UPDATE value = value', [':value' => $existing_id]);
$this->query('INSERT INTO {sequences} () VALUES ()');
$new_id = $this->lastInsertId();
}
$this->needsCleanup = TRUE;
return $new_id;
}
public function nextIdDelete() {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Modules should use instead the keyvalue storage for the last used id. See https://www.drupal.org/node/3349345', E_USER_DEPRECATED);
// While we want to clean up the table to keep it up from occupying too
// much storage and memory, we must keep the highest value in the table
// because InnoDB uses an in-memory auto-increment counter as long as the
// server runs. When the server is stopped and restarted, InnoDB
// re-initializes the counter for each table for the first INSERT to the
// table based solely on values from the table so deleting all values would
// be a problem in this case. Also, TRUNCATE resets the auto increment
// counter.
try {
$max_id = $this->query('SELECT MAX(value) FROM {sequences}')->fetchField();
// We know we are using MySQL here, no need for the slower ::delete().
$this->query('DELETE FROM {sequences} WHERE value < :value', [':value' => $max_id]);
}
// During testing, this function is called from shutdown with the
// simpletest prefix stored in $this->connection, and those tables are gone
// by the time shutdown is called so we need to ignore the database
// errors. There is no problem with completely ignoring errors here: if
// these queries fail, the sequence will work just fine, just use a bit
// more database storage and memory.
catch (DatabaseException $e) {
}
}
/**
* {@inheritdoc}
*/
@ -415,13 +342,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return new ExceptionHandler();
}
/**
* {@inheritdoc}
*/
public function select($table, $alias = NULL, array $options = []) {
return new Select($this, $table, $alias, $options);
}
/**
* {@inheritdoc}
*/
@ -429,13 +349,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return new Insert($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function merge($table, array $options = []) {
return new Merge($this, $table, $options);
}
/**
* {@inheritdoc}
*/
@ -443,27 +356,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return new Upsert($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function update($table, array $options = []) {
return new Update($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function delete($table, array $options = []) {
return new Delete($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function truncate($table, array $options = []) {
return new Truncate($this, $table, $options);
}
/**
* {@inheritdoc}
*/
@ -474,13 +366,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return $this->schema;
}
/**
* {@inheritdoc}
*/
public function condition($conjunction) {
return new Condition($conjunction);
}
/**
* {@inheritdoc}
*/
@ -488,13 +373,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return new TransactionManager($this);
}
/**
* {@inheritdoc}
*/
public function startTransaction($name = '') {
return $this->transactionManager()->push($name);
}
}

View File

@ -4,19 +4,10 @@ namespace Drupal\mysql\Driver\Database\mysql;
use Drupal\Core\Database\Query\Delete as QueryDelete;
@trigger_error('Extending from \Drupal\mysql\Driver\Database\mysql\Delete is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. Extend from the base class instead. See https://www.drupal.org/node/3256524', E_USER_DEPRECATED);
/**
* MySQL implementation of \Drupal\Core\Database\Query\Delete.
*/
class Delete extends QueryDelete {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
}

View File

@ -9,16 +9,6 @@ use Drupal\Core\Database\Query\Insert as QueryInsert;
*/
class Insert extends QueryInsert {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
public function execute() {
if (!$this->preExecute()) {
return NULL;

View File

@ -4,19 +4,10 @@ namespace Drupal\mysql\Driver\Database\mysql;
use Drupal\Core\Database\Query\Merge as QueryMerge;
@trigger_error('Extending from \Drupal\mysql\Driver\Database\mysql\Merge is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. Extend from the base class instead. See https://www.drupal.org/node/3256524', E_USER_DEPRECATED);
/**
* MySQL implementation of \Drupal\Core\Database\Query\Merge.
*/
class Merge extends QueryMerge {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
}

View File

@ -4,19 +4,10 @@ namespace Drupal\mysql\Driver\Database\mysql;
use Drupal\Core\Database\Query\Select as QuerySelect;
@trigger_error('Extending from \Drupal\mysql\Driver\Database\mysql\Select is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. Extend from the base class instead. See https://www.drupal.org/node/3256524', E_USER_DEPRECATED);
/**
* MySQL implementation of \Drupal\Core\Database\Query\Select.
*/
class Select extends QuerySelect {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, $table, $alias = NULL, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $alias, $options);
unset($this->queryOptions['return']);
}
}

View File

@ -4,19 +4,10 @@ namespace Drupal\mysql\Driver\Database\mysql;
use Drupal\Core\Database\Query\Truncate as QueryTruncate;
@trigger_error('Extending from \Drupal\mysql\Driver\Database\mysql\Truncate is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. Extend from the base class instead. See https://www.drupal.org/node/3256524', E_USER_DEPRECATED);
/**
* MySQL implementation of \Drupal\Core\Database\Query\Truncate.
*/
class Truncate extends QueryTruncate {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
}

View File

@ -4,19 +4,10 @@ namespace Drupal\mysql\Driver\Database\mysql;
use Drupal\Core\Database\Query\Update as QueryUpdate;
@trigger_error('Extending from \Drupal\mysql\Driver\Database\mysql\Update is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. Extend from the base class instead. See https://www.drupal.org/node/3256524', E_USER_DEPRECATED);
/**
* MySQL implementation of \Drupal\Core\Database\Query\Update.
*/
class Update extends QueryUpdate {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
}

View File

@ -9,16 +9,6 @@ use Drupal\Core\Database\Query\Upsert as QueryUpsert;
*/
class Upsert extends QueryUpsert {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
/**
* {@inheritdoc}
*/

View File

@ -21,14 +21,4 @@ class ConnectionTest extends DriverSpecificDatabaseTestBase {
Database::getConnection('default', 'default')->query('SELECT * FROM {test}; SELECT * FROM {test_people}', [], ['allow_delimiter_in_query' => TRUE]);
}
/**
* Tests deprecation of ::makeSequenceName().
*
* @group legacy
*/
public function testMakeSequenceNameDeprecation(): void {
$this->expectDeprecation("Drupal\\Core\\Database\\Connection::makeSequenceName() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3377046");
$this->assertIsString($this->connection->makeSequenceName('foo', 'bar'));
}
}

View File

@ -1,79 +0,0 @@
<?php
namespace Drupal\Tests\mysql\Kernel\mysql;
use Drupal\Core\Database\Driver\mysql\Connection;
use Drupal\Core\Database\Driver\mysql\ExceptionHandler;
use Drupal\Core\Database\Driver\mysql\Install\Tasks;
use Drupal\Core\Database\Driver\mysql\Insert;
use Drupal\Core\Database\Driver\mysql\Schema;
use Drupal\Core\Database\Driver\mysql\Upsert;
use Drupal\KernelTests\Core\Database\DriverSpecificDatabaseTestBase;
use Drupal\Tests\Core\Database\Stub\StubPDO;
/**
* Tests the deprecations of the MySQL database driver classes in Core.
*
* @group legacy
* @group Database
*/
class MysqlDriverLegacyTest extends DriverSpecificDatabaseTestBase {
/**
* @covers Drupal\Core\Database\Driver\mysql\Install\Tasks
*/
public function testDeprecationInstallTasks() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\mysql\Install\Tasks is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492');
$tasks = new Tasks();
$this->assertInstanceOf(Tasks::class, $tasks);
}
/**
* @covers Drupal\Core\Database\Driver\mysql\Connection
*/
public function testDeprecationConnection() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\mysql\Connection is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492');
// @todo https://www.drupal.org/project/drupal/issues/3251084 Remove setting
// the $options parameter.
$options['init_commands']['sql_mode'] = '';
$connection = new Connection($this->createMock(StubPDO::class), $options);
$this->assertInstanceOf(Connection::class, $connection);
}
/**
* @covers Drupal\Core\Database\Driver\mysql\ExceptionHandler
*/
public function testDeprecationExceptionHandler() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\mysql\ExceptionHandler is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492');
$handler = new ExceptionHandler();
$this->assertInstanceOf(ExceptionHandler::class, $handler);
}
/**
* @covers Drupal\Core\Database\Driver\mysql\Insert
*/
public function testDeprecationInsert() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\mysql\Insert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492');
$insert = new Insert($this->connection, 'test');
$this->assertInstanceOf(Insert::class, $insert);
}
/**
* @covers Drupal\Core\Database\Driver\mysql\Schema
*/
public function testDeprecationSchema() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\mysql\Schema is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492');
$schema = new Schema($this->connection);
$this->assertInstanceOf(Schema::class, $schema);
}
/**
* @covers Drupal\Core\Database\Driver\mysql\Upsert
*/
public function testDeprecationUpsert() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\mysql\Upsert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The MySQL database driver has been moved to the mysql module. See https://www.drupal.org/node/3129492');
$upsert = new Upsert($this->connection, 'test');
$this->assertInstanceOf(Upsert::class, $upsert);
}
}

View File

@ -1,75 +0,0 @@
<?php
namespace Drupal\Tests\mysql\Kernel\mysql;
use Drupal\Core\Database\Database;
use Drupal\KernelTests\Core\Database\DriverSpecificDatabaseTestBase;
/**
* Tests the sequences API.
*
* @group Database
* @group legacy
*/
class NextIdTest extends DriverSpecificDatabaseTestBase {
/**
* The modules to enable.
*
* @var array
*/
protected static $modules = ['database_test', 'system'];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$table_specification = [
'description' => 'Stores IDs.',
'fields' => [
'value' => [
'description' => 'The value of the sequence.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
],
'primary key' => ['value'],
];
$this->connection->schema()->createTable('sequences', $table_specification);
}
/**
* Tests that sequences table clear up works when a connection is closed.
*
* @see \Drupal\mysql\Driver\Database\mysql\Connection::__destruct()
*/
public function testDbNextIdClosedConnection() {
$this->expectDeprecation('Drupal\Core\Database\Connection::nextId() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Modules should use instead the keyvalue storage for the last used id. See https://www.drupal.org/node/3349345');
$this->expectDeprecation('Drupal\mysql\Driver\Database\mysql\Connection::nextIdDelete() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Modules should use instead the keyvalue storage for the last used id. See https://www.drupal.org/node/3349345');
// Create an additional connection to test closing the connection.
$connection_info = Database::getConnectionInfo();
Database::addConnectionInfo('default', 'next_id', $connection_info['default']);
// Get a few IDs to ensure there the clean up needs to run and there is more
// than one row.
Database::getConnection('next_id')->nextId();
Database::getConnection('next_id')->nextId();
// At this point the sequences table should contain unnecessary rows.
$count = $this->connection->select('sequences')->countQuery()->execute()->fetchField();
$this->assertGreaterThan(1, $count);
// Close the connection.
Database::closeConnection('next_id');
// Test that \Drupal\mysql\Driver\Database\mysql\Connection::__destruct()
// successfully trims the sequences table if the connection is closed.
$count = $this->connection->select('sequences')->countQuery()->execute()->fetchField();
$this->assertEquals(1, $count);
}
}

View File

@ -7,7 +7,6 @@ use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseAccessDeniedException;
use Drupal\Core\Database\DatabaseNotFoundException;
use Drupal\Core\Database\ExceptionHandler;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\StatementInterface;
use Drupal\Core\Database\StatementWrapperIterator;
use Drupal\Core\Database\SupportsTemporaryTablesInterface;
@ -343,49 +342,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return str_replace($this->identifierQuotes, '', $sequence_name);
}
/**
* Retrieve a the next id in a sequence.
*
* PostgreSQL has built in sequences. We'll use these instead of inserting
* and updating a sequences table.
*/
public function nextId($existing = 0) {
@trigger_error('Drupal\Core\Database\Connection::nextId() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Modules should use instead the keyvalue storage for the last used id. See https://www.drupal.org/node/3349345', E_USER_DEPRECATED);
// Retrieve the name of the sequence. This information cannot be cached
// because the prefix may change, for example, like it does in tests.
$sequence_name = $this->makeSequenceName('sequences', 'value');
// When PostgreSQL gets a value too small then it will lock the table,
// retry the INSERT and if it's still too small then alter the sequence.
$id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
if ($id > $existing) {
return $id;
}
// PostgreSQL advisory locks are simply locks to be used by an
// application such as Drupal. This will prevent other Drupal processes
// from altering the sequence while we are.
$this->query("SELECT pg_advisory_lock(" . self::POSTGRESQL_NEXTID_LOCK . ")");
// While waiting to obtain the lock, the sequence may have been altered
// so lets try again to obtain an adequate value.
$id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
if ($id > $existing) {
$this->query("SELECT pg_advisory_unlock(" . self::POSTGRESQL_NEXTID_LOCK . ")");
return $id;
}
// Reset the sequence to a higher value than the existing id.
$this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));
// Retrieve the next id. We know this will be as high as we want it.
$id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
$this->query("SELECT pg_advisory_unlock(" . self::POSTGRESQL_NEXTID_LOCK . ")");
return $id;
}
/**
* {@inheritdoc}
*/
@ -474,13 +430,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return new Insert($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function merge($table, array $options = []) {
return new Merge($this, $table, $options);
}
/**
* {@inheritdoc}
*/
@ -519,13 +468,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return $this->schema;
}
/**
* {@inheritdoc}
*/
public function condition($conjunction) {
return new Condition($conjunction);
}
/**
* {@inheritdoc}
*/
@ -533,13 +475,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return new TransactionManager($this);
}
/**
* {@inheritdoc}
*/
public function startTransaction($name = '') {
return $this->transactionManager()->push($name);
}
}
/**

View File

@ -9,16 +9,6 @@ use Drupal\Core\Database\Query\Delete as QueryDelete;
*/
class Delete extends QueryDelete {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
/**
* {@inheritdoc}
*/

View File

@ -17,16 +17,6 @@ use Drupal\Core\Database\Query\Insert as QueryInsert;
*/
class Insert extends QueryInsert {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
public function execute() {
if (!$this->preExecute()) {
return NULL;

View File

@ -251,11 +251,7 @@ class Tasks extends InstallTasks {
$connection = Database::getConnection();
try {
// Enable pg_trgm for PostgreSQL 13 or higher.
// @todo Remove this if-statement in D11 when the minimum required version
// for PostgreSQL becomes 13 or higher. https://www.drupal.org/i/3357409
if (version_compare($connection->version(), '13.0', '>=')) {
$connection->query('CREATE EXTENSION IF NOT EXISTS pg_trgm');
}
$connection->query('CREATE EXTENSION IF NOT EXISTS pg_trgm');
if ($connection->schema()->extensionExists('pg_trgm')) {
$this->pass(t('PostgreSQL has the pg_trgm extension enabled.'));

View File

@ -4,19 +4,10 @@ namespace Drupal\pgsql\Driver\Database\pgsql;
use Drupal\Core\Database\Query\Merge as QueryMerge;
@trigger_error('Extending from \Drupal\pgsql\Driver\Database\pgsql\Merge is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. Extend from the base class instead. See https://www.drupal.org/node/3256524', E_USER_DEPRECATED);
/**
* PostgreSQL implementation of \Drupal\Core\Database\Query\Merge.
*/
class Merge extends QueryMerge {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
}

View File

@ -14,16 +14,6 @@ use Drupal\Core\Database\Query\Select as QuerySelect;
*/
class Select extends QuerySelect {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, $table, $alias = NULL, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $alias, $options);
unset($this->queryOptions['return']);
}
public function orderRandom() {
$alias = $this->addExpression('RANDOM()', 'random_field');
$this->orderBy($alias);

View File

@ -9,16 +9,6 @@ use Drupal\Core\Database\Query\Truncate as QueryTruncate;
*/
class Truncate extends QueryTruncate {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
/**
* {@inheritdoc}
*/

View File

@ -10,16 +10,6 @@ use Drupal\Core\Database\Query\SelectInterface;
*/
class Update extends QueryUpdate {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
public function execute() {
$max_placeholder = 0;
$blobs = [];

View File

@ -11,16 +11,6 @@ use Drupal\Core\Database\Query\Upsert as QueryUpsert;
*/
class Upsert extends QueryUpsert {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
/**
* {@inheritdoc}
*/

View File

@ -1,106 +0,0 @@
<?php
namespace Drupal\Tests\pgsql\Kernel\pgsql;
use Drupal\Core\Database\Driver\pgsql\Connection;
use Drupal\Core\Database\Driver\pgsql\Delete;
use Drupal\Core\Database\Driver\pgsql\Install\Tasks;
use Drupal\Core\Database\Driver\pgsql\Insert;
use Drupal\Core\Database\Driver\pgsql\Schema;
use Drupal\Core\Database\Driver\pgsql\Select;
use Drupal\Core\Database\Driver\pgsql\Truncate;
use Drupal\Core\Database\Driver\pgsql\Update;
use Drupal\Core\Database\Driver\pgsql\Upsert;
use Drupal\KernelTests\Core\Database\DriverSpecificDatabaseTestBase;
use Drupal\Tests\Core\Database\Stub\StubPDO;
/**
* Tests the deprecations of the PostgreSQL database driver classes in Core.
*
* @group legacy
* @group Database
*/
class PgsqlDriverLegacyTest extends DriverSpecificDatabaseTestBase {
/**
* @covers Drupal\Core\Database\Driver\pgsql\Install\Tasks
*/
public function testDeprecationInstallTasks() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\pgsql\Install\Tasks is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492');
$tasks = new Tasks();
$this->assertInstanceOf(Tasks::class, $tasks);
}
/**
* @covers Drupal\Core\Database\Driver\pgsql\Connection
*/
public function testDeprecationConnection() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\pgsql\Connection is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492');
$connection = new Connection($this->createMock(StubPDO::class), []);
$this->assertInstanceOf(Connection::class, $connection);
}
/**
* @covers Drupal\Core\Database\Driver\pgsql\Delete
*/
public function testDeprecationDelete() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\pgsql\Delete is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492');
$delete = new Delete($this->connection, 'test');
$this->assertInstanceOf(Delete::class, $delete);
}
/**
* @covers Drupal\Core\Database\Driver\pgsql\Insert
*/
public function testDeprecationInsert() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\pgsql\Insert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492');
$insert = new Insert($this->connection, 'test');
$this->assertInstanceOf(Insert::class, $insert);
}
/**
* @covers Drupal\Core\Database\Driver\pgsql\Schema
*/
public function testDeprecationSchema() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\pgsql\Schema is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492');
$schema = new Schema($this->connection);
$this->assertInstanceOf(Schema::class, $schema);
}
/**
* @covers Drupal\Core\Database\Driver\pgsql\Select
*/
public function testDeprecationSelect() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\pgsql\Select is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492');
$select = new Select($this->connection, 'test');
$this->assertInstanceOf(Select::class, $select);
}
/**
* @covers Drupal\Core\Database\Driver\pgsql\Truncate
*/
public function testDeprecationTruncate() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\pgsql\Truncate is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492');
$truncate = new Truncate($this->connection, 'test');
$this->assertInstanceOf(Truncate::class, $truncate);
}
/**
* @covers Drupal\Core\Database\Driver\pgsql\Update
*/
public function testDeprecationUpdate() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\pgsql\Update is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492');
$update = new Update($this->connection, 'test');
$this->assertInstanceOf(Update::class, $update);
}
/**
* @covers Drupal\Core\Database\Driver\pgsql\Upsert
*/
public function testDeprecationUpsert() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\pgsql\Upsert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The PostgreSQL database driver has been moved to the pgsql module. See https://www.drupal.org/node/3129492');
$upsert = new Upsert($this->connection, 'test');
$this->assertInstanceOf(Upsert::class, $upsert);
}
}

View File

@ -234,7 +234,7 @@ class SchemaTest extends DriverSpecificSchemaTestBase {
}
/**
* @covers \Drupal\Core\Database\Driver\pgsql\Schema::extensionExists
* @covers \Drupal\pgsql\Driver\Database\pgsql\Schema::extensionExists
*/
public function testPgsqlExtensionExists(): void {
// Test the method for a non existing extension.

View File

@ -3,10 +3,8 @@
namespace Drupal\sqlite\Driver\Database\sqlite;
use Drupal\Core\Database\Connection as DatabaseConnection;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Database\DatabaseNotFoundException;
use Drupal\Core\Database\ExceptionHandler;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\StatementInterface;
use Drupal\Core\Database\SupportsTemporaryTablesInterface;
use Drupal\Core\Database\Transaction\TransactionManagerInterface;
@ -26,18 +24,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
*/
protected $statementWrapperClass = NULL;
/**
* Whether or not the active transaction (if any) will be rolled back.
*
* @var bool
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. It is
* unused.
*
* @see https://www.drupal.org/node/3381002
*/
protected $willRollback;
/**
* A map of condition operators to SQLite operators.
*
@ -410,9 +396,7 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
* {@inheritdoc}
*/
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);
}
assert(!isset($options['return']), 'Passing "return" option to prepareStatement() has no effect. See https://www.drupal.org/node/3185520');
try {
$query = $this->preprocessStatement($query, $options);
@ -424,42 +408,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return $statement;
}
/**
* {@inheritdoc}
*/
public function nextId($existing_id = 0) {
@trigger_error('Drupal\Core\Database\Connection::nextId() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Modules should use instead the keyvalue storage for the last used id. See https://www.drupal.org/node/3349345', E_USER_DEPRECATED);
try {
$this->startTransaction();
}
catch (\PDOException $e) {
// $this->exceptionHandler()->handleExecutionException()
// requires a $statement argument, so we cannot use that.
throw new DatabaseExceptionWrapper($e->getMessage(), 0, $e);
}
// We can safely use literal queries here instead of the slower query
// builder because if a given database breaks here then it can simply
// override nextId. However, this is unlikely as we deal with short strings
// and integers and no known databases require special handling for those
// simple cases. If another transaction wants to write the same row, it will
// wait until this transaction commits.
$stmt = $this->prepareStatement('UPDATE {sequences} SET [value] = GREATEST([value], :existing_id) + 1', [], TRUE);
$args = [':existing_id' => $existing_id];
try {
$stmt->execute($args);
}
catch (\Exception $e) {
$this->exceptionHandler()->handleExecutionException($e, $stmt, $args, []);
}
if ($stmt->rowCount() === 0) {
$this->query('INSERT INTO {sequences} ([value]) VALUES (:existing_id + 1)', $args);
}
// The transaction gets committed when the transaction object gets destroyed
// because it gets out of scope.
return $this->query('SELECT [value] FROM {sequences}')->fetchField();
}
/**
* {@inheritdoc}
*/
@ -537,13 +485,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return new Insert($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function merge($table, array $options = []) {
return new Merge($this, $table, $options);
}
/**
* {@inheritdoc}
*/
@ -551,20 +492,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return new Upsert($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function update($table, array $options = []) {
return new Update($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function delete($table, array $options = []) {
return new Delete($this, $table, $options);
}
/**
* {@inheritdoc}
*/
@ -582,13 +509,6 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return $this->schema;
}
/**
* {@inheritdoc}
*/
public function condition($conjunction) {
return new Condition($conjunction);
}
/**
* {@inheritdoc}
*/
@ -596,11 +516,4 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
return new TransactionManager($this);
}
/**
* {@inheritdoc}
*/
public function startTransaction($name = '') {
return $this->transactionManager()->push($name);
}
}

View File

@ -4,19 +4,10 @@ namespace Drupal\sqlite\Driver\Database\sqlite;
use Drupal\Core\Database\Query\Delete as QueryDelete;
@trigger_error('Extending from \Drupal\sqlite\Driver\Database\sqlite\Delete is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. Extend from the base class instead. See https://www.drupal.org/node/3256524', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Query\Delete.
*/
class Delete extends QueryDelete {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
}

View File

@ -14,16 +14,6 @@ use Drupal\Core\Database\Query\Insert as QueryInsert;
*/
class Insert extends QueryInsert {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
/**
* {@inheritdoc}
*/

View File

@ -4,19 +4,10 @@ namespace Drupal\sqlite\Driver\Database\sqlite;
use Drupal\Core\Database\Query\Merge as QueryMerge;
@trigger_error('Extending from \Drupal\sqlite\Driver\Database\sqlite\Merge is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. Extend from the base class instead. See https://www.drupal.org/node/3256524', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Query\Merge.
*/
class Merge extends QueryMerge {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
}

View File

@ -9,16 +9,6 @@ use Drupal\Core\Database\Query\Select as QuerySelect;
*/
class Select extends QuerySelect {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, $table, $alias = NULL, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $alias, $options);
unset($this->queryOptions['return']);
}
public function forUpdate($set = TRUE) {
// SQLite does not support FOR UPDATE so nothing to do.
return $this;

View File

@ -12,16 +12,6 @@ use Drupal\Core\Database\Query\Truncate as QueryTruncate;
*/
class Truncate extends QueryTruncate {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
public function __toString() {
// Create a sanitized comment string to prepend to the query.
$comments = $this->connection->makeComment($this->comments);

View File

@ -4,19 +4,10 @@ namespace Drupal\sqlite\Driver\Database\sqlite;
use Drupal\Core\Database\Query\Update as QueryUpdate;
@trigger_error('Extending from \Drupal\sqlite\Driver\Database\sqlite\Update is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. Extend from the base class instead. See https://www.drupal.org/node/3256524', E_USER_DEPRECATED);
/**
* SQLite implementation of \Drupal\Core\Database\Query\Update.
*/
class Update extends QueryUpdate {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
}

View File

@ -11,16 +11,6 @@ use Drupal\Core\Database\Query\Upsert as QueryUpsert;
*/
class Upsert extends QueryUpsert {
/**
* {@inheritdoc}
*/
public function __construct(Connection $connection, string $table, array $options = []) {
// @todo Remove the __construct in Drupal 11.
// @see https://www.drupal.org/project/drupal/issues/3256524
parent::__construct($connection, $table, $options);
unset($this->queryOptions['return']);
}
/**
* {@inheritdoc}
*/

View File

@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\sqlite\Kernel\sqlite;
use Drupal\KernelTests\Core\Database\DriverSpecificDatabaseTestBase;
/**
* SQLite-specific connection tests.
*
* @group Database
*/
class ConnectionTest extends DriverSpecificDatabaseTestBase {
/**
* Tests deprecation of ::makeSequenceName().
*
* @group legacy
*/
public function testMakeSequenceNameDeprecation(): void {
$this->expectDeprecation("Drupal\\Core\\Database\\Connection::makeSequenceName() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3377046");
$this->assertIsString($this->connection->makeSequenceName('foo', 'bar'));
}
}

View File

@ -1,96 +0,0 @@
<?php
namespace Drupal\Tests\sqlite\Kernel\sqlite;
use Drupal\Core\Database\Driver\sqlite\Connection;
use Drupal\Core\Database\Driver\sqlite\Install\Tasks;
use Drupal\Core\Database\Driver\sqlite\Insert;
use Drupal\Core\Database\Driver\sqlite\Schema;
use Drupal\Core\Database\Driver\sqlite\Select;
use Drupal\Core\Database\Driver\sqlite\Statement;
use Drupal\Core\Database\Driver\sqlite\Truncate;
use Drupal\Core\Database\Driver\sqlite\Upsert;
use Drupal\KernelTests\Core\Database\DriverSpecificDatabaseTestBase;
use Drupal\Tests\Core\Database\Stub\StubPDO;
/**
* Tests the deprecations of the SQLite database driver classes in Core.
*
* @group legacy
* @group Database
*/
class SqliteDriverLegacyTest extends DriverSpecificDatabaseTestBase {
/**
* @covers Drupal\Core\Database\Driver\sqlite\Install\Tasks
*/
public function testDeprecationInstallTasks() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\sqlite\Install\Tasks is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492');
$tasks = new Tasks();
$this->assertInstanceOf(Tasks::class, $tasks);
}
/**
* @covers Drupal\Core\Database\Driver\sqlite\Connection
*/
public function testDeprecationConnection() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\sqlite\Connection is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492');
$connection = new Connection($this->createMock(StubPDO::class), []);
$this->assertInstanceOf(Connection::class, $connection);
}
/**
* @covers Drupal\Core\Database\Driver\sqlite\Insert
*/
public function testDeprecationInsert() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\sqlite\Insert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492');
$insert = new Insert($this->connection, 'test');
$this->assertInstanceOf(Insert::class, $insert);
}
/**
* @covers Drupal\Core\Database\Driver\sqlite\Schema
*/
public function testDeprecationSchema() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\sqlite\Schema is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492');
$schema = new Schema($this->connection);
$this->assertInstanceOf(Schema::class, $schema);
}
/**
* @covers Drupal\Core\Database\Driver\sqlite\Select
*/
public function testDeprecationSelect() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\sqlite\Select is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492');
$select = new Select($this->connection, 'test');
$this->assertInstanceOf(Select::class, $select);
}
/**
* @covers Drupal\Core\Database\Driver\sqlite\Statement
*/
public function testDeprecationStatement() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\sqlite\Statement is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492');
$statement = new Statement($this->createMock(StubPDO::class), $this->connection, '', []);
$this->assertInstanceOf(Statement::class, $statement);
}
/**
* @covers Drupal\Core\Database\Driver\sqlite\Truncate
*/
public function testDeprecationTruncate() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\sqlite\Truncate is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492');
$truncate = new Truncate($this->connection, 'test');
$this->assertInstanceOf(Truncate::class, $truncate);
}
/**
* @covers Drupal\Core\Database\Driver\sqlite\Upsert
*/
public function testDeprecationUpsert() {
$this->expectDeprecation('\Drupal\Core\Database\Driver\sqlite\Upsert is deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. The SQLite database driver has been moved to the sqlite module. See https://www.drupal.org/node/3129492');
$upsert = new Upsert($this->connection, 'test');
$this->assertInstanceOf(Upsert::class, $upsert);
}
}

View File

@ -20,15 +20,6 @@ parameters:
count: 1
path: includes/form.inc
-
message: """
#^Call to deprecated method getFromDriverName\\(\\) of class Drupal\\\\Core\\\\Extension\\\\DatabaseDriverList\\:
in drupal\\:10\\.2\\.0 and is removed from drupal\\:11\\.0\\.0\\. Use
DatabaseDriverList\\:\\:get\\(\\) instead, passing a database driver namespace\\.$#
"""
count: 1
path: includes/install.core.inc
-
message: "#^Function install_config_download_translations\\(\\) should return string but return statement is missing\\.$#"
count: 1
@ -188,15 +179,6 @@ parameters:
count: 1
path: lib/Drupal/Core/Condition/ConditionManager.php
-
message: """
#^Fetching deprecated class constant RETURN_AFFECTED of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 4
path: lib/Drupal/Core/Config/DatabaseStorage.php
-
message: "#^Variable \\$value in isset\\(\\) always exists and is not nullable\\.$#"
count: 2
@ -207,120 +189,21 @@ parameters:
count: 1
path: lib/Drupal/Core/Config/ExtensionInstallStorage.php
-
message: """
#^Fetching deprecated class constant RETURN_AFFECTED of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Connection.php
-
message: """
#^Fetching deprecated class constant RETURN_INSERT_ID of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Connection.php
-
message: """
#^Fetching deprecated class constant RETURN_NULL of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Connection.php
-
message: """
#^Fetching deprecated class constant RETURN_STATEMENT of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 2
path: lib/Drupal/Core/Database/Connection.php
-
message: "#^Variable \\$statement might not be defined\\.$#"
count: 1
path: lib/Drupal/Core/Database/Connection.php
-
message: """
#^Fetching deprecated class constant RETURN_AFFECTED of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Query/Delete.php
-
message: "#^Method Drupal\\\\Core\\\\Database\\\\Query\\\\Delete\\:\\:execute\\(\\) should return int but return statement is missing\\.$#"
count: 1
path: lib/Drupal/Core/Database/Query/Delete.php
-
message: """
#^Fetching deprecated class constant RETURN_INSERT_ID of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Query/Insert.php
-
message: """
#^Fetching deprecated class constant RETURN_AFFECTED of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Query/Merge.php
-
message: "#^Method Drupal\\\\Core\\\\Database\\\\Query\\\\Merge\\:\\:__toString\\(\\) should return string but return statement is missing\\.$#"
count: 1
path: lib/Drupal/Core/Database/Query/Merge.php
-
message: """
#^Fetching deprecated class constant RETURN_STATEMENT of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Query/Select.php
-
message: """
#^Fetching deprecated class constant RETURN_AFFECTED of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Query/Truncate.php
-
message: """
#^Fetching deprecated class constant RETURN_AFFECTED of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Query/Update.php
-
message: """
#^Fetching deprecated class constant RETURN_AFFECTED of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Database/Query/Upsert.php
-
message: "#^Variable \\$affected_rows might not be defined\\.$#"
count: 1
@ -445,15 +328,6 @@ parameters:
count: 5
path: lib/Drupal/Core/Entity/Query/Sql/Tables.php
-
message: """
#^Fetching deprecated class constant RETURN_INSERT_ID of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 2
path: lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
-
message: "#^Variable \\$revision_query might not be defined\\.$#"
count: 2
@ -634,15 +508,6 @@ parameters:
count: 1
path: lib/Drupal/Core/Menu/MenuLinkManager.php
-
message: """
#^Fetching deprecated class constant RETURN_INSERT_ID of class Drupal\\\\Core\\\\Database\\\\Database\\:
in drupal\\:9\\.4\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is no
replacement\\.$#
"""
count: 1
path: lib/Drupal/Core/Menu/MenuTreeStorage.php
-
message: "#^Variable \\$transaction in isset\\(\\) always exists and is not nullable\\.$#"
count: 1
@ -1484,15 +1349,6 @@ parameters:
count: 8
path: modules/migrate_drupal_ui/tests/src/Functional/MultilingualReviewPageTestBase.php
-
message: """
#^Access to deprecated property \\$needsCleanup of class Drupal\\\\mysql\\\\Driver\\\\Database\\\\mysql\\\\Connection\\:
in drupal\\:10\\.2\\.0 and is removed from drupal\\:11\\.0\\.0\\. There's no
replacement\\.$#
"""
count: 1
path: modules/mysql/src/Driver/Database/mysql/Connection.php
-
message: "#^Variable \\$last_insert_id might not be defined\\.$#"
count: 1
@ -1588,15 +1444,6 @@ parameters:
count: 1
path: modules/path/src/Plugin/Field/FieldType/PathItem.php
-
message: """
#^Call to deprecated method makeSequenceName\\(\\) of class Drupal\\\\Core\\\\Database\\\\Connection\\:
in drupal\\:10\\.2\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is
no replacement\\.$#
"""
count: 1
path: modules/pgsql/src/Driver/Database/pgsql/Schema.php
-
message: "#^Variable \\$table_field might not be defined\\.$#"
count: 1
@ -1607,15 +1454,6 @@ parameters:
count: 1
path: modules/pgsql/src/Driver/Database/pgsql/Upsert.php
-
message: """
#^Call to deprecated method makeSequenceName\\(\\) of class Drupal\\\\Core\\\\Database\\\\Connection\\:
in drupal\\:10\\.2\\.0 and is removed from drupal\\:11\\.0\\.0\\. There is
no replacement\\.$#
"""
count: 1
path: modules/pgsql/src/Update10101.php
-
message: "#^Variable \\$responsive_image_styles in empty\\(\\) always exists and is not falsy\\.$#"
count: 1
@ -2412,22 +2250,6 @@ parameters:
count: 2
path: tests/Drupal/KernelTests/Core/Database/DriverSpecificKernelTestBase.php
-
message: """
#^Call to deprecated method expectError\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\:
https\\://github\\.com/sebastianbergmann/phpunit/issues/5062$#
"""
count: 3
path: tests/Drupal/KernelTests/Core/Database/StatementTest.php
-
message: """
#^Call to deprecated method expectErrorMessage\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\:
https\\://github\\.com/sebastianbergmann/phpunit/issues/5062$#
"""
count: 3
path: tests/Drupal/KernelTests/Core/Database/StatementTest.php
-
message: "#^Variable \\$title might not be defined\\.$#"
count: 2
@ -2617,24 +2439,6 @@ parameters:
count: 1
path: tests/Drupal/Tests/Core/Database/ConditionTest.php
-
message: """
#^Call to deprecated method findCaller\\(\\) of class Drupal\\\\Core\\\\Database\\\\Log\\:
in drupal\\:10\\.1\\.0 and is removed from drupal\\:11\\.0\\.0\\. Use
Connection\\:\\:findCallerFromDebugBacktrace\\(\\)\\.$#
"""
count: 1
path: tests/Drupal/Tests/Core/Database/Stub/StubConnection.php
-
message: """
#^Fetching class constant class of deprecated class Drupal\\\\Core\\\\Database\\\\StatementWrapper\\:
in drupal\\:10\\.1\\.0 and is removed from drupal\\:11\\.0\\.0\\. Use
\\\\Drupal\\\\Core\\\\Database\\\\StatementWrapperIterator instead\\.$#
"""
count: 1
path: tests/Drupal/Tests/Core/Database/Stub/StubConnection.php
-
message: """
#^Class Drupal\\\\Tests\\\\Core\\\\DependencyInjection\\\\DependencySerializationTestDummy implements deprecated interface Symfony\\\\Component\\\\DependencyInjection\\\\ContainerAwareInterface\\:

View File

@ -1,54 +0,0 @@
<?php
declare(strict_types=1);
namespace Drupal\FunctionalTests\Installer;
use Drupal\Core\Database\Database;
use Drupal\Tests\BrowserTestBase;
/**
* Tests deprecation of the non-interactive installer with driver name.
*
* @group Installer
* @group legacy
*/
class InstallerDeprecatedDriverNameTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Execute the non-interactive installer.
*
* @see install_drupal()
*/
protected function doInstall() {
require_once DRUPAL_ROOT . '/core/includes/install.core.inc';
$parameters = $this->installParameters();
// Replace the driver namespace with the driver name in the
// 'install_settings_form' parameter.
$driverNamespace = $parameters['forms']['install_settings_form']['driver'];
$driverName = Database::getDriverList()->get($driverNamespace)->getDriverName();
$parameters['forms']['install_settings_form']['driver'] = $driverName;
$parameters['forms']['install_settings_form'][$driverName] = $parameters['forms']['install_settings_form'][$driverNamespace];
unset($parameters['forms']['install_settings_form'][$driverNamespace]);
// Simulate a real install which does not start with the any connections set
// in \Drupal\Core\Database\Database::$connections.
Database::removeConnection('default');
$this->expectDeprecation("Passing a database driver name '{$driverName}' to install_get_form() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Pass a database driver namespace instead. See https://www.drupal.org/node/3258175");
$this->expectDeprecation('Drupal\\Core\\Extension\\DatabaseDriverList::getFromDriverName() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use DatabaseDriverList::get() instead, passing a database driver namespace. See https://www.drupal.org/node/3258175');
install_drupal($this->classLoader, $parameters);
}
/**
* Verifies that installation succeeded.
*/
public function testInstaller() {
$this->assertSession()->addressEquals('/');
$this->assertSession()->statusCodeEquals(200);
}
}

View File

@ -172,16 +172,6 @@ class ConnectionTest extends DatabaseTestBase {
$this->assertSame($namespace, get_class($condition));
}
/**
* Tests deprecation of ::getUnprefixedTablesMap().
*
* @group legacy
*/
public function testDeprecatedGetUnprefixedTablesMap() {
$this->expectDeprecation('Drupal\Core\Database\Connection::getUnprefixedTablesMap() is deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3257198');
$this->assertIsArray($this->connection->getUnprefixedTablesMap());
}
/**
* Tests that the method ::hasJson() returns TRUE.
*/
@ -189,14 +179,4 @@ class ConnectionTest extends DatabaseTestBase {
$this->assertTrue($this->connection->hasJson());
}
/**
* Tests deprecation of ::tablePrefix().
*
* @group legacy
*/
public function testDeprecatedTablePrefix(): void {
$this->expectDeprecation('Drupal\Core\Database\Connection::tablePrefix() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Instead, you should just use Connection::getPrefix(). See https://www.drupal.org/node/3260849');
$this->assertIsString($this->connection->tablePrefix());
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace Drupal\KernelTests\Core\Database;
use Drupal\Core\Database\Database;
/**
* Legacy database tests.
*
* @group Database
* @group legacy
*/
class DatabaseLegacyTest extends DatabaseTestBase {
/**
* Tests deprecation of install.inc database driver functions.
*/
public function testDeprecatedInstallFunctions() {
include_once $this->root . '/core/includes/install.inc';
$this->expectDeprecation('drupal_detect_database_types() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use DatabaseDriverList::getList() instead. See https://www.drupal.org/node/3258175');
$this->expectDeprecation('drupal_get_database_types() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use DatabaseDriverList::getList() instead. See https://www.drupal.org/node/3258175');
$installableDriverNames = [];
foreach (Database::getDriverList()->getInstallableList() as $driver => $driverExtension) {
$installableDriverNames[$driverExtension->getDriverName()] = $driverExtension->getInstallTasks()->name();
}
$this->assertEquals($installableDriverNames, drupal_detect_database_types());
}
}

View File

@ -8,7 +8,6 @@ use Drupal\Core\Database\Transaction\ClientConnectionTransactionState;
use Drupal\Core\Database\Transaction\StackItem;
use Drupal\Core\Database\Transaction\StackItemType;
use Drupal\Core\Database\Transaction\TransactionManagerBase;
use Drupal\Core\Database\TransactionExplicitCommitNotAllowedException;
use Drupal\Core\Database\TransactionNameNonUniqueException;
use Drupal\Core\Database\TransactionOutOfOrderException;
use PHPUnit\Framework\Error\Warning;
@ -837,48 +836,4 @@ class DriverSpecificTransactionTestBase extends DriverSpecificDatabaseTestBase {
Database::closeConnection('test_fail');
}
/**
* Tests deprecation of Connection methods.
*
* @group legacy
*/
public function testConnectionDeprecations(): void {
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$this->expectDeprecation('Drupal\\Core\\Database\\Connection::transactionDepth() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Do not access the transaction stack depth, it is an implementation detail. See https://www.drupal.org/node/3381002');
$this->assertSame(1, $this->connection->transactionDepth());
$this->insertRow('row');
$this->expectDeprecation('Drupal\\Core\\Database\\Connection::rollBack() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Do not rollback the connection, roll back the Transaction objects instead. See https://www.drupal.org/node/3381002');
$this->connection->rollback();
$transaction = NULL;
$this->assertRowAbsent('row');
$this->cleanUp();
$transaction = $this->connection->startTransaction();
$this->expectDeprecation('Drupal\\Core\\Database\\Connection::addRootTransactionEndCallback() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface::addPostTransactionCallback() instead. See https://www.drupal.org/node/3381002');
$this->connection->addRootTransactionEndCallback([$this, 'rootTransactionCallback']);
$this->insertRow('row');
$this->expectDeprecation('Drupal\\Core\\Database\\Connection::commit() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Do not commit the connection, void the Transaction objects instead. See https://www.drupal.org/node/3381002');
try {
$this->connection->commit();
}
catch (TransactionExplicitCommitNotAllowedException $e) {
// Do nothing.
}
$transaction = NULL;
$this->assertRowPresent('row');
$this->cleanUp();
$this->expectDeprecation('Drupal\\Core\\Database\\Connection::pushTransaction() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface methods instead. See https://www.drupal.org/node/3381002');
$this->connection->pushTransaction('foo');
$this->expectDeprecation('Drupal\\Core\\Database\\Connection::popTransaction() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface methods instead. See https://www.drupal.org/node/3381002');
$this->expectDeprecation('Drupal\\Core\\Database\\Connection::popCommittableTransactions() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface methods instead. See https://www.drupal.org/node/3381002');
$this->expectDeprecation('Drupal\\Core\\Database\\Connection::doCommit() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use TransactionManagerInterface methods instead. See https://www.drupal.org/node/3381002');
$this->connection->popTransaction('foo');
// Ensure there are no outstanding transactions left. This is necessary for
// the test to pass when xdebug.mode has the 'develop' option enabled.
$this->connection->commitAll();
}
}

View File

@ -115,30 +115,6 @@ class FetchTest extends DatabaseTestBase {
$this->assertSame(1, $records);
}
/**
* Confirms that we can fetch a record into a new instance of a custom class.
*
* The name of the class is determined from a value of the first column.
*
* @see \Drupal\Tests\system\Functional\Database\FakeRecord
*
* @group legacy
*/
public function testQueryFetchClasstype() {
$this->expectDeprecation('Fetch mode FETCH_CLASS | FETCH_CLASSTYPE is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999');
$records = [];
$result = $this->connection->query('SELECT [classname], [name], [job] FROM {test_classtype} WHERE [age] = :age', [':age' => 26], ['fetch' => \PDO::FETCH_CLASS | \PDO::FETCH_CLASSTYPE]);
foreach ($result as $record) {
$records[] = $record;
$this->assertInstanceOf(FakeRecord::class, $record);
$this->assertSame('Kay', $record->name);
$this->assertSame('Web Developer', $record->job);
$this->assertFalse(isset($record->classname), 'Classname field not found, as intended.');
}
$this->assertCount(1, $records, 'There is only one record.');
}
/**
* Confirms that we can fetch a record into an indexed array explicitly.
*/
@ -155,27 +131,6 @@ class FetchTest extends DatabaseTestBase {
$this->assertCount(1, $records, 'There is only one record');
}
/**
* Confirms that we can fetch a record into a doubly-keyed array explicitly.
*
* @group legacy
*/
public function testQueryFetchBoth() {
$this->expectDeprecation('Fetch mode FETCH_BOTH is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999');
$records = [];
$result = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25], ['fetch' => \PDO::FETCH_BOTH]);
foreach ($result as $record) {
$records[] = $record;
$this->assertIsArray($record);
$this->assertArrayHasKey(0, $record);
$this->assertSame('John', $record[0]);
$this->assertArrayHasKey('name', $record);
$this->assertSame('John', $record['name']);
}
$this->assertCount(1, $records, 'There is only one record.');
}
/**
* Confirms that we can fetch all records into an array explicitly.
*/

View File

@ -2,7 +2,6 @@
namespace Drupal\KernelTests\Core\Database;
use Drupal\Core\Database\Log;
use Drupal\Core\Database\Database;
/**
@ -141,197 +140,4 @@ class LoggingTest extends DatabaseTestBase {
$this->assertEquals([], $result, 'The function getLog with a wrong key returns an empty array.');
}
/**
* Tests that a log called by a custom database driver returns proper caller.
*
* @param string $driver_namespace
* The driver namespace to be tested.
* @param string $stack
* A test debug_backtrace stack.
* @param array $expected_entry
* The expected stack entry.
*
* @covers ::findCaller
*
* @dataProvider providerContribDriverLog
*
* @group legacy
*/
public function testContribDriverLog($driver_namespace, $stack, array $expected_entry) {
$this->expectDeprecation('Drupal\Core\Database\Log::findCaller() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use Connection::findCallerFromDebugBacktrace(). See https://www.drupal.org/node/3328053');
$this->expectDeprecation('Drupal\Core\Database\Log::removeDatabaseEntries() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use Connection::removeDatabaseEntriesFromDebugBacktrace(). See https://www.drupal.org/node/3328053');
$mock_builder = $this->getMockBuilder(Log::class);
$log = $mock_builder
->onlyMethods(['getDebugBacktrace'])
->setConstructorArgs(['test'])
->getMock();
$log->expects($this->once())
->method('getDebugBacktrace')
->willReturn($stack);
Database::addConnectionInfo('test', 'default', ['driver' => 'mysql', 'namespace' => $driver_namespace]);
$result = $log->findCaller($stack);
$this->assertEquals($expected_entry, $result);
}
/**
* Provides data for the testContribDriverLog test.
*
* @return array[]
* A associative array of simple arrays, each having the following elements:
* - the contrib driver PHP namespace
* - a test debug_backtrace stack
* - the stack entry expected to be returned.
*
* @see ::testContribDriverLog()
*/
public static function providerContribDriverLog() {
$stack = [
[
'file' => '/var/www/core/lib/Drupal/Core/Database/Log.php',
'line' => 125,
'function' => 'findCaller',
'class' => 'Drupal\\Core\\Database\\Log',
'object' => 'test',
'type' => '->',
'args' => [
0 => 'test',
],
],
[
'file' => '/var/www/libraries/test/lib/Statement.php',
'line' => 264,
'function' => 'log',
'class' => 'Drupal\\Core\\Database\\Log',
'object' => 'test',
'type' => '->',
'args' => [
0 => 'test',
],
],
[
'file' => '/var/www/libraries/test/lib/Connection.php',
'line' => 213,
'function' => 'execute',
'class' => 'Drupal\\Driver\\Database\\dbal\\Statement',
'object' => 'test',
'type' => '->',
'args' => [
0 => 'test',
],
],
[
'file' => '/var/www/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php',
'line' => 23,
'function' => 'query',
'class' => 'Drupal\\Driver\\Database\\dbal\\Connection',
'object' => 'test',
'type' => '->',
'args' => [
0 => 'test',
],
],
[
'file' => '/var/www/vendor/phpunit/phpunit/src/Framework/TestCase.php',
'line' => 1154,
'function' => 'testEnableLogging',
'class' => 'Drupal\\KernelTests\\Core\\Database\\LoggingTest',
'object' => 'test',
'type' => '->',
'args' => [
0 => 'test',
],
],
[
'file' => '/var/www/vendor/phpunit/phpunit/src/Framework/TestCase.php',
'line' => 842,
'function' => 'runTest',
'class' => 'PHPUnit\\Framework\\TestCase',
'object' => 'test',
'type' => '->',
'args' => [
0 => 'test',
],
],
[
'file' => '/var/www/vendor/phpunit/phpunit/src/Framework/TestResult.php',
'line' => 693,
'function' => 'runBare',
'class' => 'PHPUnit\\Framework\\TestCase',
'object' => 'test',
'type' => '->',
'args' => [
0 => 'test',
],
],
[
'file' => '/var/www/vendor/phpunit/phpunit/src/Framework/TestCase.php',
'line' => 796,
'function' => 'run',
'class' => 'PHPUnit\\Framework\\TestResult',
'object' => 'test',
'type' => '->',
'args' => [
0 => 'test',
],
],
[
'file' => 'Standard input code',
'line' => 57,
'function' => 'run',
'class' => 'PHPUnit\\Framework\\TestCase',
'object' => 'test',
'type' => '->',
'args' => [
0 => 'test',
],
],
[
'file' => 'Standard input code',
'line' => 111,
'function' => '__phpunit_run_isolated_test',
'args' => [
0 => 'test',
],
],
];
return [
// Test that if the driver namespace is in the stack trace, the first
// non-database entry is returned.
'contrib driver namespace' => [
'Drupal\\Driver\\Database\\dbal',
$stack,
[
'class' => 'Drupal\\KernelTests\\Core\\Database\\LoggingTest',
'function' => 'testEnableLogging',
'file' => '/var/www/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php',
'line' => 23,
'type' => '->',
'args' => [
0 => 'test',
],
],
],
// Extreme case, should not happen at normal runtime - if the driver
// namespace is not in the stack trace, the first entry to a method
// in core database namespace is returned.
'missing driver namespace' => [
'Drupal\\Driver\\Database\\fake',
$stack,
[
'class' => 'Drupal\\Driver\\Database\\dbal\\Statement',
'function' => 'execute',
'file' => '/var/www/libraries/test/lib/Statement.php',
'line' => 264,
'type' => '->',
'args' => [
0 => 'test',
],
],
],
];
}
}

View File

@ -222,19 +222,4 @@ class MergeTest extends DatabaseTestBase {
$this->assertEquals('2', $person->id);
}
/**
* Tests deprecation of Merge::key() with array $field argument.
*
* @group legacy
*/
public function testDeprecatedKeyArrayArgument(): void {
$this->expectDeprecation('Passing an array to the $field argument of Drupal\Core\Database\Query\Merge::key() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. See https://www.drupal.org/node/2205327');
$this->connection->merge('select')
->key(['id' => 2])
->execute();
$person = $this->connection->query('SELECT * FROM {select} WHERE [id] = :id', [':id' => 2])->fetch();
$this->assertEquals('', $person->update);
$this->assertEquals('2', $person->id);
}
}

View File

@ -1,57 +0,0 @@
<?php
namespace Drupal\KernelTests\Core\Database;
/**
* Tests the sequences API.
*
* @group Database
* @group legacy
*/
class NextIdTest extends DatabaseTestBase {
/**
* The modules to enable.
*
* @var array
*/
protected static $modules = ['database_test', 'system'];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$table_specification = [
'description' => 'Stores IDs.',
'fields' => [
'value' => [
'description' => 'The value of the sequence.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
],
'primary key' => ['value'],
];
$this->connection->schema()->createTable('sequences', $table_specification);
}
/**
* Tests that the sequences API works.
*/
public function testDbNextId() {
$this->expectDeprecation('Drupal\Core\Database\Connection::nextId() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Modules should use instead the keyvalue storage for the last used id. See https://www.drupal.org/node/3349345');
$first = $this->connection->nextId();
$second = $this->connection->nextId();
// We can test for exact increase in here because we know there is no
// other process operating on these tables -- normally we could only
// expect $second > $first.
$this->assertEquals($first + 1, $second, 'The second call from a sequence provides a number increased by one.');
$result = $this->connection->nextId(1000);
$this->assertEquals(1001, $result, 'Sequence provides a larger number than the existing ID.');
}
}

View File

@ -2,12 +2,8 @@
namespace Drupal\KernelTests\Core\Database;
use Drupal\Core\Database\Database;
// cSpell:ignore aquery aprepare
/**
* Tests Drupal's extended prepared statement syntax..
* Tests Drupal's extended prepared statement syntax.
*
* @coversDefaultClass \Drupal\Core\Database\Connection
* @group Database
@ -165,22 +161,4 @@ class QueryTest extends DatabaseTestBase {
$this->assertEquals('Update value 1', $result->update);
}
/**
* Tests deprecation of the 'return' query option.
*
* @covers ::query
* @covers ::prepareStatement
*
* @group legacy
*/
public function testReturnOptionDeprecation() {
$this->expectDeprecation('Passing "return" option to %Aquery() 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');
$this->expectDeprecation('Passing "return" option to %AprepareStatement() 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');
$this->assertIsInt((int) $this->connection->query('INSERT INTO {test} ([name], [age], [job]) VALUES (:name, :age, :job)', [
':name' => 'Magoo',
':age' => 56,
':job' => 'Driver',
], ['return' => Database::RETURN_INSERT_ID]));
}
}

View File

@ -627,18 +627,4 @@ class SelectTest extends DatabaseTestBase {
->execute();
}
/**
* Tests thrown exception for non array operator conditions with array value.
*
* @dataProvider providerNonArrayOperatorWithArrayValueCondition
* @group legacy
*/
public function testNonArrayOperatorWithArrayValueConditionDeprecated($operator, $operator_in_exception_message) {
$this->expectDeprecation('Calling Drupal\Core\Database\Query\Condition::condition() without an array compatible operator is deprecated in drupal:10.1.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3350985');
$this->connection->select('test', 't')
->fields('t')
->condition('age', [26], $operator)
->execute();
}
}

View File

@ -2,6 +2,7 @@
namespace Drupal\KernelTests\Core\Database;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Database\StatementInterface;
/**
@ -168,8 +169,8 @@ class StatementTest extends DatabaseTestBase {
}
// Trying to iterate through the same statement again should fail.
$this->expectError();
$this->expectErrorMessage('Attempted rewinding a StatementInterface object when fetching has already started. Refactor your code to avoid rewinding statement objects.');
$this->expectException(DatabaseExceptionWrapper::class);
$this->expectExceptionMessage('Attempted rewinding a StatementInterface object when fetching has already started. Refactor your code to avoid rewinding statement objects.');
foreach ($statement as $row) {
$this->assertNotNull($row);
}
@ -204,8 +205,8 @@ class StatementTest extends DatabaseTestBase {
$rowCount = iterator_count($statement);
$this->assertSame(4, $rowCount);
$this->expectError();
$this->expectErrorMessage('Attempted rewinding a StatementInterface object when fetching has already started. Refactor your code to avoid rewinding statement objects.');
$this->expectException(DatabaseExceptionWrapper::class);
$this->expectExceptionMessage('Attempted rewinding a StatementInterface object when fetching has already started. Refactor your code to avoid rewinding statement objects.');
$rowCount = iterator_count($statement);
}
@ -242,8 +243,8 @@ class StatementTest extends DatabaseTestBase {
// Restart iterating through the same statement. The foreach loop will try
// rewinding the statement which should fail, and the counter should not be
// increased.
$this->expectError();
$this->expectErrorMessage('Attempted rewinding a StatementInterface object when fetching has already started. Refactor your code to avoid rewinding statement objects.');
$this->expectException(DatabaseExceptionWrapper::class);
$this->expectExceptionMessage('Attempted rewinding a StatementInterface object when fetching has already started. Refactor your code to avoid rewinding statement objects.');
foreach ($statement as $row) {
// No-op.
}

View File

@ -6,7 +6,6 @@ namespace Drupal\Tests\Core\Database;
use Composer\Autoload\ClassLoader;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\StatementPrefetch;
use Drupal\Core\Database\StatementPrefetchIterator;
use Drupal\Tests\Core\Database\Stub\StubConnection;
use Drupal\Tests\Core\Database\Stub\StubPDO;
@ -26,7 +25,7 @@ class ConnectionTest extends UnitTestCase {
* @return array
* Array of arrays with the following elements:
* - Arguments to pass to Connection::setPrefix().
* - Expected result from Connection::tablePrefix().
* - Expected result from Connection::getPrefix().
*/
public static function providerPrefixRoundTrip() {
return [
@ -47,7 +46,7 @@ class ConnectionTest extends UnitTestCase {
}
/**
* Exercise setPrefix() and tablePrefix().
* Exercise setPrefix() and getPrefix().
*
* @dataProvider providerPrefixRoundTrip
*/
@ -340,7 +339,7 @@ class ConnectionTest extends UnitTestCase {
'Truncate',
'Schema',
'Condition',
'Transaction' => $this->expectDeprecation('Calling Drupal\\Core\\Database\\Connection::getDriverClass() for \'' . $class . '\' is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use standard autoloading in the methods that return database operations. See https://www.drupal.org/node/3217534'),
'Transaction' => $this->expectExceptionMessage('Calling Drupal\\Core\\Database\\Connection::getDriverClass() for \'' . $class . '\' is not supported. Use standard autoloading in the methods that return database operations. See https://www.drupal.org/node/3217534'),
default => NULL,
};
$this->assertEquals($expected, $connection->getDriverClass($class));
@ -883,32 +882,6 @@ class ConnectionTest extends UnitTestCase {
];
}
/**
* Tests deprecation of the StatementWrapper class.
*
* @group legacy
*/
public function testStatementWrapperDeprecation() {
$this->expectDeprecation('\\Drupal\\Core\\Database\\StatementWrapper is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use \\Drupal\\Core\\Database\\StatementWrapperIterator instead. See https://www.drupal.org/node/3265938');
$mock_pdo = $this->createMock(StubPDO::class);
$connection = new StubConnection($mock_pdo, []);
$this->expectError();
$connection->prepareStatement('boing', []);
}
/**
* Tests deprecation of the StatementPrefetch class.
*
* @group legacy
*/
public function testStatementPrefetchDeprecation() {
$this->expectDeprecation('\\Drupal\\Core\\Database\\StatementPrefetch is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use \Drupal\Core\Database\StatementPrefetchIterator instead. See https://www.drupal.org/node/3265938');
$mockPdo = $this->createMock(StubPDO::class);
$mockConnection = new StubConnection($mockPdo, []);
$statement = new StatementPrefetch($mockPdo, $mockConnection, '');
$this->assertInstanceOf(StatementPrefetch::class, $statement);
}
/**
* Provides data for testSupportedFetchModes.
*
@ -942,14 +915,14 @@ class ConnectionTest extends UnitTestCase {
}
/**
* Provides data for testDeprecatedFetchModes.
* Provides data for testUnsupportedFetchModes.
*
* @return array
* An associative array of simple arrays, each having the following
* elements:
* - a PDO fetch mode.
*/
public static function providerDeprecatedFetchModes(): array {
public static function providerUnsupportedFetchModes(): array {
return [
'FETCH_DEFAULT' => [\PDO::FETCH_DEFAULT],
'FETCH_LAZY' => [\PDO::FETCH_LAZY],
@ -964,17 +937,13 @@ class ConnectionTest extends UnitTestCase {
}
/**
* Tests deprecated fetch modes.
* Tests unsupported fetch modes.
*
* @todo in drupal:11.0.0, do not remove this test but convert it to expect
* exceptions instead of deprecations.
*
* @dataProvider providerDeprecatedFetchModes
*
* @group legacy
* @dataProvider providerUnsupportedFetchModes
*/
public function testDeprecatedFetchModes(int $mode): void {
$this->expectDeprecation('Fetch mode %A is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use supported modes only. See https://www.drupal.org/node/3377999');
public function testUnsupportedFetchModes(int $mode): void {
$this->expectException(\AssertionError::class);
$this->expectExceptionMessageMatches("/^Fetch mode FETCH_.* is not supported\\. Use supported modes only/");
$mockPdo = $this->createMock(StubPDO::class);
$mockConnection = new StubConnection($mockPdo, []);
$statement = new StatementPrefetchIterator($mockPdo, $mockConnection, '');

View File

@ -1,151 +0,0 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\Core\Database;
use Composer\Autoload\ClassLoader;
use Drupal\Core\Cache\NullBackend;
use Drupal\Core\Database\Database;
use Drupal\Core\Extension\DatabaseDriverList;
use Drupal\Core\Extension\Exception\UnknownExtensionException;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* @coversDefaultClass \Drupal\Core\Database\Database
*
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*
* @group Database
*/
class DatabaseTest extends UnitTestCase {
/**
* A classloader to enable testing of contrib drivers.
*
* @var \Composer\Autoload\ClassLoader
*/
protected $additionalClassloader;
/**
* Path to DRUPAL_ROOT.
*
* @var string
*/
protected $root;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->additionalClassloader = new ClassLoader();
$this->additionalClassloader->register();
// Mock the container so we don't need to mock drupal_valid_test_ua().
// @see \Drupal\Core\Extension\ExtensionDiscovery::scan()
$this->root = dirname(__DIR__, 6);
$databaseDriverList = new DatabaseDriverList($this->root, 'database_driver', new NullBackend('database_driver'));
$container = $this->createMock(ContainerInterface::class);
$container->expects($this->any())
->method('has')
->willReturnMap([
['kernel', TRUE],
['extension.list.database_driver', TRUE],
]);
$container->expects($this->any())
->method('get')
->with('extension.list.database_driver')
->willReturn($databaseDriverList);
$container->expects($this->any())
->method('getParameter')
->with('site.path')
->willReturn('');
\Drupal::setContainer($container);
}
/**
* @covers ::findDriverAutoloadDirectory
* @dataProvider providerFindDriverAutoloadDirectory
* @group legacy
*/
public function testFindDriverAutoloadDirectory($expected, $namespace, $include_test_drivers) {
$this->expectDeprecation('Drupal\Core\Database\Database::findDriverAutoloadDirectory() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use DatabaseDriverList::getList() instead. See https://www.drupal.org/node/3258175');
// The only module that provides a driver in core is a test module.
if (!$expected) {
$this->expectException(UnknownExtensionException::class);
Database::findDriverAutoloadDirectory($namespace, $this->root, $include_test_drivers);
}
else {
$this->assertSame($expected, Database::findDriverAutoloadDirectory($namespace, $this->root, $include_test_drivers));
}
}
/**
* Data provider for ::testFindDriverAutoloadDirectory().
*
* @return array
*/
public static function providerFindDriverAutoloadDirectory() {
return [
'core mysql' => ['core/modules/mysql/src/Driver/Database/mysql/', 'Drupal\mysql\Driver\Database\mysql', FALSE],
'D8 custom fake' => [FALSE, 'Drupal\Driver\Database\CoreFake', TRUE],
'module mysql' => ['core/modules/system/tests/modules/driver_test/src/Driver/Database/DrivertestMysql/', 'Drupal\driver_test\Driver\Database\DrivertestMysql', TRUE],
];
}
/**
* @covers ::findDriverAutoloadDirectory
* @dataProvider providerFindDriverAutoloadDirectoryException
* @group legacy
*/
public function testFindDriverAutoloadDirectoryException($expected_message, $namespace, $include_tests) {
$this->expectDeprecation('Drupal\Core\Database\Database::findDriverAutoloadDirectory() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use DatabaseDriverList::getList() instead. See https://www.drupal.org/node/3258175');
$this->expectException(UnknownExtensionException::class);
$this->expectExceptionMessage($expected_message);
Database::findDriverAutoloadDirectory($namespace, $this->root, $include_tests);
}
/**
* Data provider for ::testFindDriverAutoloadDirectoryException().
*
* @return array
*/
public static function providerFindDriverAutoloadDirectoryException() {
return [
'test module but tests not included' => [
"The database_driver Drupal\driver_test\Driver\Database\DrivertestMysql does not exist.",
'Drupal\driver_test\Driver\Database\DrivertestMysql',
FALSE,
],
'non-existent driver in test module' => [
"The database_driver Drupal\driver_test\Driver\Database\sqlite does not exist.",
'Drupal\driver_test\Driver\Database\sqlite',
TRUE,
],
'non-existent module' => [
"The database_driver Drupal\does_not_exist\Driver\Database\mysql does not exist.",
'Drupal\does_not_exist\Driver\Database\mysql',
TRUE,
],
];
}
/**
* Adds a database driver that uses the D8's Drupal\Driver\Database namespace.
*/
protected function addD8CustomDrivers() {
$this->additionalClassloader->addPsr4("Drupal\\Driver\\Database\\CoreFake\\", __DIR__ . "/../../../../../tests/fixtures/database_drivers/custom/CoreFake");
}
/**
* Adds database drivers that are provided by modules.
*/
protected function addModuleDrivers() {
$this->additionalClassloader->addPsr4("Drupal\\driver_test\\Driver\\Database\\DrivertestMysql\\", __DIR__ . "/../../../../../modules/system/tests/modules/driver_test/src/Driver/Database/DrivertestMysql");
$this->additionalClassloader->addPsr4("Drupal\\CoreFake\\Driver\\Database\\CoreFake\\", __DIR__ . "/../../../../../tests/fixtures/database_drivers/module/core_fake/src/Driver/Database/CoreFake");
}
}

View File

@ -1,80 +0,0 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\Core\Database;
use Composer\Autoload\ClassLoader;
use Drupal\mysql\Driver\Database\mysql\Install\Tasks as MysqlInstallTasks;
use Drupal\Driver\Database\fake\Install\Tasks as FakeInstallTasks;
use Drupal\Driver\Database\CoreFake\Install\Tasks as CustomCoreFakeInstallTasks;
use Drupal\driver_test\Driver\Database\DrivertestMysql\Install\Tasks as DriverTestMysqlInstallTasks;
use Drupal\Tests\UnitTestCase;
/**
* Tests the db_installer_object() function that is used during installation.
*
* These tests run in isolation to prevent the autoloader additions from
* affecting other tests.
*
* @covers ::db_installer_object
*
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*
* @group Database
* @group legacy
*/
class InstallerObjectTest extends UnitTestCase {
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
require_once __DIR__ . '/../../../../../includes/install.inc';
$additional_class_loader = new ClassLoader();
$additional_class_loader->addPsr4("Drupal\\Driver\\Database\\fake\\", __DIR__ . "/../../../../../tests/fixtures/database_drivers/custom/fake");
$additional_class_loader->addPsr4("Drupal\\Core\\Database\\Driver\\CoreFake\\", __DIR__ . "/../../../../../tests/fixtures/database_drivers/core/CoreFake");
$additional_class_loader->addPsr4("Drupal\\Driver\\Database\\CoreFake\\", __DIR__ . "/../../../../../tests/fixtures/database_drivers/custom/CoreFake");
$additional_class_loader->addPsr4("Drupal\\driver_test\\Driver\\Database\\DrivertestMysql\\", __DIR__ . "/../../../../../../modules/system/tests/modules/driver_test/src/Driver/Database/DrivertestMysql");
$additional_class_loader->register(TRUE);
}
/**
* @dataProvider providerDbInstallerObject
*/
public function testDbInstallerObject($driver, $namespace, $expected_class_name) {
$this->expectDeprecation('db_installer_object() is deprecated in drupal:10.0.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3256641');
$object = db_installer_object($driver, $namespace);
$this->assertEquals(get_class($object), $expected_class_name);
}
/**
* Data provider for testDbUrlToConnectionConversion().
*
* @return array
* Array of arrays with the following elements:
* - driver: The driver name.
* - namespace: The namespace providing the driver.
* - class: The fully qualified class name of the expected install task.
*/
public static function providerDbInstallerObject() {
return [
// A driver only in the core namespace.
['mysql', "Drupal\\mysql\\Driver\\Database\\mysql", MysqlInstallTasks::class],
// A driver only in the custom namespace.
// @phpstan-ignore-next-line
['fake', "Drupal\\Driver\\Database\\fake", FakeInstallTasks::class],
// A driver in both namespaces. The custom one takes precedence.
// @phpstan-ignore-next-line
['CoreFake', "Drupal\\Driver\\Database\\CoreFake", CustomCoreFakeInstallTasks::class],
// A driver from a module that has a different name as the driver.
['DrivertestMysql', "Drupal\\driver_test\\Driver\\Database\\DrivertestMysql", DriverTestMysqlInstallTasks::class],
];
}
}

View File

@ -1,64 +0,0 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\Core\Database;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Log;
use Drupal\Tests\Core\Database\Stub\StubConnection;
use Drupal\Tests\Core\Database\Stub\StubPDO;
use Drupal\Tests\UnitTestCase;
/**
* Tests the Log class.
*
* @group Database
* @group legacy
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
* @coversDefaultClass \Drupal\Core\Database\Log
*/
class LogTest extends UnitTestCase {
/**
* Tests that a log called by a custom database driver returns proper caller.
*
* @covers ::findCaller
*/
public function testContribDriverLog() {
Database::addConnectionInfo('default', 'default', [
'driver' => 'test',
'namespace' => 'Drupal\Tests\Core\Database\Stub',
]);
$this->expectDeprecation('Drupal\Core\Database\Log::findCaller() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use Connection::findCallerFromDebugBacktrace(). See https://www.drupal.org/node/3328053');
$this->expectDeprecation('Drupal\Core\Database\Log::getDebugBacktrace() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3328053');
$this->expectDeprecation('Drupal\Core\Database\Log::removeDatabaseEntries() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use Connection::removeDatabaseEntriesFromDebugBacktrace(). See https://www.drupal.org/node/3328053');
$pdo = $this->prophesize(StubPDO::class)->reveal();
$result = (new StubConnection($pdo, []))->testLogCaller();
$this->assertSame([
'file' => __FILE__,
'line' => 39,
'function' => 'testContribDriverLog',
'class' => 'Drupal\Tests\Core\Database\LogTest',
'type' => '->',
'args' => [],
], $result);
// Test calling the database log from outside of database code.
$this->expectDeprecation('Drupal\Core\Database\Log::findCaller() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use Connection::findCallerFromDebugBacktrace(). See https://www.drupal.org/node/3328053');
$this->expectDeprecation('Drupal\Core\Database\Log::getDebugBacktrace() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3328053');
$this->expectDeprecation('Drupal\Core\Database\Log::removeDatabaseEntries() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use Connection::removeDatabaseEntriesFromDebugBacktrace(). See https://www.drupal.org/node/3328053');
$result = (new Log())->findCaller();
$this->assertSame([
'file' => __FILE__,
'line' => 53,
'function' => 'testContribDriverLog',
'class' => 'Drupal\Tests\Core\Database\LogTest',
'type' => '->',
'args' => [],
], $result);
}
}

View File

@ -7,14 +7,7 @@ namespace Drupal\Tests\Core\Database\Stub;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\ExceptionHandler;
use Drupal\Core\Database\Log;
use Drupal\Core\Database\Query\Delete;
use Drupal\Core\Database\Query\Insert;
use Drupal\Core\Database\Query\Merge;
use Drupal\Core\Database\Query\Select;
use Drupal\Core\Database\Query\Truncate;
use Drupal\Core\Database\Query\Update;
use Drupal\Core\Database\StatementWrapper;
use Drupal\Core\Database\Transaction;
use Drupal\Core\Database\StatementWrapperIterator;
use Drupal\Tests\Core\Database\Stub\Driver\Schema;
/**
@ -27,7 +20,7 @@ class StubConnection extends Connection {
/**
* {@inheritdoc}
*/
protected $statementWrapperClass = StatementWrapper::class;
protected $statementWrapperClass = StatementWrapperIterator::class;
/**
* Public property so we can test driver loading mechanism.
@ -92,14 +85,6 @@ class StubConnection extends Connection {
return NULL;
}
/**
* {@inheritdoc}
*/
public function nextId($existing_id = 0) {
@trigger_error('Drupal\Core\Database\Connection::nextId() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Modules should use instead the keyvalue storage for the last used id. See https://www.drupal.org/node/3349345', E_USER_DEPRECATED);
return 0;
}
/**
* Helper method to test database classes are not included in backtraces.
*
@ -117,27 +102,6 @@ class StubConnection extends Connection {
return new ExceptionHandler();
}
/**
* {@inheritdoc}
*/
public function select($table, $alias = NULL, array $options = []) {
return new Select($this, $table, $alias, $options);
}
/**
* {@inheritdoc}
*/
public function insert($table, array $options = []) {
return new Insert($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function merge($table, array $options = []) {
return new Merge($this, $table, $options);
}
/**
* {@inheritdoc}
*/
@ -145,27 +109,6 @@ class StubConnection extends Connection {
return new StubUpsert($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function update($table, array $options = []) {
return new Update($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function delete($table, array $options = []) {
return new Delete($this, $table, $options);
}
/**
* {@inheritdoc}
*/
public function truncate($table, array $options = []) {
return new Truncate($this, $table, $options);
}
/**
* {@inheritdoc}
*/
@ -183,11 +126,4 @@ class StubConnection extends Connection {
return new StubCondition($conjunction);
}
/**
* {@inheritdoc}
*/
public function startTransaction($name = '') {
return new Transaction($this, $name);
}
}