diff options
| author | Rob Hudson | 2008-09-18 13:44:15 -0700 | 
|---|---|---|
| committer | Rob Hudson | 2008-09-18 13:44:15 -0700 | 
| commit | 41a7cdbc553d3180f0e355a850bda61f0500d7c1 (patch) | |
| tree | cd6e669785619e8e34be897626901f2dbbd988f5 /debug_toolbar | |
| parent | e40b2c0fbdbd932be5f9d0550a16b6652de0d38d (diff) | |
| parent | 96ca83db5686f5b8983e7b008a698307130e58c9 (diff) | |
| download | django-debug-toolbar-41a7cdbc553d3180f0e355a850bda61f0500d7c1.tar.bz2 | |
Merge branch 'explain' of git@github.com:robhudson/django-debug-toolbar
Diffstat (limited to 'debug_toolbar')
| -rw-r--r-- | debug_toolbar/panels/sql.py | 21 | ||||
| -rw-r--r-- | debug_toolbar/templates/debug_toolbar/panels/sql.html | 4 | ||||
| -rw-r--r-- | debug_toolbar/templates/debug_toolbar/panels/sql_explain.html | 25 | ||||
| -rw-r--r-- | debug_toolbar/urls.py | 8 | ||||
| -rw-r--r-- | debug_toolbar/views.py | 31 | 
5 files changed, 74 insertions, 15 deletions
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index f23e317..757505a 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -1,3 +1,4 @@ +import simplejson  import time  from debug_toolbar.panels import DebugPanel  from django.db import connection @@ -20,7 +21,7 @@ class DatabaseStatTracker(util.CursorDebugWrapper):                  'sql': self.db.ops.last_executed_query(self.cursor, sql, params),                  'time': stop - start,                  'raw_sql': sql, -                'params': params, +                'params': simplejson.dumps(params),              })  util.CursorDebugWrapper = DatabaseStatTracker @@ -36,13 +37,6 @@ class SQLDebugPanel(DebugPanel):          self._offset = len(connection.queries)          self._sql_time = 0 -    def _reformat_sql(self, sql): -        sql = sql.replace('`,`', '`, `') -        sql = sql.replace('` FROM `', '` \n  FROM `') -        sql = sql.replace('` WHERE ', '` \n  WHERE ') -        sql = sql.replace(' ORDER BY ', ' \n  ORDER BY ') -        return sql -      def title(self):          self._sql_time = sum(map(lambda q: float(q['time']) * 1000, connection.queries))          return '%d SQL Queries (%.2fms)' % (len(connection.queries), self._sql_time) @@ -53,10 +47,19 @@ class SQLDebugPanel(DebugPanel):      def content(self):          sql_queries = connection.queries[self._offset:]          for query in sql_queries: -            query['sql'] = self._reformat_sql(query['sql']) +            query['sql'] = reformat_sql(query['sql'])          context = {              'queries': sql_queries,              'sql_time': self._sql_time,          }          return render_to_string('debug_toolbar/panels/sql.html', context) + +def reformat_sql(sql): +    sql = sql.replace('`,`', '`, `') +    sql = sql.replace('` FROM `', '` \n  FROM `') +    sql = sql.replace('` WHERE ', '` \n  WHERE ') +    sql = sql.replace('` INNER JOIN ', '` \n  INNER JOIN ') +    sql = sql.replace('` OUTER JOIN ', '` \n  OUTER JOIN ') +    sql = sql.replace(' ORDER BY ', ' \n  ORDER BY ') +    return sql diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html index 046be7f..246fa74 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html @@ -4,13 +4,15 @@  		<tr>  			<th>Time (ms)</th>  			<th>Query</th> +			<th>Action</th>  		</tr>  	</thead>  	<tbody>  		{% for query in queries %}  			<tr class="{% cycle 'row1' 'row2' %}">  				<td>{{ query.time|floatformat:"4" }}</td> -				<td><pre>{{ query.sql|escape }}</pre></td> +				<td><pre>{{ query.sql|wordwrap:80|escape }}</pre></td> +				<td><a href="/__debug__/sql_explain/?sql={{ query.raw_sql|urlencode }}¶ms={{ query.params|urlencode }}&time={{ query.time|floatformat:"4"|urlencode }}">EXPLAIN</a></td>  			</tr>  		{% endfor %}  	</tbody> diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html new file mode 100644 index 0000000..757d43f --- /dev/null +++ b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html @@ -0,0 +1,25 @@ +<h3>SQL Explained</h3> +<dl> +	<dt>Executed SQL</dt> +	<dd><pre>{{ sql|wordwrap:80 }}</pre></dd> +	<dt>Time</dt> +	<dd>{{ time }} ms</dd> +</dl> +<table> +	<thead> +		<tr> +			{% for h in headers %} +				<th>{{ h|upper }}</th> +			{% endfor %} +		</tr> +	</thead> +	<tbody> +		{% for row in result %} +			<tr class="{% cycle 'row1' 'row2' %}"> +				{% for column in row %} +					<td>{{ column|escape }}</td> +				{% endfor %} +			</tr> +		{% endfor %} +	</tbody> +</table> diff --git a/debug_toolbar/urls.py b/debug_toolbar/urls.py index 26a5ca2..e0e4b7a 100644 --- a/debug_toolbar/urls.py +++ b/debug_toolbar/urls.py @@ -4,10 +4,10 @@ URLpatterns for the debug toolbar.  These should not be loaded explicitly; the debug toolbar middleware will patch  this into the urlconf for the request.  """ -  from django.conf.urls.defaults import *  from django.conf import settings -urlpatterns = patterns('',  -    url('^__debug__/m/(.*)$', 'debug_toolbar.views.debug_media'), -)
\ No newline at end of file +urlpatterns = patterns('', +    url(r'^__debug__/m/(.*)$', 'debug_toolbar.views.debug_media'), +    url(r'^__debug__/sql_explain/$', 'debug_toolbar.views.sql_explain', name='sql_explain'), +) diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py index 40cc7b1..1b44ed1 100644 --- a/debug_toolbar/views.py +++ b/debug_toolbar/views.py @@ -5,12 +5,41 @@ views in any other way is generally not advised.  """  import os +import simplejson  import django.views.static  from django.conf import settings +from django.db import connection +from django.shortcuts import render_to_response  def debug_media(request, path):      root = getattr(settings, 'DEBUG_TOOLBAR_MEDIA_ROOT', None)      if root is None:          parent = os.path.abspath(os.path.dirname(__file__))          root = os.path.join(parent, 'media') -    return django.views.static.serve(request, path, root)
\ No newline at end of file +    return django.views.static.serve(request, path, root) + +def sql_explain(request): +    """ +    Returns the output of the SQL EXPLAIN on the given query. +     +    Expected GET variables: +        sql: urlencoded sql with position arguments +        params: JSON encoded parameter values +        time: time for SQL to execute passed in from toolbar just for redisplay +    """ +    from debug_toolbar.panels.sql import reformat_sql +    sql = request.GET.get('sql', '') +    if sql.lower().startswith('select'): +        params = simplejson.loads(request.GET.get('params', '')) +        cursor = connection.cursor() +        cursor.execute("EXPLAIN %s" % (sql,), params) +        headers = [d[0] for d in cursor.description] +        result = cursor.fetchall() +        cursor.close() +        context = { +            'result': result, +            'sql': reformat_sql(cursor.db.ops.last_executed_query(cursor, sql, params)), +            'time': request.GET.get('time', 0.0), +            'headers': headers, +        } +        return render_to_response('debug_toolbar/panels/sql_explain.html', context)  | 
