Skip to content

Commit

Permalink
Fix wrapping of the DBAL driver connection when implementing the `Doc…
Browse files Browse the repository at this point in the history
…trine\DBAL\Driver\ServerInfoAwareConnection` interface (#567)
  • Loading branch information
ste93cry authored Oct 19, 2021
1 parent 977755e commit f3594df
Show file tree
Hide file tree
Showing 17 changed files with 751 additions and 86 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Add return typehints to the methods of the `SentryExtension` class to prepare for Symfony 6 (#563)
- Fix setting the IP address on the user context when it's not available (#565)
- Fix wrong method existence check in `TracingDriverConnection::errorCode()` (#568)
- Fix decoration of the Doctrine DBAL connection when it implemented the `ServerInfoAwareConnection` interface (#567)

## 4.2.3 (2021-09-21)

Expand Down
40 changes: 40 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,26 @@ parameters:
count: 1
path: src/Tracing/Doctrine/DBAL/TracingDriverConnection.php

-
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingServerInfoAwareDriverConnection\\:\\:errorInfo\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php

-
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingServerInfoAwareDriverConnection\\:\\:exec\\(\\) has parameter \\$sql with no typehint specified\\.$#"
count: 1
path: src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php

-
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingServerInfoAwareDriverConnection\\:\\:prepare\\(\\) has parameter \\$sql with no typehint specified\\.$#"
count: 1
path: src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php

-
message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingServerInfoAwareDriverConnection\\:\\:query\\(\\) has parameter \\$args with no typehint specified\\.$#"
count: 1
path: src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php

-
message: "#^Class Symfony\\\\Bundle\\\\FrameworkBundle\\\\Client not found\\.$#"
count: 1
Expand Down Expand Up @@ -170,6 +190,26 @@ parameters:
count: 1
path: tests/Tracing/Doctrine/DBAL/TracingDriverConnectionTest.php

-
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\\.$#"
count: 1
path: tests/Tracing/Doctrine/DBAL/TracingDriverMiddlewareTest.php

-
message: "#^Trying to mock an undefined method errorCode\\(\\) on class Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriverConnectionInterface\\.$#"
count: 1
path: tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php

-
message: "#^Trying to mock an undefined method errorInfo\\(\\) on class Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriverConnectionInterface\\.$#"
count: 1
path: tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php

-
message: "#^Trying to mock an undefined method requiresQueryForServerVersion\\(\\) on class Sentry\\\\SentryBundle\\\\Tests\\\\Tracing\\\\Doctrine\\\\DBAL\\\\ServerInfoAwareConnectionStub\\.$#"
count: 1
path: tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php

-
message: "#^Trying to mock an undefined method closeCursor\\(\\) on class Doctrine\\\\DBAL\\\\Driver\\\\Statement\\.$#"
count: 1
Expand Down
8 changes: 7 additions & 1 deletion src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,16 @@
<tag name="console.command" />
</service>

<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware" class="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware">
<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactoryInterface" alias="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactory" />

<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactory" class="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactory">
<argument type="service" id="Sentry\State\HubInterface" />
</service>

<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware" class="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware">
<argument type="service" id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverConnectionFactoryInterface" />
</service>

<service id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\ConnectionConfigurator" class="Sentry\SentryBundle\Tracing\Doctrine\DBAL\ConnectionConfigurator">
<argument type="service" id="Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware" />
</service>
Expand Down
2 changes: 1 addition & 1 deletion src/Tracing/Doctrine/DBAL/TracingDriverConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* capabilities to Doctrine DBAL. This implementation IS and MUST be compatible
* with all versions of Doctrine DBAL >= 2.10.
*/
final class TracingDriverConnection implements DriverConnectionInterface
final class TracingDriverConnection implements TracingDriverConnectionInterface
{
/**
* @internal
Expand Down
50 changes: 50 additions & 0 deletions src/Tracing/Doctrine/DBAL/TracingDriverConnectionFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Sentry\SentryBundle\Tracing\Doctrine\DBAL;

use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Sentry\State\HubInterface;

/**
* @internal
*/
final class TracingDriverConnectionFactory implements TracingDriverConnectionFactoryInterface
{
/**
* @var HubInterface The current hub
*/
private $hub;

/**
* Constructor.
*
* @param HubInterface $hub The current hub
*/
public function __construct(HubInterface $hub)
{
$this->hub = $hub;
}

/**
* {@inheritdoc}
*/
public function create(Connection $connection, AbstractPlatform $databasePlatform, array $params): TracingDriverConnectionInterface
{
$tracingDriverConnection = new TracingDriverConnection(
$this->hub,
$connection,
$databasePlatform->getName(),
$params
);

if ($connection instanceof ServerInfoAwareConnection) {
$tracingDriverConnection = new TracingServerInfoAwareDriverConnection($tracingDriverConnection);
}

return $tracingDriverConnection;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Sentry\SentryBundle\Tracing\Doctrine\DBAL;

use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Platforms\AbstractPlatform;

interface TracingDriverConnectionFactoryInterface
{
/**
* Creates an instance of a driver connection which is decorated to trace
* the performances of the queries.
*
* @param Connection $connection The connection to wrap
* @param AbstractPlatform $databasePlatform The database platform
* @param array<string, mixed> $params The params of the connection
*/
public function create(Connection $connection, AbstractPlatform $databasePlatform, array $params): TracingDriverConnectionInterface;
}
12 changes: 12 additions & 0 deletions src/Tracing/Doctrine/DBAL/TracingDriverConnectionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Sentry\SentryBundle\Tracing\Doctrine\DBAL;

use Doctrine\DBAL\Driver\Connection;

interface TracingDriverConnectionInterface extends Connection
{
public function getWrappedConnection(): Connection;
}
20 changes: 9 additions & 11 deletions src/Tracing/Doctrine/DBAL/TracingDriverForV2.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use Sentry\State\HubInterface;

/**
* This is a simple implementation of the {@see Driver} interface that decorates
Expand All @@ -24,34 +23,33 @@
final class TracingDriverForV2 implements Driver, VersionAwarePlatformDriver, ExceptionConverterDriver
{
/**
* @var HubInterface The current hub
* @var TracingDriverConnectionFactoryInterface
*/
private $hub;
private $connectionFactory;

/**
* @var Driver|VersionAwarePlatformDriver|ExceptionConverterDriver The instance of the decorated driver
*/
private $decoratedDriver;

/**
* @param HubInterface $hub The current hub
* @param Driver $decoratedDriver The instance of the driver to decorate
* @param TracingDriverConnectionFactoryInterface $connectionFactory The connection factory
* @param Driver $decoratedDriver The instance of the driver to decorate
*/
public function __construct(HubInterface $hub, Driver $decoratedDriver)
public function __construct(TracingDriverConnectionFactoryInterface $connectionFactory, Driver $decoratedDriver)
{
$this->hub = $hub;
$this->decoratedDriver = $decoratedDriver;
$this->connectionFactory = $connectionFactory;
}

/**
* {@inheritdoc}
*/
public function connect(array $params, $username = null, $password = null, array $driverOptions = []): TracingDriverConnection
public function connect(array $params, $username = null, $password = null, array $driverOptions = []): TracingDriverConnectionInterface
{
return new TracingDriverConnection(
$this->hub,
return $this->connectionFactory->create(
$this->decoratedDriver->connect($params, $username, $password, $driverOptions),
$this->decoratedDriver->getDatabasePlatform()->getName(),
$this->decoratedDriver->getDatabasePlatform(),
$params
);
}
Expand Down
22 changes: 11 additions & 11 deletions src/Tracing/Doctrine/DBAL/TracingDriverForV3.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use Sentry\State\HubInterface;

/**
* This is a simple implementation of the {@see Driver} interface that decorates
Expand All @@ -22,34 +21,35 @@
final class TracingDriverForV3 implements Driver, VersionAwarePlatformDriver
{
/**
* @var HubInterface The current hub
* @var TracingDriverConnectionFactoryInterface The connection factory
*/
private $hub;
private $connectionFactory;

/**
* @var Driver|VersionAwarePlatformDriver The instance of the decorated driver
*/
private $decoratedDriver;

/**
* @param HubInterface $hub The current hub
* @param Driver $decoratedDriver The instance of the driver to decorate
* Constructor.
*
* @param TracingDriverConnectionFactoryInterface $connectionFactory The connection factory
* @param Driver $decoratedDriver The instance of the driver to decorate
*/
public function __construct(HubInterface $hub, Driver $decoratedDriver)
public function __construct(TracingDriverConnectionFactoryInterface $connectionFactory, Driver $decoratedDriver)
{
$this->hub = $hub;
$this->connectionFactory = $connectionFactory;
$this->decoratedDriver = $decoratedDriver;
}

/**
* {@inheritdoc}
*/
public function connect(array $params): TracingDriverConnection
public function connect(array $params): TracingDriverConnectionInterface
{
return new TracingDriverConnection(
$this->hub,
return $this->connectionFactory->create(
$this->decoratedDriver->connect($params),
$this->decoratedDriver->getDatabasePlatform()->getName(),
$this->decoratedDriver->getDatabasePlatform(),
$params
);
}
Expand Down
22 changes: 16 additions & 6 deletions src/Tracing/Doctrine/DBAL/TracingDriverMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,39 @@
/**
* This middleware wraps a {@see Driver} instance into one that
* supports the distributed tracing feature of Sentry.
*
* @internal since version 4.2
*/
final class TracingDriverMiddleware implements Middleware
{
/**
* @var HubInterface The current hub
* @var TracingDriverConnectionFactoryInterface
*/
private $hub;
private $connectionFactory;

/**
* Constructor.
*
* @param HubInterface $hub The current hub
* @param HubInterface|TracingDriverConnectionFactoryInterface $hubOrConnectionFactory The current hub (deprecated) or the connection factory
*/
public function __construct(HubInterface $hub)
public function __construct($hubOrConnectionFactory)
{
$this->hub = $hub;
if ($hubOrConnectionFactory instanceof TracingDriverConnectionFactoryInterface) {
$this->connectionFactory = $hubOrConnectionFactory;
} elseif ($hubOrConnectionFactory instanceof HubInterface) {
@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);

$this->connectionFactory = new TracingDriverConnectionFactory($hubOrConnectionFactory);
} else {
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));
}
}

/**
* {@inheritdoc}
*/
public function wrap(Driver $driver): Driver
{
return new TracingDriver($this->hub, $driver);
return new TracingDriver($this->connectionFactory, $driver);
}
}
Loading

0 comments on commit f3594df

Please sign in to comment.