Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for compatibility with DBAL 3 #1263

Merged
merged 2 commits into from
Nov 19, 2020
Merged

Conversation

greg0ire
Copy link
Member

@greg0ire greg0ire commented Nov 16, 2020

I tested this on a real project, it allows to install the project without errors.

Fixes #1262 , fixes #1264

How can I test this?

composer config repositories.greg0ire vcs https://github.com/greg0ire/DoctrineBundle
composer require doctrine/doctrine-bundle "dev-dbal-3-compat as 2.2.1"

@greg0ire greg0ire added the Bug label Nov 16, 2020
@greg0ire greg0ire removed the request for review from ostrolucky November 16, 2020 08:29
@greg0ire greg0ire marked this pull request as draft November 16, 2020 08:29
@ostrolucky
Copy link
Member

Looks good so far, ask me to review after it's no longer draft please.

@greg0ire
Copy link
Member Author

greg0ire commented Nov 16, 2020

Looks good so far, ask me to review after it's no longer draft please.

I need to revert the composer.json change and detect 2.10.0, will work on it this evening but feel fre to do it and push to my branch 👍

The alternative to that would be to merge and release doctrine/dbal#4386

@greg0ire greg0ire force-pushed the dbal-3-compat branch 3 times, most recently from 740f645 to 3171edc Compare November 16, 2020 17:30
@@ -23,11 +23,7 @@
<service id="Doctrine\DBAL\Driver\Connection" alias="database_connection" public="false" />
<service id="Doctrine\DBAL\Connection" alias="database_connection" public="false" />

<service id="doctrine.dbal.logger.chain" class="%doctrine.dbal.logger.chain.class%" public="false" abstract="true">
<call method="addLogger">
<argument type="service" id="doctrine.dbal.logger" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wasn't this call needed ? I don't see its replacement

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The replacement is in PHP, it's the very first lines of this PR

