Problem/Motivation
Drupal core just introduced a feature to use the query portion of the database URI to pass in additional parameters to the database layer. Currently, the only parameter that is used in core is 'module'. the sqlsrv module would like to use 'schema' to pass in the name of the database schema, and use Connection:: createConnectionOptionsFromUrl() to manage this option. This strategy was working in development until the parent issue went live.
The database query sqlsrv://sa:Password12!@localhost/mydrupalsite?schema=dbo
will currently cause Drupal to throw an error.
Proposed resolution
The file core/lib/Drupal/Core/Database/Database.php should change:
if ($query['module'])
to
if (isset($query['module']))
This will allow drivers to have query parameters without specifying the optional 'module' parameter. When other query parameters are officially added, this will have to be changed regardless.
Comment | File | Size | Author |
---|---|---|---|
#11 | 3126940-11-expect-fail.patch | 980 bytes | Beakerboy |
#11 | 3126940-11.patch | 1.68 KB | Beakerboy |
Comments
Comment #2
BeakerboyComment #3
daffie CreditAttribution: daffie commentedHi @Beakerboy: Could write up with more details what exactly you would like. Add examples with what should work according to you.
Comment #4
BeakerboyI would like to use the database uri sqlsrv://sa:Password12!@localhost/mydrupalsite?schema=dbo
The new feature assumes that if there is any parameter in the query position, it must include ‘?module=something’. Changing
if ($query['module'])
toif (isset($query['module']))
. Will allow a driver to specify a query parameter without a ‘module’.Comment #5
daffie CreditAttribution: daffie commentedHi @Beakerboy: I think what you miss is that the query parameter can hold multiple variables. See: https://www.php.net/manual/en/function.parse-str.php. If you we to add the module parameter to your database connection URL it would become:
sqlsrv://sa:Password12!@localhost/mydrupalsite?schema=dbo&module=sqlsrv
or
sqlsrv://sa:Password12!@localhost/mydrupalsite?module=sqlsrv&schema=dbo
They work the same.
With the database connection URL that you gave as an example, the part within the if-statement (the one in your patch) will be skiped. Without your patch applied and with your patch applied.
As for your the code:
if (isset($query['module']))
only checks the existens of the key "module" in the $query array. The code:if ($query['module'])
does the same check as the previous code example and also checks that the value of$query['module']
is not an empty string, the number zero or NULL. In this case as the parse_str method returns only string values, the testing is only that it is not an empty string.If my answer does not help you or you wanted to make a point that I missed, then please say so.
Comment #6
BeakerboyWithout my proposed change, my example URI will cause an error to be thrown because $query[‘module’] is not set. I can add an override to Connection:: createConnectionOptionsFromUrl() to ensure my module’s custom functionality is correct. Core does not need to know anything about what custom query parameters the sqlsrv module is implementing...but the lack of the
isset($query[‘module’])
prevents sqlsrv (and any other driver) from implementing query parameters.Good point on the empty string part. We could use short circuiting and do
if(isset($query[‘module’]) && $query[‘module’])
.The first rule of PHP is to check user input. Core is not checking the query array and instead assuming that if it exists, there must be a ‘module’ index. I would like it to silently ignore cases where this index does not exist instead of throwing an error.
Comment #7
BeakerboyI added a few more details to the issue. Should it be a bug instead of a feature request?
Comment #8
daffie CreditAttribution: daffie commented@Beakerboy: Yes, you are right. This is a bug. Do you want to make the automated test? Then I will review it.
Comment #9
BeakerboyShould I add this to core/tests/Drupal/Tests/Core/Database/UrlConversionTest.php
This would test that adding some value to the query parameter will have no effect on the connection array; they will be silently ignored.
Comment #10
daffie CreditAttribution: daffie commentedThat looks about right. Make 2 patches: one with the test and the fix, the other patch only with the test. The first patch should pass the testbot and the second patch should fail.
Comment #11
Beakerboyincluding a failing test and a patch for the failure.
Comment #13
BeakerboyTesting demonstrated the failure and the fix. Needs review.
Comment #14
daffie CreditAttribution: daffie commentedThe fix looks good.
The added testing looks good.
The testbot fails with the message; "Undefined index: module".
For me it is RTBC.
Good work @Beakerboy.
Comment #18
catchCommitted/pushed to 9.1.x and cherry-picked back to 8.9.x, thanks!