Permalink
Browse files

Added a controller to explain the query

  • Loading branch information...
1 parent 77a3dc1 commit e987d4f48c8074ab123b348942d1e2501834592e @stof stof committed Jan 23, 2012
View
64 Controller/ProfilerController.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Doctrine Bundle
+ *
+ * The code was originally distributed inside the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ * (c) Doctrine Project, Benjamin Eberlei <kontakt@beberlei.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Doctrine\Bundle\DoctrineBundle\Controller;
+
+use Symfony\Component\DependencyInjection\ContainerAware;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * ProfilerController.
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ProfilerController extends ContainerAware
+{
+ /**
+ * Renders the profiler panel for the given token.
+ *
+ * @param string $token The profiler token
+ * @param string $connectionName
+ * @param integer $query
+ *
+ * @return Response A Response instance
+ */
+ public function explainAction($token, $connectionName, $query)
+ {
+ $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 \Doctrine\DBAL\Connection */
+ $connection = $this->container->get('doctrine')->getConnection($connectionName);
+ $results = $connection->executeQuery('EXPLAIN '.$query['sql'], $query['params'], $query['types'])
+ ->fetchAll(\PDO::FETCH_ASSOC);
+
+
+ return $this->container->get('templating')->renderResponse('DoctrineBundle:Collector:explain.html.twig', array(
+ 'data' => $results,
+ 'query' => $query,
+ ));
+ }
+}
View
16 Resources/views/Collector/db.html.twig
@@ -22,6 +22,19 @@
{% endblock %}
{% block panel %}
+ {% if app.request.query.has('connection') and app.request.query.has('query') %}
+ {% render 'DoctrineBundle:Profiler:explain' with {
+ 'token': token,
+ 'panel': 'db',
+ 'connectionName': app.request.query.get('connection'),
+ 'query': app.request.query.get('query')
+ } %}
+ {% else %}
+ {{ block('queries') }}
+ {% endif %}
+{% endblock %}
+
+{% block queries %}
<h2>Queries</h2>
{% for connection, queries in collector.queries %}
@@ -41,6 +54,9 @@
<strong>Parameters</strong>: {{ query.params|yaml_encode }}<br />
<strong>Time</strong>: {{ '%0.2f'|format(query.executionMS * 1000) }} ms
</small>
+ {% if query.explainable %}
+ <a href="{{ path('_profiler', {'panel': 'db', 'token': token, 'connection': connection, 'query': i}) }}">Explain the query</a>
+ {% endif %}
</li>
{% endfor %}
</ul>
View
26 Resources/views/Collector/explain.html.twig
@@ -0,0 +1,26 @@
+<h2>Original query</h2>
+
+<div>
+ <code>{{ query.sql }}</code>
+</div>
+<small>
+ <strong>Parameters</strong>: {{ query.params|yaml_encode }}<br />
+ <strong>Time</strong>: {{ '%0.2f'|format(query.executionMS * 1000) }} ms
+</small>
+
+<h2>Explanation</h2>
+
+<table>
+ <tr>
+ {% for label in data[0]|keys %}
+ <th>{{ label }}</th>
+ {% endfor %}
+ </tr>
+ {% for row in data %}
+ <tr>
+ {% for item in row %}
+ <td>{{ item }}</td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+</table>

0 comments on commit e987d4f

Please sign in to comment.