Skip to content

Commit 1751d47

Browse files
transistiveexaby73
andauthored
Support Symfony featues on all Driver Building blocks (#91)
* fix: reworked architecture to support symfony features in every driver building block * feat: Add events for pre and post: begin, rollback and commit transaction events --------- Co-authored-by: exaby73 <[email protected]>
1 parent b7eda4b commit 1751d47

28 files changed

+1159
-289
lines changed

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"symfony/stopwatch": "^6.4",
3333
"symfony/test-pack": "^1.1",
3434
"symfony/twig-bundle": "^5.4 || ^6.0 || ^7.0",
35+
"symfony/uid": "^6.4",
3536
"symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0",
3637
"symfony/yaml": "^5.4 || ^6.0 || ^7.0",
3738
"vimeo/psalm": "^5.15.0"

config/services.php

+37-6
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,37 @@
22

33
use Laudis\Neo4j\Basic\Driver;
44
use Laudis\Neo4j\Basic\Session;
5+
use Laudis\Neo4j\Common\DriverSetupManager;
56
use Laudis\Neo4j\Contracts\ClientInterface;
67
use Laudis\Neo4j\Contracts\DriverInterface;
78
use Laudis\Neo4j\Contracts\SessionInterface;
89
use Laudis\Neo4j\Contracts\TransactionInterface;
9-
use Neo4j\Neo4jBundle\ClientFactory;
10+
use Laudis\Neo4j\Databags\DriverConfiguration;
11+
use Laudis\Neo4j\Databags\SessionConfiguration;
12+
use Laudis\Neo4j\Databags\TransactionConfiguration;
13+
use Laudis\Neo4j\Formatter\SummarizedResultFormatter;
14+
use Neo4j\Neo4jBundle\Builders\ClientBuilder;
15+
use Neo4j\Neo4jBundle\Decorators\SymfonyClient;
16+
use Neo4j\Neo4jBundle\EventHandler;
1017
use Neo4j\Neo4jBundle\EventListener\Neo4jProfileListener;
11-
use Neo4j\Neo4jBundle\SymfonyClient;
18+
use Neo4j\Neo4jBundle\Factories\ClientFactory;
19+
use Neo4j\Neo4jBundle\Factories\StopwatchEventNameFactory;
20+
use Neo4j\Neo4jBundle\Factories\SymfonyDriverFactory;
1221
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
1322

1423
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
1524

1625
return static function (ContainerConfigurator $configurator) {
1726
$services = $configurator->services();
1827

19-
$services->set('neo4j.client_factory', ClientFactory::class)
20-
->args([
21-
service('neo4j.event_handler'),
22-
]);
28+
$services->set('neo4j.client_factory', ClientFactory::class);
29+
30+
$services->set(DriverConfiguration::class, DriverConfiguration::class)
31+
->factory([DriverConfiguration::class, 'default']);
32+
$services->set(SessionConfiguration::class, SessionConfiguration::class);
33+
$services->set(TransactionConfiguration::class, TransactionConfiguration::class);
34+
$services->set(ClientBuilder::class, ClientBuilder::class)
35+
->autowire();
2336

2437
$services->set('neo4j.client', SymfonyClient::class)
2538
->factory([service('neo4j.client_factory'), 'create'])
@@ -39,6 +52,24 @@
3952
->share(false)
4053
->public();
4154

55+
$services->set(SymfonyDriverFactory::class, SymfonyDriverFactory::class)
56+
->arg('$handler', service(EventHandler::class))
57+
->arg('$uuidFactory', service('uuid.factory')->nullOnInvalid());
58+
59+
$services->set(StopwatchEventNameFactory::class, StopwatchEventNameFactory::class);
60+
$services->set(EventHandler::class, EventHandler::class)
61+
->arg('$dispatcher', service('event_dispatcher')->nullOnInvalid())
62+
->arg('$stopwatch', service('debug.stopwatch')->nullOnInvalid())
63+
->arg('$nameFactory', service(StopwatchEventNameFactory::class));
64+
65+
$services->set(StopwatchEventNameFactory::class);
66+
67+
$services->set(DriverSetupManager::class, DriverSetupManager::class)
68+
->arg('$formatter', service(SummarizedResultFormatter::class))
69+
->arg('$configuration', service(DriverConfiguration::class));
70+
$services->set(SummarizedResultFormatter::class, SummarizedResultFormatter::class)
71+
->factory([SummarizedResultFormatter::class, 'create']);
72+
4273
$services->alias(ClientInterface::class, 'neo4j.client');
4374
$services->alias(DriverInterface::class, 'neo4j.driver');
4475
$services->alias(SessionInterface::class, 'neo4j.session');

src/Builders/ClientBuilder.php

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
namespace Neo4j\Neo4jBundle\Builders;
4+
5+
use Laudis\Neo4j\Authentication\Authenticate;
6+
use Laudis\Neo4j\Common\DriverSetupManager;
7+
use Laudis\Neo4j\Common\Uri;
8+
use Laudis\Neo4j\Contracts\AuthenticateInterface;
9+
use Laudis\Neo4j\Databags\DriverConfiguration;
10+
use Laudis\Neo4j\Databags\DriverSetup;
11+
use Laudis\Neo4j\Databags\SessionConfiguration;
12+
use Laudis\Neo4j\Databags\TransactionConfiguration;
13+
use Laudis\Neo4j\Exception\UnsupportedScheme;
14+
use Neo4j\Neo4jBundle\Decorators\SymfonyClient;
15+
use Neo4j\Neo4jBundle\Factories\SymfonyDriverFactory;
16+
17+
final class ClientBuilder
18+
{
19+
public const SUPPORTED_SCHEMES = ['', 'bolt', 'bolt+s', 'bolt+ssc', 'neo4j', 'neo4j+s', 'neo4j+ssc', 'http', 'https'];
20+
21+
/**
22+
* @psalm-mutation-free
23+
*
24+
* @param DriverSetupManager<mixed> $driverSetups
25+
*/
26+
public function __construct(
27+
private SessionConfiguration $defaultSessionConfig,
28+
private TransactionConfiguration $defaultTransactionConfig,
29+
private DriverSetupManager $driverSetups,
30+
private readonly SymfonyDriverFactory $driverFactory,
31+
) {
32+
}
33+
34+
public function withDriver(string $alias, string $url, ?AuthenticateInterface $authentication = null, ?int $priority = 0): self
35+
{
36+
$uri = Uri::create($url);
37+
38+
$authentication ??= Authenticate::fromUrl($uri, $this->driverSetups->getLogger());
39+
40+
return $this->withParsedUrl($alias, $uri, $authentication, $priority ?? 0);
41+
}
42+
43+
private function withParsedUrl(string $alias, Uri $uri, AuthenticateInterface $authentication, int $priority): self
44+
{
45+
$scheme = $uri->getScheme();
46+
47+
if (!in_array($scheme, self::SUPPORTED_SCHEMES, true)) {
48+
throw UnsupportedScheme::make($scheme, self::SUPPORTED_SCHEMES);
49+
}
50+
51+
$tbr = clone $this;
52+
$tbr->driverSetups = $this->driverSetups->withSetup(new DriverSetup($uri, $authentication), $alias, $priority);
53+
54+
return $tbr;
55+
}
56+
57+
public function withDefaultDriver(string $alias): self
58+
{
59+
$tbr = clone $this;
60+
$tbr->driverSetups = $this->driverSetups->withDefault($alias);
61+
62+
return $tbr;
63+
}
64+
65+
public function build(): SymfonyClient
66+
{
67+
return new SymfonyClient(
68+
driverSetups: $this->driverSetups,
69+
defaultSessionConfiguration: $this->defaultSessionConfig,
70+
defaultTransactionConfiguration: $this->defaultTransactionConfig,
71+
factory: $this->driverFactory
72+
);
73+
}
74+
75+
public function withDefaultDriverConfiguration(DriverConfiguration $config): self
76+
{
77+
$tbr = clone $this;
78+
79+
$tbr->driverSetups = $tbr->driverSetups->withDriverConfiguration($config);
80+
81+
return $tbr;
82+
}
83+
84+
public function withDefaultSessionConfiguration(SessionConfiguration $config): self
85+
{
86+
$tbr = clone $this;
87+
$tbr->defaultSessionConfig = $config;
88+
89+
return $tbr;
90+
}
91+
92+
public function withDefaultTransactionConfiguration(TransactionConfiguration $config): self
93+
{
94+
$tbr = clone $this;
95+
$tbr->defaultTransactionConfig = $config;
96+
97+
return $tbr;
98+
}
99+
}

src/Collector/Neo4jDataCollector.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function collect(Request $request, Response $response, ?\Throwable $excep
5151
'time' => $x['time'],
5252
'timestamp' => $x['timestamp'],
5353
'result' => [
54-
'statement' => $x['statement']->toArray(),
54+
'statement' => $x['statement']?->toArray(),
5555
],
5656
'exception' => [
5757
'code' => $x['exception']->getErrors()[0]->getCode(),

0 commit comments

Comments
 (0)