Skip to content

Commit 687afd2

Browse files
author
jelte
committed
Convert Bundle & Bridge DataCollectors
1 parent e7bdab9 commit 687afd2

File tree

30 files changed

+845
-56
lines changed

30 files changed

+845
-56
lines changed

src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
* DoctrineDataCollector.
2323
*
2424
* @author Fabien Potencier <fabien@symfony.com>
25+
*
26+
* @deprecated since 2.8, to be removed in 3.0. Use Symfony\Bridge\Twig\Profiler\DoctrineDataCollector instead.
2527
*/
2628
class DoctrineDataCollector extends DataCollector
2729
{
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Profiler;
13+
14+
use Doctrine\Common\Persistence\ManagerRegistry;
15+
use Doctrine\DBAL\Logging\DebugStack;
16+
use Doctrine\DBAL\Types\Type;
17+
use Symfony\Component\Profiler\DataCollector\AbstractDataCollector;
18+
use Symfony\Component\Profiler\DataCollector\RuntimeDataCollectorInterface;
19+
20+
/**
21+
* DoctrineDataCollector.
22+
*
23+
* @author Fabien Potencier <fabien@symfony.com>
24+
*/
25+
class DoctrineDataCollector extends AbstractDataCollector implements RuntimeDataCollectorInterface
26+
{
27+
private $registry;
28+
private $connections;
29+
private $managers;
30+
private $loggers = array();
31+
32+
public function __construct(ManagerRegistry $registry)
33+
{
34+
$this->registry = $registry;
35+
$this->connections = $registry->getConnectionNames();
36+
$this->managers = $registry->getManagerNames();
37+
}
38+
39+
/**
40+
* Adds the stack logger for a connection.
41+
*
42+
* @param string $name
43+
* @param DebugStack $logger
44+
*/
45+
public function addLogger($name, DebugStack $logger)
46+
{
47+
$this->loggers[$name] = $logger;
48+
}
49+
50+
/**
51+
* {@inheritdoc}
52+
*/
53+
public function collect()
54+
{
55+
$queries = array();
56+
foreach ($this->loggers as $name => $logger) {
57+
$queries[$name] = $this->sanitizeQueries($name, $logger->queries);
58+
}
59+
60+
return new DoctrineProfileData($queries, $this->registry->getConnections(), $this->registry->getManagers());
61+
}
62+
63+
/**
64+
* {@inheritdoc}
65+
*/
66+
public function getName()
67+
{
68+
return 'db';
69+
}
70+
71+
private function sanitizeQueries($connectionName, $queries)
72+
{
73+
foreach ($queries as $i => $query) {
74+
$queries[$i] = $this->sanitizeQuery($connectionName, $query);
75+
}
76+
77+
return $queries;
78+
}
79+
80+
private function sanitizeQuery($connectionName, $query)
81+
{
82+
$query['explainable'] = true;
83+
if (!is_array($query['params'])) {
84+
$query['params'] = array($query['params']);
85+
}
86+
foreach ($query['params'] as $j => $param) {
87+
if (isset($query['types'][$j])) {
88+
// Transform the param according to the type
89+
$type = $query['types'][$j];
90+
if (is_string($type)) {
91+
$type = Type::getType($type);
92+
}
93+
if ($type instanceof Type) {
94+
$query['types'][$j] = $type->getBindingType();
95+
$param = $type->convertToDatabaseValue($param, $this->registry->getConnection($connectionName)->getDatabasePlatform());
96+
}
97+
}
98+
99+
list($query['params'][$j], $explainable) = $this->sanitizeParam($param);
100+
if (!$explainable) {
101+
$query['explainable'] = false;
102+
}
103+
}
104+
105+
return $query;
106+
}
107+
108+
/**
109+
* Sanitizes a param.
110+
*
111+
* The return value is an array with the sanitized value and a boolean
112+
* indicating if the original value was kept (allowing to use the sanitized
113+
* value to explain the query).
114+
*
115+
* @param mixed $var
116+
*
117+
* @return array
118+
*/
119+
private function sanitizeParam($var)
120+
{
121+
if (is_object($var)) {
122+
return array(sprintf('Object(%s)', get_class($var)), false);
123+
}
124+
125+
if (is_array($var)) {
126+
$a = array();
127+
$original = true;
128+
foreach ($var as $k => $v) {
129+
list($value, $orig) = $this->sanitizeParam($v);
130+
$original = $original && $orig;
131+
$a[$k] = $value;
132+
}
133+
134+
return array($a, $original);
135+
}
136+
137+
if (is_resource($var)) {
138+
return array(sprintf('Resource(%s)', get_resource_type($var)), false);
139+
}
140+
141+
return array($var, true);
142+
}
143+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Symfony\Bridge\Doctrine\Profiler;
4+
5+
use Symfony\Component\Profiler\ProfileData\ProfileDataInterface;
6+
7+
class DoctrineProfileData implements ProfileDataInterface
8+
{
9+
private $queries;
10+
private $connections;
11+
private $managers;
12+
13+
public function __construct(array $queries, array $connections, array $managers)
14+
{
15+
$this->queries = $queries;
16+
$this->connections = $connections;
17+
$this->managers = $managers;
18+
}
19+
20+
public function getManagers()
21+
{
22+
return $this->managers;
23+
}
24+
25+
public function getConnections()
26+
{
27+
return $this->connections;
28+
}
29+
30+
public function getQueryCount()
31+
{
32+
return array_sum(array_map('count', $this->queries));
33+
}
34+
35+
public function getQueries()
36+
{
37+
return $this->queries;
38+
}
39+
40+
public function getTime()
41+
{
42+
$time = 0;
43+
foreach ($this->queries as $queries) {
44+
foreach ($queries as $query) {
45+
$time += $query['executionMS'];
46+
}
47+
}
48+
49+
return $time;
50+
}
51+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\Profiler;
13+
14+
use Doctrine\DBAL\Platforms\MySqlPlatform;
15+
use Symfony\Bridge\Doctrine\Profiler\DoctrineDataCollector;
16+
17+
class DoctrineDataCollectorTest extends \PHPUnit_Framework_TestCase
18+
{
19+
public function testCollectConnections()
20+
{
21+
$c = $this->createCollector(array());
22+
$data = $c->collect();
23+
$this->assertEquals(array('default' => 'doctrine.dbal.default_connection'), $data->getConnections());
24+
}
25+
26+
public function testCollectManagers()
27+
{
28+
$c = $this->createCollector(array());
29+
$data = $c->collect();
30+
$this->assertEquals(array('default' => 'doctrine.orm.default_entity_manager'), $data->getManagers());
31+
}
32+
33+
public function testCollectQueryCount()
34+
{
35+
$c = $this->createCollector(array());
36+
$data = $c->collect();
37+
$this->assertEquals(0, $data->getQueryCount());
38+
39+
$queries = array(
40+
array('sql' => 'SELECT * FROM table1', 'params' => array(), 'types' => array(), 'executionMS' => 0),
41+
);
42+
$c = $this->createCollector($queries);
43+
$data = $c->collect();
44+
$this->assertEquals(1, $data->getQueryCount());
45+
}
46+
47+
public function testCollectTime()
48+
{
49+
$c = $this->createCollector(array());
50+
$data = $c->collect();
51+
$this->assertEquals(0, $data->getTime());
52+
53+
$queries = array(
54+
array('sql' => 'SELECT * FROM table1', 'params' => array(), 'types' => array(), 'executionMS' => 1),
55+
);
56+
$c = $this->createCollector($queries);
57+
$data = $c->collect();
58+
$this->assertEquals(1, $data->getTime());
59+
60+
$queries = array(
61+
array('sql' => 'SELECT * FROM table1', 'params' => array(), 'types' => array(), 'executionMS' => 1),
62+
array('sql' => 'SELECT * FROM table2', 'params' => array(), 'types' => array(), 'executionMS' => 2),
63+
);
64+
$c = $this->createCollector($queries);
65+
$data = $c->collect();
66+
$this->assertEquals(3, $data->getTime());
67+
}
68+
69+
/**
70+
* @dataProvider paramProvider
71+
*/
72+
public function testCollectQueries($param, $types, $expected, $explainable)
73+
{
74+
$queries = array(
75+
array('sql' => 'SELECT * FROM table1 WHERE field1 = ?1', 'params' => array($param), 'types' => $types, 'executionMS' => 1),
76+
);
77+
$c = $this->createCollector($queries);
78+
$data = $c->collect();
79+
80+
$collected_queries = $data->getQueries();
81+
$this->assertEquals($expected, $collected_queries['default'][0]['params'][0]);
82+
$this->assertEquals($explainable, $collected_queries['default'][0]['explainable']);
83+
}
84+
85+
/**
86+
* @dataProvider paramProvider
87+
*/
88+
public function testSerialization($param, $types, $expected, $explainable)
89+
{
90+
$queries = array(
91+
array('sql' => 'SELECT * FROM table1 WHERE field1 = ?1', 'params' => array($param), 'types' => $types, 'executionMS' => 1),
92+
);
93+
$c = $this->createCollector($queries);
94+
$data = $c->collect();
95+
$data = unserialize(serialize($data));
96+
97+
$collected_queries = $data->getQueries();
98+
$this->assertEquals($expected, $collected_queries['default'][0]['params'][0]);
99+
$this->assertEquals($explainable, $collected_queries['default'][0]['explainable']);
100+
}
101+
102+
public function paramProvider()
103+
{
104+
return array(
105+
array('some value', array(), 'some value', true),
106+
array(1, array(), 1, true),
107+
array(true, array(), true, true),
108+
array(null, array(), null, true),
109+
array(new \DateTime('2011-09-11'), array('date'), '2011-09-11', true),
110+
array(fopen(__FILE__, 'r'), array(), 'Resource(stream)', false),
111+
array(new \SplFileInfo(__FILE__), array(), 'Object(SplFileInfo)', false),
112+
);
113+
}
114+
115+
private function createCollector($queries)
116+
{
117+
$connection = $this->getMockBuilder('Doctrine\DBAL\Connection')
118+
->disableOriginalConstructor()
119+
->getMock();
120+
$connection->expects($this->any())
121+
->method('getDatabasePlatform')
122+
->will($this->returnValue(new MySqlPlatform()));
123+
124+
$registry = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry');
125+
$registry
126+
->expects($this->any())
127+
->method('getConnectionNames')
128+
->will($this->returnValue(array('default' => 'doctrine.dbal.default_connection')));
129+
$registry
130+
->expects($this->any())
131+
->method('getManagerNames')
132+
->will($this->returnValue(array('default' => 'doctrine.orm.default_entity_manager')));
133+
$registry->expects($this->any())
134+
->method('getConnection')
135+
->will($this->returnValue($connection));
136+
137+
$logger = $this->getMock('Doctrine\DBAL\Logging\DebugStack');
138+
$logger->queries = $queries;
139+
140+
$collector = new DoctrineDataCollector($registry);
141+
$collector->addLogger('default', $logger);
142+
143+
return $collector;
144+
}
145+
}

src/Symfony/Bridge/Twig/DataCollector/TwigDataCollector.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
* TwigDataCollector.
2121
*
2222
* @author Fabien Potencier <fabien@symfony.com>
23+
*
24+
* @deprecated since 2.8, to be removed in 3.0. Use Symfony\Bridge\Twig\Profiler\TwigDataCollector instead.
2325
*/
2426
class TwigDataCollector extends DataCollector implements LateDataCollectorInterface
2527
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy