/
ProfilerController.php
104 lines (87 loc) · 3.29 KB
/
ProfilerController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?php
namespace Doctrine\Bundle\DoctrineBundle\Controller;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Profiler\Profiler;
use Symfony\Component\VarDumper\Cloner\Data;
/**
* ProfilerController.
*/
class ProfilerController implements ContainerAwareInterface
{
/** @var ContainerInterface */
private $container;
/**
* {@inheritDoc}
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* Renders the profiler panel for the given token.
*
* @param string $token The profiler token
* @param string $connectionName
* @param int $query
*
* @return Response A Response instance
*/
public function explainAction($token, $connectionName, $query)
{
/** @var Profiler $profiler */
$profiler = $this->container->get('profiler');
$profiler->disable();
$profile = $profiler->loadProfile($token);
$queries = $profile->getCollector('db')->getQueries();
if (! isset($queries[$connectionName][$query])) {
return new Response('This query does not exist.');
}
$query = $queries[$connectionName][$query];
if (! $query['explainable']) {
return new Response('This query cannot be explained.');
}
/** @var Connection $connection */
$connection = $this->container->get('doctrine')->getConnection($connectionName);
try {
if ($connection->getDatabasePlatform() instanceof SQLServerPlatform) {
$results = $this->explainSQLServerPlatform($connection, $query);
} else {
$results = $this->explainOtherPlatform($connection, $query);
}
} catch (\Exception $e) {
return new Response('This query cannot be explained.');
}
return new Response($this->container->get('twig')->render('@Doctrine/Collector/explain.html.twig', [
'data' => $results,
'query' => $query,
]));
}
private function explainSQLServerPlatform(Connection $connection, $query)
{
if (stripos($query['sql'], 'SELECT') === 0) {
$sql = 'SET STATISTICS PROFILE ON; ' . $query['sql'] . '; SET STATISTICS PROFILE OFF;';
} else {
$sql = 'SET SHOWPLAN_TEXT ON; GO; SET NOEXEC ON; ' . $query['sql'] . '; SET NOEXEC OFF; GO; SET SHOWPLAN_TEXT OFF;';
}
$params = $query['params'];
if ($params instanceof Data) {
$params = $params->getValue(true);
}
$stmt = $connection->executeQuery($sql, $params, $query['types']);
$stmt->nextRowset();
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
private function explainOtherPlatform(Connection $connection, $query)
{
$params = $query['params'];
if ($params instanceof Data) {
$params = $params->getValue(true);
}
return $connection->executeQuery('EXPLAIN ' . $query['sql'], $params, $query['types'])
->fetchAll(\PDO::FETCH_ASSOC);
}
}