Skip to content

Commit c704332

Browse files
committed
revert: Remove profiling
1 parent f84e9dd commit c704332

File tree

8 files changed

+363
-0
lines changed

8 files changed

+363
-0
lines changed

config/services.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Laudis\Neo4j\Contracts\TransactionInterface;
99
use Neo4j\Neo4jBundle\ClientFactory;
1010
use Neo4j\Neo4jBundle\EventHandler;
11+
use Neo4j\Neo4jBundle\EventListener\Neo4jProfileListener;
1112
use Neo4j\Neo4jBundle\SymfonyClient;
1213
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
1314

@@ -47,4 +48,7 @@
4748
$services->alias(DriverInterface::class, 'neo4j.driver');
4849
$services->alias(SessionInterface::class, 'neo4j.session');
4950
$services->alias(TransactionInterface::class, 'neo4j.transaction');
51+
52+
$services->set('neo4j.subscriber', Neo4jProfileListener::class)
53+
->tag('kernel.event_subscriber');
5054
};

phpunit.xml.dist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="./vendor/autoload.php" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
33
<testsuites>
4+
<testsuite name="Unit tests">
5+
<directory suffix="Test.php">./tests/Unit</directory>
6+
</testsuite>
47
<testsuite name="Functional tests">
58
<directory suffix="Test.php">./tests/Functional</directory>
69
</testsuite>

src/Collector/Neo4jDataCollector.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Neo4j\Neo4jBundle\Collector;
6+
7+
use Laudis\Neo4j\Databags\ResultSummary;
8+
use Neo4j\Neo4jBundle\EventListener\Neo4jProfileListener;
9+
use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector;
10+
use Symfony\Component\HttpFoundation\Request;
11+
use Symfony\Component\HttpFoundation\Response;
12+
13+
/**
14+
* @var array{
15+
* successful_statements: array<array-key, array<string, mixed>>,
16+
* failed_statements: list<array{
17+
* statement: mixed,
18+
* exception: mixed,
19+
* alias: string|null
20+
* }>
21+
* } $data
22+
*/
23+
final class Neo4jDataCollector extends AbstractDataCollector
24+
{
25+
public function __construct(
26+
private Neo4jProfileListener $subscriber
27+
) {
28+
}
29+
30+
public function collect(Request $request, Response $response, ?\Throwable $exception = null): void
31+
{
32+
$this->data['successful_statements'] = array_map(
33+
static fn (ResultSummary $summary) => $summary->toArray(),
34+
$this->subscriber->getProfiledSummaries()
35+
);
36+
37+
$this->data['failed_statements'] = array_map(
38+
static fn (array $x) => [
39+
'statement' => $x['statement']->toArray(),
40+
'exception' => [
41+
'code' => $x['exception']->getErrors()[0]->getCode(),
42+
'message' => $x['exception']->getErrors()[0]->getMessage(),
43+
'classification' => $x['exception']->getErrors()[0]->getClassification(),
44+
'category' => $x['exception']->getErrors()[0]->getCategory(),
45+
'title' => $x['exception']->getErrors()[0]->getTitle(),
46+
],
47+
'alias' => $x['alias'],
48+
],
49+
$this->subscriber->getProfiledFailures()
50+
);
51+
}
52+
53+
public function reset(): void
54+
{
55+
parent::reset();
56+
$this->subscriber->reset();
57+
}
58+
59+
public function getName(): string
60+
{
61+
return 'neo4j';
62+
}
63+
64+
public function getFailedStatements(): array
65+
{
66+
return $this->data['failed_statements'];
67+
}
68+
69+
public function getSuccessfulStatements(): array
70+
{
71+
return $this->data['successful_statements'];
72+
}
73+
74+
public function getQueryCount(): int
75+
{
76+
return count($this->data['successful_statements']) + count($this->data['failed_statements']);
77+
}
78+
79+
public static function getTemplate(): ?string
80+
{
81+
return 'web_profiler.html.twig';
82+
}
83+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Neo4j\Neo4jBundle\Collector\Twig;
6+
7+
use Laudis\Neo4j\Types\Node;
8+
use Twig\Extension\AbstractExtension;
9+
use Twig\TwigFilter;
10+
11+
/**
12+
* @author Tobias Nyholm <[email protected]>
13+
*/
14+
class Neo4jResultExtension extends AbstractExtension
15+
{
16+
/**
17+
* @return array<TwigFilter>
18+
*/
19+
public function getFilters(): array
20+
{
21+
return [
22+
new TwigFilter('neo4jResult', [$this, 'getType']),
23+
];
24+
}
25+
26+
public function getType(mixed $object): string
27+
{
28+
return $this->doGetType($object, true);
29+
}
30+
31+
public function getName(): string
32+
{
33+
return 'neo4j.result';
34+
}
35+
36+
private function doGetType(mixed $object, bool $recursive): string
37+
{
38+
if ($object instanceof Node) {
39+
return sprintf('%s: %s', $object->getId(), $object->getLabels()->join(', '));
40+
}
41+
42+
if (is_array($object) && $recursive) {
43+
if (empty($object)) {
44+
return 'Empty array';
45+
}
46+
$ret = [];
47+
foreach ($object as $o) {
48+
$ret[] = $this->doGetType($o, false);
49+
}
50+
51+
return sprintf('[%s]', implode(', ', $ret));
52+
}
53+
54+
return get_debug_type($object);
55+
}
56+
}

src/DependencyInjection/Neo4jExtension.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44

55
namespace Neo4j\Neo4jBundle\DependencyInjection;
66

7+
use Neo4j\Neo4jBundle\Collector\Neo4jDataCollector;
8+
use Neo4j\Neo4jBundle\EventListener\Neo4jProfileListener;
79
use Psr\Http\Client\ClientInterface;
810
use Psr\Http\Message\RequestFactoryInterface;
911
use Psr\Http\Message\StreamFactoryInterface;
1012
use Symfony\Component\Config\FileLocator;
1113
use Symfony\Component\DependencyInjection\ContainerBuilder;
1214
use Symfony\Component\DependencyInjection\ContainerInterface;
15+
use Symfony\Component\DependencyInjection\Definition;
1316
use Symfony\Component\DependencyInjection\Extension\Extension;
1417
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
1518
use Symfony\Component\DependencyInjection\Reference;
@@ -49,6 +52,20 @@ public function load(array $configs, ContainerBuilder $container): ContainerBuil
4952
}
5053
}
5154

