Skip to content
Browse files

Allow to show explain plans on each queries

  • Loading branch information...
1 parent 5552ebd commit 7188e19536961d70614483d240433cba8be50187 @cedriclombardot cedriclombardot committed Mar 16, 2012
View
41 Controller/PanelController.php
@@ -12,6 +12,7 @@
use Symfony\Bridge\Propel1\DataCollector\PropelDataCollector;
use Symfony\Component\DependencyInjection\ContainerAware;
+use Symfony\Component\HttpFoundation\Response;
/**
* PanelController is designed to display information in the Propel Panel.
@@ -39,4 +40,44 @@ public function configurationAction()
);
}
+ /**
+ * Renders the profiler panel for the given token.
+ *
+ * @param string $token The profiler token
+ * @param string $connection The connection name
+ * @param integer $query
+ *
+ * @return Response A Response instance
+ */
+ public function explainAction($token, $connection, $query)
+ {
+ $profiler = $this->container->get('profiler');
+ $profiler->disable();
+
+ $profile = $profiler->loadProfile($token);
+ $queries = $profile->getCollector('propel')->getQueries();
+
+ if (!isset($queries[$query])) {
+ return new Response('This query does not exist.');
+ }
+
+ // Open the connection
+ $con = \Propel::getConnection($connection);
+
+ // Get the adapter
+ $db = \Propel::getDB($connection);
+
+ try {
+ $stmt = $db->doExplainPlan($con, $queries[$query]['sql']);
+ $results = $stmt->fetchAll(\PDO::FETCH_ASSOC);
+ } catch (\Exception $e) {
+ return new Response('<div class="error">This query cannot be explained.</div>');
+ }
+
+ return $this->container->get('templating')->renderResponse('PropelBundle:Panel:explain.html.twig', array(
+ 'data' => $results,
+ 'query' => $query,
+ ));
+
+ }
}
View
1 PropelBundle.php
@@ -48,6 +48,7 @@ public function boot()
$config->setParameter('debugpdo.logging.details', array(
'time' => array('enabled' => true),
'mem' => array('enabled' => true),
+ 'connection' => array('enabled' => true),
));
\Propel::setLogger($this->container->get('propel.logger'));
View
37 Resources/views/Collector/propel.html.twig
@@ -41,6 +41,23 @@
font-size: 0.9em;
margin: 3px 0;
}
+
+ .SQLExplain {
+ margin: 5px;
+ }
+
+ .SQLExplain .error {
+ background-color: #F2DEDE;
+ border-color: #EED3D7;
+ color: #B94A48;
+ padding: 8px 35px 8px 14px;
+ font-weight: bold;
+ }
+
+ #content .SQLExplain h2 {
+ font-size: 17px;
+ margin-bottom: 0;
+ }
</style>
<h2>Queries</h2>
@@ -54,11 +71,27 @@
{% if not collector.querycount %}
<tr><td>No queries.</td></tr>
{% else %}
- {% for query in collector.queries %}
+ {% for i, query in collector.queries %}
<tr>
<td>
<code>{{ query.sql|format_sql }}</code>
- <div class="SQLInfo">Time: {{ query.time }} - Memory: {{ query.memory }}</div>
+ {% if app.request.query.has('query') and app.request.query.get('query') == i %}
+ <div class="SQLExplain">
+ {% render 'PropelBundle:Panel:explain' with {
+ 'token': token,
+ 'panel': 'propel',
+ 'query': app.request.query.get('query'),
+ 'connection': app.request.query.get('connection')
+ } %}
+ </div>
+ {% endif %}
+ <div class="SQLInfo">
+ Time: {{ query.time }} - Memory: {{ query.memory }} - Connection: {{ query.connection }}
+
+ {% if app.request.query.get('query', -1) != i %}
+ - <a href="{{ path('_profiler', {'panel': 'propel', 'token': token, 'connection': query.connection, 'query': i}) }}">Explain the query</a>
+ {% endif %}
+ </div>
</td>
</tr>
{% endfor %}
View
16 Resources/views/Panel/explain.html.twig
@@ -0,0 +1,16 @@
+<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 7188e19

Please sign in to comment.
Something went wrong with that request. Please try again.