$chainLogger->addMethodCall('addLogger', [$profilingLogger]);
} else {
$chainLogger->addArgument([$profilingLogger]);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stof here is the replacement you asked for in https://github.com/doctrine/DoctrineBundle/pull/1263/files#r524450538 (I think it's equivalent)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not equivalent. As you need to pass an array of loggers to the constructor rather than multiple calls to addLogger, you need to build an array containing them all.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But there is only one logger before this PR, right?

Copy link
Member Author

@greg0ire greg0ire Nov 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are you suggesting exactly? This?

            $chainLogger->replaceArgument(
                0,
                array_merge($chainLogger->getArgument(0), [$logger])
            );

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no. Cases where the chain logger are used are precisely cases where we have 2 loggers:

  • doctrine.dbal.logger logging to your app PSR-3 logger (generally Monolog)
  • the profiling logger which logs query executions for the profiler

Your suggestion won't work if the reference to doctrine.dbal.logger is added to the constructor of the doctrine.dbal.logger.chain abstract definition, because the child definition won't have anything yet for the argument. Instead, you should just use [$logger, $profilingLogger] as the value of the argument

Copy link
Member Author

@greg0ire greg0ire Nov 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stof none of the calls to addLogger in this codebase are performed on the same service. I don't get your point.

UPD: didn't see your answer, I will try that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the existing code, the call done in XML is done on the abstract service definition which is extended by the definitions in each of the DBAL connections.

so after resolving the definition inheritance, each chain logger will have 2 addLogger calls:

  • the one inherited from the abstract definition for doctrine.dbal.logger
  • the one set on themselves for the connection-specific profiling logger.

@@ -85,6 +87,14 @@ protected function dbalLoad(array $config, ContainerBuilder $container)
{
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('dbal.xml');
$chainLogger = $container->getDefinition('doctrine.dbal.logger.chain');
$profilingLogger = new Reference('doctrine.dbal.logger');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable name is really confusing, as doctrine.dbal.logger is not the profiling logger, but the logger logging your queries in the Symfony logs through PSR-3.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

$container = $this->createDbalOnlyTestContainer();
$this->assertInstanceOf(
LoggerChain::class,
$container->get('doctrine.dbal.logger.chain.default')
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have messed up somewhere because although the service definition has 2 loggers, that object has only one when I dump it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh but when I remove the first else branch in this PR, it works.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment on the broken code.

Copy link
Member Author

@greg0ire greg0ire Nov 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just pushed, does it look correct or do I still misunderstand? Sorry, I'm quite tired today 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now looks good.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// doctrine/dbal < 2.10.0
$chainLogger->addMethodCall('addLogger', [$logger]);
} else {
$chainLogger->addArgument([$logger]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this must be removed. You are adding an argument here with an array with 1 element, and then later adding a second argument with an array with 2 elements. But the ChainLogger expects the list of loggers as its first argument so that's why things don't work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an alternative would be to use replaceArgument in the ChildDefinition

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That might be better 🤔 in case people are using the abstract service definition to build their custom service.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed again, this time with replaceArgument

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if they use it to build their own custom service, they will need to change their code for the DBAL 3 way anyway.

Copy link
Member Author

@greg0ire greg0ire Nov 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I'm switching to the constructor as soon as possible (2.10.0), not as late as possible (3.0.0), because a deprecation layer might be added later on the DBAL. This means people using DBAL >=2.10 and building their own custom service should need this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed again, this time with replaceArgument

We could even go a cleaner way to prepare for the day we will require DBAL 2.10+ in the bundle (hopefully soon, if the PR adding back PHP 7.1 support in 2.12 is accepted):

  • stop using ChildDefinition in loadDbalConnection but a normal Definition using the chainlogger class (this requires adding the addLogger call for $logger in the branch dealing with DBAL 2.9, but that's fine)
  • mark the doctrine.dbal.logger.chain abstract service as deprecated (in case someone was using it for their own service)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That does seem more straightforward, let me try 👍

$container = $this->createDbalOnlyTestContainer();
$this->assertInstanceOf(
LoggerChain::class,
$container->get('doctrine.dbal.logger.chain.default')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment on the broken code.

@greg0ire greg0ire force-pushed the dbal-3-compat branch 3 times, most recently from a0268d8 to 065a36c Compare November 16, 2020 18:59
<argument type="service" id="doctrine.dbal.logger" />
</call>
<service id="doctrine.dbal.logger.chain" class="%doctrine.dbal.logger.chain.class%" public="false" abstract="true" >
<!-- TODO: deprecate this service in 2.3.0 -->
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stof introducing a new deprecation is minor, so I should do it in a subsequent PR to master I think.

DependencyInjection/DoctrineExtension.php Show resolved Hide resolved
Tests/ContainerTest.php Show resolved Hide resolved
Tests/ContainerTest.php Outdated Show resolved Hide resolved
Tests/TestCase.php Outdated Show resolved Hide resolved
@greg0ire greg0ire changed the title Fix for compatibility with DBAL 3 Fixes for compatibility with DBAL 3 Nov 17, 2020
Passing them through addLogger() is deprecated and no longer works with
DBAL 3 which we support.
That command is built from
Doctrine\DBAL\Tools\Console\Command\ImportCommand, which no longer
exists in DBAL 3 (it is removed in favor of using a client application).
@greg0ire
Copy link
Member Author

@stof can you please give this another review?

@greg0ire
Copy link
Member Author

I suppose the 2 existing reviews are enough already :)

@greg0ire greg0ire merged commit 74c3bab into doctrine:2.2.x Nov 19, 2020
@greg0ire greg0ire deleted the dbal-3-compat branch November 19, 2020 19:13
@greg0ire greg0ire added this to the 2.2.2 milestone Nov 19, 2020
@dmaicher
Copy link
Contributor

@greg0ire I think we need some of those changes also on 1.12.x, or?

As it also allows installing dbal 3: https://github.com/doctrine/DoctrineBundle/blob/1.12.x/composer.json#L29

@greg0ire
Copy link
Member Author

@dmaicher you're right, I had no idea dbal 3 was supported on 1.12.x (or why, it sounds weird, since that version of the bundle is supposed to be left unmaintained soon).

@dmaicher
Copy link
Contributor

@dmaicher you're right, I had no idea dbal 3 was supported on 1.12.x (or why, it sounds weird, since that version of the bundle is supposed to be left unmaintained soon).

Yeah I also just found out while debugging some travis CI failures while working on dmaicher/doctrine-test-bundle#136 😕

@ostrolucky
Copy link
Member

with symfony 3.4 out of maintenance, 1.12.x is pretty much dead now, all that is left is just officially mark it as unmaintained on website config

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
5 participants