Skip to content

Commit f3594df

Browse files
authored
Fix wrapping of the DBAL driver connection when implementing the Doctrine\DBAL\Driver\ServerInfoAwareConnection interface (#567)
1 parent 977755e commit f3594df

17 files changed

+751
-86
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Add return typehints to the methods of the `SentryExtension` class to prepare for Symfony 6 (#563)
66
- Fix setting the IP address on the user context when it's not available (#565)
77
- Fix wrong method existence check in `TracingDriverConnection::errorCode()` (#568)
8+
- Fix decoration of the Doctrine DBAL connection when it implemented the `ServerInfoAwareConnection` interface (#567)
89

910
## 4.2.3 (2021-09-21)
1011

phpstan-baseline.neon

+40
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,26 @@ parameters:
3535
count: 1
3636
path: src/Tracing/Doctrine/DBAL/TracingDriverConnection.php
3737

38+
-
39+
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingServerInfoAwareDriverConnection\\:\\:errorInfo\\(\\) return type has no value type specified in iterable type array\\.$#"
40+
count: 1
41+
path: src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php
42+
43+
-
44+
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingServerInfoAwareDriverConnection\\:\\:exec\\(\\) has parameter \\$sql with no typehint specified\\.$#"
45+
count: 1
46+
path: src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php
47+
48+
-
49+
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingServerInfoAwareDriverConnection\\:\\:prepare\\(\\) has parameter \\$sql with no typehint specified\\.$#"
50+
count: 1
51+
path: src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php
52+
53+
-
54+
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingServerInfoAwareDriverConnection\\:\\:query\\(\\) has parameter \\$args with no typehint specified\\.$#"
55+
count: 1
56+
path: src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php
57+
3858
-
3959
message: "#^Class Symfony\\\\Bundle\\\\FrameworkBundle\\\\Client not found\\.$#"
4060
count: 1
@@ -170,6 +190,26 @@ parameters:
170190
count: 1
171191
path: tests/Tracing/Doctrine/DBAL/TracingDriverConnectionTest.php
172192

193+
-
194+
message: "#^Parameter \\#1 \\$hubOrConnectionFactory of class Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriverMiddleware constructor expects Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriverConnectionFactoryInterface\\|Sentry\\\\State\\\\HubInterface, null given\\.$#"
195+
count: 1
196+
path: tests/Tracing/Doctrine/DBAL/TracingDriverMiddlewareTest.php
197+
198+
-
199+
message: "#^Trying to mock an undefined method errorCode\\(\\) on class Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriverConnectionInterface\\.$#"
200+
count: 1
201+
path: tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php
202+
203+
-
204+
message: "#^Trying to mock an undefined method errorInfo\\(\\) on class Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriverConnectionInterface\\.$#"
205+
count: 1
206+
path: tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php
207+
208+
-
209+
message: "#^Trying to mock an undefined method requiresQueryForServerVersion\\(\\) on class Sentry\\\\SentryBundle\\\\Tests\\\\Tracing\\\\Doctrine\\\\DBAL\\\\ServerInfoAwareConnectionStub\\.$#"
210+
count: 1
211+
path: tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php
212+
173213
-
174214
message: "#^Trying to mock an undefined method closeCursor\\(\\) on class Doctrine\\\\DBAL\\\\Driver\\\\Statement\\.$#"
175215
count: 1

src/Resources/config/services.xml

+7-1
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,16 @@
9191
<tag name="console.command" />
9292
</service>
9393

94-
<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware" class="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware">
94+
<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactoryInterface" alias="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactory" />
95+
96+
<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactory" class="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactory">
9597
<argument type="service" id="Sentry\State\HubInterface" />
9698
</service>
9799

100+
<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware" class="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware">
101+
<argument type="service" id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactoryInterface" />
102+
</service>
103+
98104
<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\ConnectionConfigurator" class="Sentry\SentryBundle\Tracing\Doctrine\DBAL\ConnectionConfigurator">
99105
<argument type="service" id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware" />
100106
</service>

src/Tracing/Doctrine/DBAL/TracingDriverConnection.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* capabilities to Doctrine DBAL. This implementation IS and MUST be compatible
1717
* with all versions of Doctrine DBAL >= 2.10.
1818
*/
19-
final class TracingDriverConnection implements DriverConnectionInterface
19+
final class TracingDriverConnection implements TracingDriverConnectionInterface
2020
{
2121
/**
2222
* @internal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\SentryBundle\Tracing\Doctrine\DBAL;
6+
7+
use Doctrine\DBAL\Driver\Connection;
8+
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
9+
use Doctrine\DBAL\Platforms\AbstractPlatform;
10+
use Sentry\State\HubInterface;
11+
12+
/**
13+
* @internal
14+
*/
15+
final class TracingDriverConnectionFactory implements TracingDriverConnectionFactoryInterface
16+
{
17+
/**
18+
* @var HubInterface The current hub
19+
*/
20+
private $hub;
21+
22+
/**
23+
* Constructor.
24+
*
25+
* @param HubInterface $hub The current hub
26+
*/
27+
public function __construct(HubInterface $hub)
28+
{
29+
$this->hub = $hub;
30+
}
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
public function create(Connection $connection, AbstractPlatform $databasePlatform, array $params): TracingDriverConnectionInterface
36+
{
37+
$tracingDriverConnection = new TracingDriverConnection(
38+
$this->hub,
39+
$connection,
40+
$databasePlatform->getName(),
41+
$params
42+
);
43+
44+
if ($connection instanceof ServerInfoAwareConnection) {
45+
$tracingDriverConnection = new TracingServerInfoAwareDriverConnection($tracingDriverConnection);
46+
}
47+
48+
return $tracingDriverConnection;
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\SentryBundle\Tracing\Doctrine\DBAL;
6+
7+
use Doctrine\DBAL\Driver\Connection;
8+
use Doctrine\DBAL\Platforms\AbstractPlatform;
9+
10+
interface TracingDriverConnectionFactoryInterface
11+
{
12+
/**
13+
* Creates an instance of a driver connection which is decorated to trace
14+
* the performances of the queries.
15+
*
16+
* @param Connection $connection The connection to wrap
17+
* @param AbstractPlatform $databasePlatform The database platform
18+
* @param array<string, mixed> $params The params of the connection
19+
*/
20+
public function create(Connection $connection, AbstractPlatform $databasePlatform, array $params): TracingDriverConnectionInterface;
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\SentryBundle\Tracing\Doctrine\DBAL;
6+
7+
use Doctrine\DBAL\Driver\Connection;
8+
9+
interface TracingDriverConnectionInterface extends Connection
10+
{
11+
public function getWrappedConnection(): Connection;
12+
}

src/Tracing/Doctrine/DBAL/TracingDriverForV2.php

+9-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use Doctrine\DBAL\Platforms\AbstractPlatform;
1313
use Doctrine\DBAL\Schema\AbstractSchemaManager;
1414
use Doctrine\DBAL\VersionAwarePlatformDriver;
15-
use Sentry\State\HubInterface;
1615

1716
/**
1817
* This is a simple implementation of the {@see Driver} interface that decorates
@@ -24,34 +23,33 @@
2423
final class TracingDriverForV2 implements Driver, VersionAwarePlatformDriver, ExceptionConverterDriver
2524
{
2625
/**
27-
* @var HubInterface The current hub
26+
* @var TracingDriverConnectionFactoryInterface
2827
*/
29-
private $hub;
28+
private $connectionFactory;
3029

3130
/**
3231
* @var Driver|VersionAwarePlatformDriver|ExceptionConverterDriver The instance of the decorated driver
3332
*/
3433
private $decoratedDriver;
3534

3635
/**
37-
* @param HubInterface $hub The current hub
38-
* @param Driver $decoratedDriver The instance of the driver to decorate
36+
* @param TracingDriverConnectionFactoryInterface $connectionFactory The connection factory
37+
* @param Driver $decoratedDriver The instance of the driver to decorate
3938
*/
40-
public function __construct(HubInterface $hub, Driver $decoratedDriver)
39+
public function __construct(TracingDriverConnectionFactoryInterface $connectionFactory, Driver $decoratedDriver)
4140
{
42-
$this->hub = $hub;
4341
$this->decoratedDriver = $decoratedDriver;
42+
$this->connectionFactory = $connectionFactory;
4443
}
4544

4645
/**
4746
* {@inheritdoc}
4847
*/
49-
public function connect(array $params, $username = null, $password = null, array $driverOptions = []): TracingDriverConnection
48+
public function connect(array $params, $username = null, $password = null, array $driverOptions = []): TracingDriverConnectionInterface
5049
{
51-
return new TracingDriverConnection(
52-
$this->hub,
50+
return $this->connectionFactory->create(
5351
$this->decoratedDriver->connect($params, $username, $password, $driverOptions),
54-
$this->decoratedDriver->getDatabasePlatform()->getName(),
52+
$this->decoratedDriver->getDatabasePlatform(),
5553
$params
5654
);
5755
}

src/Tracing/Doctrine/DBAL/TracingDriverForV3.php

+11-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use Doctrine\DBAL\Platforms\AbstractPlatform;
1111
use Doctrine\DBAL\Schema\AbstractSchemaManager;
1212
use Doctrine\DBAL\VersionAwarePlatformDriver;
13-
use Sentry\State\HubInterface;
1413

1514
/**
1615
* This is a simple implementation of the {@see Driver} interface that decorates
@@ -22,34 +21,35 @@
2221
final class TracingDriverForV3 implements Driver, VersionAwarePlatformDriver
2322
{
2423
/**
25-
* @var HubInterface The current hub
24+
* @var TracingDriverConnectionFactoryInterface The connection factory
2625
*/
27-
private $hub;
26+
private $connectionFactory;
2827

2928
/**
3029
* @var Driver|VersionAwarePlatformDriver The instance of the decorated driver
3130
*/
3231
private $decoratedDriver;
3332

3433
/**
35-
* @param HubInterface $hub The current hub
36-
* @param Driver $decoratedDriver The instance of the driver to decorate
34+
* Constructor.
35+
*
36+
* @param TracingDriverConnectionFactoryInterface $connectionFactory The connection factory
37+
* @param Driver $decoratedDriver The instance of the driver to decorate
3738
*/
38-
public function __construct(HubInterface $hub, Driver $decoratedDriver)
39+
public function __construct(TracingDriverConnectionFactoryInterface $connectionFactory, Driver $decoratedDriver)
3940
{
40-
$this->hub = $hub;
41+
$this->connectionFactory = $connectionFactory;
4142
$this->decoratedDriver = $decoratedDriver;
4243
}
4344

4445
/**
4546
* {@inheritdoc}
4647
*/
47-
public function connect(array $params): TracingDriverConnection
48+
public function connect(array $params): TracingDriverConnectionInterface
4849
{
49-
return new TracingDriverConnection(
50-
$this->hub,
50+
return $this->connectionFactory->create(
5151
$this->decoratedDriver->connect($params),
52-
$this->decoratedDriver->getDatabasePlatform()->getName(),
52+
$this->decoratedDriver->getDatabasePlatform(),
5353
$params
5454
);
5555
}

src/Tracing/Doctrine/DBAL/TracingDriverMiddleware.php

+16-6
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,39 @@
1111
/**
1212
* This middleware wraps a {@see Driver} instance into one that
1313
* supports the distributed tracing feature of Sentry.
14+
*
15+
* @internal since version 4.2
1416
*/
1517
final class TracingDriverMiddleware implements Middleware
1618
{
1719
/**
18-
* @var HubInterface The current hub
20+
* @var TracingDriverConnectionFactoryInterface
1921
*/
20-
private $hub;
22+
private $connectionFactory;
2123

2224
/**
2325
* Constructor.
2426
*
25-
* @param HubInterface $hub The current hub
27+
* @param HubInterface|TracingDriverConnectionFactoryInterface $hubOrConnectionFactory The current hub (deprecated) or the connection factory
2628
*/
27-
public function __construct(HubInterface $hub)
29+
public function __construct($hubOrConnectionFactory)
2830
{
29-
$this->hub = $hub;
31+
if ($hubOrConnectionFactory instanceof TracingDriverConnectionFactoryInterface) {
32+
$this->connectionFactory = $hubOrConnectionFactory;
33+
} elseif ($hubOrConnectionFactory instanceof HubInterface) {
34+
@trigger_error(sprintf('Not passing an instance of the "%s" interface as argument of the constructor is deprecated since version 4.2 and will not work since version 5.0.', TracingDriverConnectionFactoryInterface::class), \E_USER_DEPRECATED);
35+
36+
$this->connectionFactory = new TracingDriverConnectionFactory($hubOrConnectionFactory);
37+
} else {
38+
throw new \InvalidArgumentException(sprintf('The constructor requires either an instance of the "%s" interface or an instance of the "%s" interface.', HubInterface::class, TracingDriverConnectionFactoryInterface::class));
39+
}
3040
}
3141

3242
/**
3343
* {@inheritdoc}
3444
*/
3545
public function wrap(Driver $driver): Driver
3646
{
37-
return new TracingDriver($this->hub, $driver);
47+
return new TracingDriver($this->connectionFactory, $driver);
3848
}
3949
}

0 commit comments

Comments
 (0)