Commit 2989dd00 authored by catch's avatar catch
Browse files

Issue #3112476 by alexpott, Neslee Canil Pinto, mondrake, daffie, salah1,...

Issue #3112476 by alexpott, Neslee Canil Pinto, mondrake, daffie, salah1, neelam_wadhwani: Always set $info['namespace'] on database connection info
parent 4994ca42
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -214,6 +214,13 @@ public function __construct(\PDO $connection, array $connection_options) {
      unset($connection_options['transactions']);
    }

    // Work out the database driver namespace if none is provided. This normally
    // written to setting.php by installer or set by
    // \Drupal\Core\Database\Database::parseConnectionInfo().
    if (empty($connection_options['namespace'])) {
      $connection_options['namespace'] = (new \ReflectionObject($this))->getNamespaceName();
    }

    // Initialize and prepare the connection prefix.
    $this->setPrefix(isset($connection_options['prefix']) ? $connection_options['prefix'] : '');

@@ -863,10 +870,6 @@ protected function expandArguments(&$query, &$args) {
   */
  public function getDriverClass($class) {
    if (empty($this->driverClasses[$class])) {
      if (empty($this->connectionOptions['namespace'])) {
        // Fallback for Drupal 7 settings.php and the test runner script.
        $this->connectionOptions['namespace'] = (new \ReflectionObject($this))->getNamespaceName();
      }
      $driver_class = $this->connectionOptions['namespace'] . '\\' . $class;
      $this->driverClasses[$class] = class_exists($driver_class) ? $driver_class : $class;
      if ($this->driverClasses[$class] === 'Condition') {
+15 −3
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ final public static function parseConnectionInfo(array $info) {
    if (empty($info['driver'])) {
      $info = $info[mt_rand(0, count($info) - 1)];
    }

    // Parse the prefix information.
    if (!isset($info['prefix'])) {
      // Default to an empty prefix.
@@ -227,6 +228,12 @@ final public static function parseConnectionInfo(array $info) {
        'default' => $info['prefix'],
      ];
    }

    // Fallback for Drupal 7 settings.php if namespace is not provided.
    if (empty($info['namespace'])) {
      $info['namespace'] = 'Drupal\\Core\\Database\\Driver\\' . $info['driver'];
    }

    return $info;
  }

@@ -368,8 +375,7 @@ final protected static function openConnection($key, $target) {
      throw new DriverNotSpecifiedException('Driver not specified for this database connection: ' . $key);
    }

    $namespace = static::getDatabaseDriverNamespace(self::$databaseInfo[$key][$target]);
    $driver_class = $namespace . '\\Connection';
    $driver_class = self::$databaseInfo[$key][$target]['namespace'] . '\\Connection';

    $pdo_connection = $driver_class::open(self::$databaseInfo[$key][$target]);
    $new_connection = new $driver_class($pdo_connection, self::$databaseInfo[$key][$target]);
@@ -605,7 +611,7 @@ public static function getConnectionInfoAsUrl($key = 'default') {
    if (empty($db_info) || empty($db_info['default'])) {
      throw new \RuntimeException("Database connection $key not defined or missing the 'default' settings");
    }
    $namespace = static::getDatabaseDriverNamespace($db_info['default']);
    $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
@@ -628,8 +634,14 @@ public static function getConnectionInfoAsUrl($key = 'default') {
   *
   * @return string
   *   The PHP namespace of the driver's database.
   *
   * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. There is no
   *   replacement as $connection_info['namespace'] is always set.
   *
   * @see https://www.drupal.org/node/3127769
   */
  protected static function getDatabaseDriverNamespace(array $connection_info) {
    @trigger_error(__METHOD__ . " is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. There is no replacement as \$connection_info['namespace'] is always set. See https://www.drupal.org/node/3127769.", E_USER_DEPRECATED);
    if (isset($connection_info['namespace'])) {
      return $connection_info['namespace'];
    }
+3 −22
Original line number Diff line number Diff line
@@ -38,13 +38,6 @@ class Log {
   */
  protected $connectionKey = 'default';

  /**
   * The PHP namespace of the database driver that this object is logging.
   *
   * @var string
   */
  protected $driverNamespace;

  /**
   * Constructor.
   *
@@ -152,6 +145,8 @@ public function log(StatementInterface $statement, $args, $time) {
  public function findCaller() {
    $stack = $this->getDebugBacktrace();

    $driver_namespace = Database::getConnectionInfo($this->connectionKey)['default']['namespace'];

    // Starting from the very first entry processed during the request, find
    // the first function call that can be identified as a call to a
    // method/function in the database layer.
@@ -160,7 +155,7 @@ public function findCaller() {
      // it a default empty string value in that case.
      $class = $stack[$n]['class'] ?? '';

      if (strpos($class, __NAMESPACE__, 0) === 0 || strpos($class, $this->getDriverNamespace(), 0) === 0) {
      if (strpos($class, __NAMESPACE__, 0) === 0 || strpos($class, $driver_namespace, 0) === 0) {
        break;
      }
    }
@@ -181,20 +176,6 @@ public function findCaller() {
    }
  }

  /**
   * Gets the namespace of the database driver.
   *
   * @return string|null
   *   Namespace of the database driver, or NULL if the connection is
   *   missing.
   */
  protected function getDriverNamespace() {
    if (!isset($this->driverNamespace)) {
      $this->driverNamespace = (new \ReflectionObject(Database::getConnection('default', $this->connectionKey)))->getNamespaceName();
    }
    return $this->driverNamespace;
  }

  /**
   * Gets the debug backtrace.
   *
+3 −2
Original line number Diff line number Diff line
@@ -46,8 +46,9 @@ public function resetLoggedStatements() {
   * {@inheritdoc}
   */
  public function getDriverClass($class) {
    // Override because the base class uses reflection to determine namespace
    // based on object, which would break.
    // Override because the database driver copies in the
    // database_statement_monitoring_test module don't contain all the necessary
    // classes.
    $namespace = (new \ReflectionClass(get_parent_class($this)))->getNamespaceName();
    $driver_class = $namespace . '\\' . $class;
    if (class_exists($driver_class)) {
+3 −4
Original line number Diff line number Diff line
@@ -155,14 +155,13 @@ public function testGetLoggingWrongKey() {
  public function testContribDriverLog($driver_namespace, $stack, array $expected_entry) {
    $mock_builder = $this->getMockBuilder(Log::class);
    $log = $mock_builder
      ->setMethods(['getDriverNamespace', 'getDebugBacktrace'])
      ->setMethods(['getDebugBacktrace'])
      ->setConstructorArgs(['test'])
      ->getMock();
    $log->expects($this->any())
      ->method('getDriverNamespace')
      ->will($this->returnValue($driver_namespace));
    $log->expects($this->once())
      ->method('getDebugBacktrace')
      ->will($this->returnValue($stack));
    Database::addConnectionInfo('test', 'default', ['driver' => 'mysql', 'namespace' => $driver_namespace]);

    $result = $log->findCaller($stack);
    $this->assertEquals($expected_entry, $result);
Loading