Skip to content

Fix decoration of the Doctrine DBAL connection when it implemented the ServerInfoAwareConnection interface #567

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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