55+
if (0 !== count($enabledProfiles)) {
56+
$container->setDefinition('neo4j.data_collector', (new Definition(Neo4jDataCollector::class))
57+
->setAutowired(true)
58+
->addTag('data_collector')
59+
);
60+
61+
$container->setAlias(Neo4jProfileListener::class, 'neo4j.subscriber');
62+
63+
$container->setDefinition('neo4j.subscriber', (new Definition(Neo4jProfileListener::class))
64+
->setArgument(0, $enabledProfiles)
65+
->addTag('kernel.event_subscriber')
66+
);
67+
}
68+
5269
return $container;
5370
}
5471

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Neo4j\Neo4jBundle\EventListener;
6+
7+
use Laudis\Neo4j\Databags\ResultSummary;
8+
use Laudis\Neo4j\Databags\Statement;
9+
use Laudis\Neo4j\Exception\Neo4jException;
10+
use Neo4j\Neo4jBundle\Event\FailureEvent;
11+
use Neo4j\Neo4jBundle\Event\PostRunEvent;
12+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
13+
use Symfony\Contracts\Service\ResetInterface;
14+
15+
final class Neo4jProfileListener implements EventSubscriberInterface, ResetInterface
16+
{
17+
/**
18+
* @var list<ResultSummary>
19+
*/
20+
private array $profiledSummaries = [];
21+
22+
/**
23+
* @var list<array{exception: Neo4jException, statement: Statement, alias: string|null}>
24+
*/
25+
private array $profiledFailures = [];
26+
27+
/**
28+
* @param list<string> $enabledProfiles
29+
*/
30+
public function __construct(private array $enabledProfiles = [])
31+
{
32+
}
33+
34+
public static function getSubscribedEvents(): array
35+
{
36+
return [
37+
PostRunEvent::EVENT_ID => 'onPostRun',
38+
FailureEvent::EVENT_ID => 'onFailure',
39+
];
40+
}
41+
42+
public function onPostRun(PostRunEvent $event): void
43+
{
44+
if (in_array($event->getAlias(), $this->enabledProfiles)) {
45+
$this->profiledSummaries[] = $event->getResult();
46+
}
47+
}
48+
49+
public function onFailure(FailureEvent $event): void
50+
{
51+
if (in_array($event->getAlias(), $this->enabledProfiles)) {
52+
$this->profiledFailures[] = [
53+
'exception' => $event->getException(),
54+
'statement' => $event->getStatement(),
55+
'alias' => $event->getAlias(),
56+
];
57+
}
58+
}
59+
60+
public function getProfiledSummaries(): array
61+
{
62+
return $this->profiledSummaries;
63+
}
64+
65+
/**
66+
* @return list<array{exception: Neo4jException, statement: Statement, alias: string|null}>
67+
*/
68+
public function getProfiledFailures(): array
69+
{
70+
return $this->profiledFailures;
71+
}
72+
73+
public function reset(): void
74+
{
75+
$this->profiledFailures = [];
76+
$this->profiledSummaries = [];
77+
}
78+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Neo4j\Neo4jBundle\Tests\Unit\Collector\Twig;
6+
7+
use Laudis\Neo4j\Types\CypherList;
8+
use Laudis\Neo4j\Types\CypherMap;
9+
use Laudis\Neo4j\Types\Node;
10+
use Neo4j\Neo4jBundle\Collector\Twig\Neo4jResultExtension;
11+
use PHPUnit\Framework\TestCase;
12+
13+
/**
14+
* @author Tobias Nyholm <[email protected]>
15+
*/
16+
class Neo4jResultExtensionTest extends TestCase
17+
{
18+
public function testEmptyArray(): void
19+
{
20+
$o = new Neo4jResultExtension();
21+
$result = $o->getType([]);
22+
23+
$this->assertEquals('Empty array', $result);
24+
}
25+
26+
public function testObject(): void
27+
{
28+
$o = new Neo4jResultExtension();
29+
$result = $o->getType($o);
30+
31+
$this->assertEquals(Neo4jResultExtension::class, $result);
32+
}
33+
34+
public function testScalar(): void
35+
{
36+
$o = new Neo4jResultExtension();
37+
$result = $o->getType(3);
38+
39+
$this->assertEquals('int', $result);
40+
}
41+
42+
public function testScalarArray(): void
43+
{
44+
$o = new Neo4jResultExtension();
45+
$result = $o->getType([3, 6.3]);
46+
47+
$this->assertEquals('[int, float]', $result);
48+
}
49+
50+
public function testArrayArray(): void
51+
{
52+
$o = new Neo4jResultExtension();
53+
$result = $o->getType([[]]);
54+
55+
$this->assertEquals('[array]', $result);
56+
}
57+
58+
public function testNode(): void
59+
{
60+
$o = new Neo4jResultExtension();
61+
$result = $o->getType(new Node(1, new CypherList(['Label']), new CypherMap(), null));
62+
63+
$this->assertEquals('1: Label', $result);
64+
}
65+
}

0 commit comments

Comments
 (0)