Problem/Motivation

getDriverCalls calls driver(). There's no need for this. Also, it hardwires Core. There's no need for that either.

Proposed resolution

Grab the namespace from the namespace of the connection class itself. This does not have a lot of performance implication since it only happens once per class per run-tests.sh invocation and never in a normal Drupal 8 install.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

+++ b/core/lib/Drupal/Core/Database/Connection.php
@@ -659,13 +659,12 @@ protected function expandArguments(&$query, &$args) {
       else {
         // Fallback for Drupal 7 settings.php.
-        $driver_class = "Drupal\\Core\\Database\\Driver\\{$driver}\\{$class}";
+        $driver_class = 'Drupal\Core\Database\Driver\\' . $this->driver() . '\\' . $class;
       }

Why do we support the Drupal 7 way of doing it, in the first place? Can't we drop that now?

chx’s picture

You can not if you want to support test runs without settings.php . That's where namespace is coming from. Where else would it come from?

dawehner’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Quickfix

Alright, so we need it to run tests, maybe we could document it at some point

chx’s picture

Title: Fake based drivers break due to superflous driver() call » Connection::getDriverClass doesn't support non-core drivers
Issue summary: View changes
Status: Reviewed & tested by the community » Needs review
Issue tags: -Quickfix
FileSize
1.12 KB

Actually... Connection is abstract and so the driver must extend and so we have the namespace at hand. I adjusted the comment as well.

Status: Needs review » Needs work

The last submitted patch, 4: 2462653_4.patch, failed testing.

dawehner’s picture

Assigned: Unassigned » Crell

Looks great for me. Thank you for adding a bit more explanation.

I think we should get some feedback from crell.

chx’s picture

Status: Needs work » Needs review
FileSize
1.12 KB

Yes, that was my idea too and I pinged him earlier today on IRC already although the issue definitely didn't bloom into this nice reflection solution yet.

Status: Needs review » Needs work

The last submitted patch, 7: 2462653_6.patch, failed testing.

chx’s picture

Status: Needs work » Needs review
FileSize
1.12 KB

This is why I shouldn't be patching without phpstorm.

Status: Needs review » Needs work

The last submitted patch, 9: 2462653_8.patch, failed testing.

Crell’s picture

Title: Connection::getDriverClass doesn't support non-core drivers » Connection::getDriverClass doesn't support non-core Drupal 7 drivers

I *think* this is what we're talking about; the new code for D8 should handle any autoloadable class. It's the D7 code path that doesn't work for non-core libs, which I think it only used for upgrades, no? I don't know how testbot gets into this...

chx’s picture

Title: Connection::getDriverClass doesn't support non-core Drupal 7 drivers » Connection::getDriverClass doesn't support non-core drivers
Status: Needs work » Needs review
FileSize
1.12 KB

> I don't know how testbot gets into this

If you run run-tests.sh --dburl then simpletest_script_setup_database creates a connection definition that doesn't (can not) contain the namespace so this codepath is hit. Check the bot fail above. It shows the code is hit.

Status: Needs review » Needs work

The last submitted patch, 12: 2462653_12.patch, failed testing.

chx’s picture

Status: Needs work » Needs review
FileSize
3.04 KB

Well, the connection test needs to change.

chx’s picture

And yes, this is rapidly heading to where driver() is not used at all but let's kill the last usage in the next patch. It'll look like this:

  public function extend($extender_name) {
    try {
      $override_class = $extender_name . '_' . $this->connection->driver();
      if (class_exists($override_class)) {
        $extender_name = $override_class;
      }
    }
    catch (\Exception $e) {
      // If the driver() method is not supported then there is no per driver
      // extender support.
    }
    return new $extender_name($this, $this->connection);
  }

Edit: the mongodb driver now has a driver name but Fake doesn't and that's right and Fake is in core.

Fabianx’s picture

So what is missing? Can this be RTBCed? It looks good to me ...

chx’s picture

Crell’s picture

Status: Needs review » Reviewed & tested by the community

With that follow up filed, this looks good.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Any reason why we don't avoid reflection and just do substr(get_called_class(), 0, strrpos(get_called_class(), "\\"))

+++ b/core/lib/Drupal/Core/Database/Connection.php
@@ -659,14 +659,14 @@ protected function expandArguments(&$query, &$args) {
       if (!empty($this->connectionOptions['namespace'])) {
-        $driver_class  = $this->connectionOptions['namespace'] . '\\' . $class;
+        $namespace  = $this->connectionOptions['namespace'];
       }
       else {
-        // Fallback for Drupal 7 settings.php.
-        $driver_class = "Drupal\\Core\\Database\\Driver\\{$driver}\\{$class}";
+        // Fallback for Drupal 7 settings.php and the test runner script.
+        $namespace = (new \ReflectionObject($this))->getNamespaceName();

Can we set the $this->connectionOptions['namespace'] so we don't have to do the reflection multiple times for different classes?

mgifford’s picture

Assigned: Crell » Unassigned

Unassigning stale issue. Hopefully someone else will pursue this.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

daffie’s picture

I have changed the patch so that the reflection is not run multiple times.

As for:

Any reason why we don't avoid reflection and just do substr(get_called_class(), 0, strrpos(get_called_class(), "\\"))

I have no idea.

daffie’s picture

Status: Needs work » Needs review

For the testbot

The last submitted patch, 22: 2462653-22-test-only-should-fail.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 22: 2462653-22.patch, failed testing.

chx’s picture

Any reason why we don't avoid reflection and just do

substr(get_called_class(), 0, strrpos(get_called_class(), "\\"))

Because the following:

$namespace = (new \ReflectionObject($this))->getNamespaceName();

is way easier to understand...? Self documenting and all that.

daffie’s picture

With the patch from comment #22, I have tried to make the calling of the ReflextionObject as little as possible by saving the namespace to $this->connectionOptions['namespace']. The problem is that the test ConnectionTest::testConnectionOptions() then fails. In that test a second database connection is made. The connection info from both database connections are tested to see if they are identical. If I save the namespace value to $this->connectionOptions['namespace'] they are not identical. So the question of @alexpott:

Can we set the $this->connectionOptions['namespace'] so we don't have to do the reflection multiple times for different classes?

has to be answered with no.
The first question from @alexpott has been answered by @chx in the previous comment.

In comment #18 is this issue set to RTBC by @Crell. So back to RTBC for the patch from comment #14. That patch still applies.

neclimdul’s picture

Status: Reviewed & tested by the community » Needs work

testbot sadly disagrees with you :(

neclimdul’s picture

FileSize
2.31 KB

My interdiff tools says this is the interdiff between #14 and #22. Its possible and likely the missing file is causing your failures.

daffie’s picture

Status: Needs work » Reviewed & tested by the community

@neclimdul: The patch from comment #14 made by @chx is the patch that is RTBC for @Crell. Not my patch from comment #22. In that patch have I tried to fix the remarks made by @alexpott. Those remarks are not fixable so I have made the patch from comment #14 RTBC again. If the patch from comment #14 made by chx is not RTBC for you, then please change the status of this issue.

daffie’s picture

I made a mistake in my patch in comment #22 by not adding the the database stub. I have tried locally to pass the ConnectionTest with the database stub and I failed. See comment #27 for the explanation why.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
2.37 KB
3.01 KB

I think we can do less reflection if we do something like the patch attached.

tstoeckler’s picture

Status: Needs review » Needs work

The last submitted patch, 32: 2462653-32.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
861 bytes
3.85 KB
daffie’s picture

Status: Needs review » Reviewed & tested by the community

I am not exactly sure why it passes the ConnectionTest but it does.

It all looks good to me.
It fixed the problem from the issue summary.
The 2 problems from alexpott in comment #19 are addressed. With one being explained by chx in comment #26.

For me it is RTBC.

neclimdul’s picture

Neat! Thanks guys!

edit: PS: Sorry about my confusion. Thanks for addressing it and improving everything though!

  • catch committed b7a2901 on 8.2.x
    Issue #2462653 by chx, alexpott, daffie, neclimdul: Connection::...

  • catch committed 011d2f9 on 8.1.x
    Issue #2462653 by chx, alexpott, daffie, neclimdul: Connection::...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.2.x and cherry-picked to 8.1.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.