Problem/Motivation
As noted in #3186934: Introduce an ExceptionHandler class in the database API, deprecate Connection::handleQueryException, the way query classes are loaded by Connection is preventing static code analysis, besides being 'a magic' in the sense that they're autoloaded by placing files that override the base classes in the same directory where the Connection class resides.
Proposed resolution
While waiting for #3217699: Convert select query extenders to backend-overrideable services, for now let's start changing most Database/Query classes to standard autoloading. This will reduce a lot boilerplate in contrib drivers.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#30 | 3217531-30-do-not-test-do-not-commit.patch | 16.44 KB | mondrake |
Issue fork drupal-3217531
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3217531-deprecate-connectiongetdriverclass-mechanism changes, plain diff MR !757
Comments
Comment #3
mondrakeA first patch. While overriding the Connection methods that call getDriverClass in the driver-specific classes with direct indication of the class to use is (relatively) straigthforward, the use of the method to replace query extenders with driver-specific classes is not. AFAICS this in more recent times was done with backend-overridable services; could that be applied here too?
Comment #4
andypostComment #5
andypostComment #6
mondrakeI have opened #3217699: Convert select query extenders to backend-overrideable services for #3. There's a PoC there, comments appreciated.
Comment #7
mondrake#3217699: Convert select query extenders to backend-overrideable services would help here, so postponing on that for the moment.
Comment #9
mondrakeRebased to 9.4 and rerolled
Comment #10
daffie CreditAttribution: daffie commented#3217699: Convert select query extenders to backend-overrideable services has landed.
Comment #11
mondrakeOn this
Comment #12
daffie CreditAttribution: daffie commentedUpdated the CR.
Comment #13
mondrakeI think we are hitting #3256642: Introduce database driver extensions and autoload database drivers' dependencies here, we are blocked on it
Comment #14
mondrakeComment #15
mondrakeAgh no #3256642: Introduce database driver extensions and autoload database drivers' dependencies is D10 only, need to figure out 9.4
Comment #16
mondrakeWith #3256642: Introduce database driver extensions and autoload database drivers' dependencies the D10 patch will be much simpler and cleanup a lot, so I am still keen on holding this (both 9.4 and 10) on that. But the MR towards 9.4 should pass now.
Comment #17
daffie CreditAttribution: daffie commentedAs we need #3256642: Introduce database driver extensions and autoload database drivers' dependencies before we can do the patch for D10, lets postpone this issue until the other lands.
The patch for 9.4 looks good.
Comment #18
mondrakeUnfortunately, #3217699: Convert select query extenders to backend-overrideable services was reverted and reopened so now this is postponed on 2 issues.
Comment #22
mondrakeMaybe we can still get on after #3256642: Introduce database driver extensions and autoload database drivers' dependencies commit leaving aside, alas, #3217699: Convert select query extenders to backend-overrideable services.
Comment #23
mondrakeLet's make this issue a bit less boastful. The MR here helps a lot reducing boilerplate classes in database drivers extending from core ones.
Comment #24
daffie CreditAttribution: daffie at Finalist commented@mondrake: Thank you for working on this.
Adding the same code to every database drivers Connnection class is a bit of an ugly solution. We are breaking the DRY principle. Would it be possible to put the code in trait? Or maybe another solution?
Comment #25
mondrakeIt’s not the SAME code actually. Each method instantiates a class either in the same namespace of the Connection class, or in the core lib, depending in the
use
imports at the beginning of each driver’s Connection class. In D11 we might change the core abstract Connection methods to instantiate the classes onDatabase\Query
, and use default inheritance in drivers’ extending Connection classes. We can’t do that now without breaking BC. In any case, most of the classes even in core drivers DO extend from the core classes, so the driver specific methods will stay.Comment #26
smustgrave CreditAttribution: smustgrave at Mobomo commentedGoing to put this in the committers queue. But if I'm understanding correctly this gives more control in the individual drivers?
Change record was clear too for how to update my own driver. Think getting in early gives more time for contrib modules to transition.
Comment #27
daffie CreditAttribution: daffie at Finalist commented@mondrake I am not sure my other solution also works with static code analysis. A database driver only needs to set the class variable when it is overriding the class. This solution also works for database drivers that are extending another database driver. The problem with your solution is that every database driver Connnection class needs to add the "same" boilerplate code. What do you think?
Comment #28
mondrake@daffie IMHO we should avoid using properties to store the class whereabouts, that replace native autoloading with our magic. That's what
protected $statementWrapperClass
is doing, and I think we should also change that at some point.I know this looks like adding boilerplate, but it's actually not. These are methods that are there just to create a proper instance of a class depending on the driver. In our current predicament, we can not leverage inheritance because of BC concerns. But once we can, there will be quite some cleanup possible - the same cleanup that it's possible with this MR in contrib drivers that extend from core ones and do not have to override a specific class (see the test drivers in the MR already).
Better than many words, I'll post here 'how' D11 could look like in this respect.
Comment #29
daffie CreditAttribution: daffie at Finalist commented+1 for RTBC.
@mondrake: Thank you for explaining.
Comment #30
mondrake@daffie here's the idea per #28;
Upsert
andSchema
are abstract classes in core, so every driver must implement its ones. But the rest of the classes we can inherit from the core Connection in D11, unless there are overrides.EDIT - I shouldn't have removed MySql Insert class... but here is to illustrate, not to make it work.
Comment #31
daffie CreditAttribution: daffie at Finalist commented@mondrake: Lets go with your solution. I think that in some point in the future, we should create a boilerplate module for a custom database driver for maintainer/creators of database driver modules.
Comment #32
longwaveShould we not deprecate
getDriverClass()
entirely here? Are there any other calls to it with other arguments?Also #28/#30 imply that we might not make all those @todo methods abstract?
Comment #33
mondrakeUnfortunately not, #3217699: Convert select query extenders to backend-overrideable services blocks that deprecation since Query\Select::extend() uses it.
Yes, NW to adjust the @todo(s) - so we need to make
schema
andupsert
abstract since the classes are abstract, all others should be implementations instantiating the corresponding Query\* base class.Comment #34
mondrakeComment #35
smustgrave CreditAttribution: smustgrave at Mobomo commentedPutting back in front of committer eyes.
Comment #36
mondrakeRebased.
Comment #37
longwaveSome tiny nitpicks/questions, and the Postgres tests had a random fail, but I have reviewed this twice now and think it is ready to go after this last round is responded to.
Comment #38
mondrakeHere it comes, @longwave. Thanks
Comment #39
daffie CreditAttribution: daffie at Finalist commentedThe changes look good to me.
Back to RTBC for me.
As long as the testbot is happy too.
Comment #41
longwaveCommitted and pushed 97db62a138 to 11.x. Thanks!
Also published the change record.
Comment #43
mondrakeThank you. Edited the CR to reflect the approach that was eventually committed.
Comment #44
mondrakeFiled #3375919: Deprecate usage of Connection::getDriverClass for 'Install\Tasks' for follow up.