Problem/Motivation

The views module allows a view to be to an external database. And the external database does not have to be of the same type as the default database. For instance the default database is MySQL and the view get its data from a Microsoft SQL Server (a.k.a. the external database). The class Drupal\views\Plugin\views\query\Sql uses the correct database connection for the query. A number of views plugins that need a database connection, only use the default database connection. As long as the methods that they use from the database connection have the same implementation for all databases, then there is no problem. Unfortionally is this not always the case. The 2 databases from the example have a different implementations for conditions. See: #3130655: Deprecate creating an instance of the class Drupal\Core\Database\Query\Condition with the new keyword and #2031261: Make SQLite faster by combining multiple inserts and updates in a single query. Plugins therfor need to use the database connection from the class Drupal\views\Plugin\views\query\Sql. Plugins can only do that when there is a public method that will return the correct database connection.

Proposed resolution

Create a new public method Drupal\views\Plugin\views\query\Sql::getConnection() that will return the correct database connection for the view.

Remaining tasks

TBD

User interface changes

None

API changes

API addition with the new public method Drupal\views\Plugin\views\query\Sql::getConnection()

Data model changes

None

Release notes snippet

TBD

Comments

daffie created an issue. See original summary.

daffie’s picture

Status: Active » Needs review
StatusFileSize
new4.9 KB
andypost’s picture

StatusFileSize
new1.1 KB
new4.79 KB

Let's use more readable code as the method is new, also fix CS

daffie’s picture

@andypost: Thank you. Your patch makes the code more readable!

beakerboy’s picture

Status: Needs review » Reviewed & tested by the community

This new function fulfills the needs, and the tests provide suitable code coverage.

xjm’s picture

Status: Reviewed & tested by the community » Needs work

This seems like a fine refactoring and also a nice code cleanup at the same time. When I read the title I thought we should have a subsystem maintainer sign off on the change, but I'm a Views subsystem maintainer and this seems totally a safe change for me. Good test coverage, also. I have just a few nitpicks for us to address:

  1. +++ b/core/modules/views/src/Plugin/views/query/Sql.php
    @@ -1248,6 +1248,24 @@ protected function compileFields($query) {
    +   * Get the database connection to use for the view.
    

    Should be "Gets".

  2. +++ b/core/modules/views/tests/src/Kernel/Plugin/SqlQueryTest.php
    @@ -79,4 +80,49 @@ public function testExecuteMetadata() {
    +   * @covers \Drupal\views\Plugin\views\query\Sql::getConnection
    +   *
    +   * This cannot be made as a PHPUnit test, because the tested method uses the
    +   * method \Drupal\Core\Database\Database::getConnection() which is a 'final'
    +   * method and therefor cannot be mocked.
    

    This should have a one-line summary.

  3. +++ b/core/modules/views/tests/src/Kernel/Plugin/SqlQueryTest.php
    @@ -79,4 +80,49 @@ public function testExecuteMetadata() {
    +    // Cleanup the created database connections.
    

    "Clean up" (two words).

Thank you!

mrinalini9’s picture

Assigned: Unassigned » mrinalini9
mrinalini9’s picture

Assigned: mrinalini9 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new4.67 KB
new1.68 KB

Updated patch as per the changes suggested in #6, please review.

beakerboy’s picture

Status: Needs review » Reviewed & tested by the community

All recommendations for changes to comments have been made. No changes to code so back to RTBC.

xjm’s picture

Status: Reviewed & tested by the community » Needs work

Thanks for the quick fixes for my nitpicks. :) One point needs a little more work:

+++ b/core/modules/views/tests/src/Kernel/Plugin/SqlQueryTest.php
@@ -83,9 +83,7 @@
   /**
    * @covers \Drupal\views\Plugin\views\query\Sql::getConnection
    *
-   * This cannot be made as a PHPUnit test, because the tested method uses the
-   * method \Drupal\Core\Database\Database::getConnection() which is a 'final'
-   * method and therefor cannot be mocked.
+   * This cannot be made as a PHPUnit test as it uses the 'final' method.

This change is not quite right. :) The full paragraph here is necessary and useful.

What's missing is a one-line summary above the @covers that describes what the method does. This should be followed by the full detail of the existing paragraph, and then the @covers goes below that.

Thanks!

andypost’s picture

Status: Needs work » Needs review

@xjm For tests @covers should be enough https://www.drupal.org/node/1354#tests (there was policy accepted at least for phpunit tests)

@covers is self explanatory - means testing specific method

xjm’s picture

Status: Needs review » Needs work

I pointed out to @andypost that that bullet links a reference that only allows omitting a one-line summary for a class in lieu of just using @coversDefaultClass. There's nothing about @covers replacing the one-line summary for methods; in fact, it says:

Every test class MUST have a PHPDoc summary line. Only PHPUnit tests MAY skip the PHPDoc summary line if their PHPDoc specifies a @coversDefaultClass. See PHPUnit @coversDefaultClass annotation documentation

https://www.drupal.org/node/2116043#s-examples--3

Nothing about skipping it for @covers. Even if there were, though, this particular method is way longer than just a 1:1 test of a simple method and required a whole paragraph to explain, so I would still ask for a one-line summary here that's more human-readable.

Also NW still because #8 is definitely not right regardless; we shouldn't be deleting most of the useful paragraph. My review meant add a sentence at the top.

daffie’s picture

Status: Needs work » Needs review
StatusFileSize
new823 bytes
new4.88 KB

For #12: Fixed. I think that we have the information about which method is being tested double. The link that is given by @xjm in comment #12 is only about docblock for by the class definition and how it should work for methods is not available. Maybe we should fix this. There are a lot of test methods in core that only have an @covers annotation and to me that is more then enough.

andypost’s picture

Status: Needs review » Reviewed & tested by the community

As I got we should use @covers only for unittests which has @coversDefaultClass

So make sense to file follow-up and maybe policy to introduce sniff in coder

lendude’s picture

+++ b/core/modules/views/tests/src/Kernel/Plugin/SqlQueryTest.php
@@ -79,4 +80,51 @@ public function testExecuteMetadata() {
+   * This cannot be made as a PHPUnit test, because the tested method uses the

Nitpick. it is a PHPUnit test, just not a Unit test.....strictly speaking it should probably say something like 'This is a kernel test because....'

Great to see test coverage for this!

xjm’s picture

Status: Reviewed & tested by the community » Needs work

Oops, yep, let's fix #15. If it were just swapping one word I might fix it on commit, but rewrapping whole paragraphs on commit is error-prone. NW for that too. Thanks @Lendude!

lendude’s picture

Status: Needs work » Needs review
StatusFileSize
new852 bytes
new4.87 KB

So, that would be something like this

daffie’s picture

Status: Needs review » Reviewed & tested by the community

I was just about to fix the remark of comment #15.
The fix looks good.
Back to RTBC.
@lendude: Thanks.

  • xjm committed e57b4ac on 9.1.x
    Issue #3139353 by daffie, andypost, mrinalini9, Lendude, xjm: Add public...
xjm’s picture

Pushed to 9.1.x and published the CR. Thanks!

daffie’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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

taran2l’s picture

This issue continues work started in #3113403: Make Drupal\Core\Database\Query\Condition driver overridable and finished in #3130655: Deprecate creating an instance of the class Drupal\Core\Database\Query\Condition with the new keyword, however, it has not been committed to 8.9.x despite #3113403: Make Drupal\Core\Database\Query\Condition driver overridable has been, so again supporting a single codebase for D8 and D9 is not possible, but it can be with a little effort.

I can provide a backported patch for D8.9, anyone interested (i.e. will it be committed)?