From 4ef51f1c912d49c7650126398c4ac38fef0f795c Mon Sep 17 00:00:00 2001
From: Rob Hudson
Date: Thu, 11 Sep 2008 23:18:14 -0700
Subject: Moving reformat sql so we can pull this in elsewhere.
---
debug_toolbar/panels/sql.py | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py
index f23e317..8edfce9 100644
--- a/debug_toolbar/panels/sql.py
+++ b/debug_toolbar/panels/sql.py
@@ -36,13 +36,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 +46,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
--
cgit v1.2.3
From 8377ea179568c1fbf8f46db1234e85d689daae0a Mon Sep 17 00:00:00 2001
From: Rob Hudson
Date: Thu, 11 Sep 2008 23:19:27 -0700
Subject: Adding JSON params to pass to view and adding link for explain.
---
debug_toolbar/panels/sql.py | 3 ++-
debug_toolbar/templates/debug_toolbar/panels/sql.html | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py
index 8edfce9..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
diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html
index 046be7f..9a6638b 100644
--- a/debug_toolbar/templates/debug_toolbar/panels/sql.html
+++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html
@@ -4,13 +4,15 @@
| Time (ms) |
Query |
+ Action |
{% for query in queries %}
| {{ query.time|floatformat:"4" }} |
- {{ query.sql|escape }} |
+ {{ query.sql|wordwrap:80|escape }} |
+ EXPLAIN |
{% endfor %}
--
cgit v1.2.3
From 4591e34f0140c43e68e4ecd97eae7f3ea05878f6 Mon Sep 17 00:00:00 2001
From: Rob Hudson
Date: Thu, 11 Sep 2008 23:21:12 -0700
Subject: Adding view to explain SQL passed in via query string. Hopefully
this is database backend agnostic. Next up is connecting this with the SQL
panel via AJAX.
---
.../debug_toolbar/panels/sql_explain.html | 25 ++++++++++++++++++
debug_toolbar/urls.py | 6 +++++
debug_toolbar/views.py | 30 ++++++++++++++++++++++
3 files changed, 61 insertions(+)
create mode 100644 debug_toolbar/templates/debug_toolbar/panels/sql_explain.html
create mode 100644 debug_toolbar/urls.py
create mode 100644 debug_toolbar/views.py
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 @@
+SQL Explained
+
+ - Executed SQL
+ {{ sql|wordwrap:80 }}
+ - Time
+ - {{ time }} ms
+
+
+
+
+ {% for h in headers %}
+ | {{ h|upper }} |
+ {% endfor %}
+
+
+
+ {% for row in result %}
+
+ {% for column in row %}
+ | {{ column|escape }} |
+ {% endfor %}
+
+ {% endfor %}
+
+
diff --git a/debug_toolbar/urls.py b/debug_toolbar/urls.py
new file mode 100644
index 0000000..24d4b12
--- /dev/null
+++ b/debug_toolbar/urls.py
@@ -0,0 +1,6 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+ # EXPLAIN SQL via AJAX
+ url(r'explain/$', 'debug_toolbar.views.explain', name='explain_sql'),
+)
diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py
new file mode 100644
index 0000000..5bdf450
--- /dev/null
+++ b/debug_toolbar/views.py
@@ -0,0 +1,30 @@
+import simplejson
+from django.db import connection
+from django.shortcuts import render_to_response
+from debug_toolbar.panels.sql import reformat_sql
+
+def 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
+ """
+ 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)
+
\ No newline at end of file
--
cgit v1.2.3
From 43bb25c874f765800076285e76b2b0ba1460a597 Mon Sep 17 00:00:00 2001
From: Nowell Strite
Date: Fri, 19 Sep 2008 01:17:16 -0400
Subject: Fixed template panel to skip over debug_toolbar templates. Fixed a
bug in template context output where rendering would hang while trying to
autoescape the context variable output.
---
debug_toolbar/panels/template.py | 3 +++
debug_toolbar/templates/debug_toolbar/panels/templates.html | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/debug_toolbar/panels/template.py b/debug_toolbar/panels/template.py
index f02b673..bda6630 100644
--- a/debug_toolbar/panels/template.py
+++ b/debug_toolbar/panels/template.py
@@ -50,6 +50,9 @@ class TemplateDebugPanel(DebugPanel):
info = {}
# Clean up some info about templates
t = d.get('template', None)
+ # Skip templates that we are generating through the debug toolbar.
+ if t.name.startswith('debug_toolbar/'):
+ continue
if t.origin and t.origin.name:
t.origin_name = t.origin.name
else:
diff --git a/debug_toolbar/templates/debug_toolbar/panels/templates.html b/debug_toolbar/templates/debug_toolbar/panels/templates.html
index ee93708..0c47c5c 100644
--- a/debug_toolbar/templates/debug_toolbar/panels/templates.html
+++ b/debug_toolbar/templates/debug_toolbar/panels/templates.html
@@ -16,7 +16,7 @@
{{ template.template.origin_name|addslashes }}
-
+ {{ template.context|safe }}
{% endfor %}
--
cgit v1.2.3
From 5a711759e75bfef4788498d9cfaa9fe019bcd15d Mon Sep 17 00:00:00 2001
From: Rob Hudson
Date: Fri, 19 Sep 2008 10:47:16 -0700
Subject: Remove the safe filter from template context so objects don't turn
into HTML tags (e.g. )
---
debug_toolbar/templates/debug_toolbar/panels/templates.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/debug_toolbar/templates/debug_toolbar/panels/templates.html b/debug_toolbar/templates/debug_toolbar/panels/templates.html
index 0c47c5c..575d507 100644
--- a/debug_toolbar/templates/debug_toolbar/panels/templates.html
+++ b/debug_toolbar/templates/debug_toolbar/panels/templates.html
@@ -16,10 +16,10 @@
{{ template.template.origin_name|addslashes }}
- {{ template.context|safe }}
+
{% endfor %}
{% else %}
None
-{% endif %}
\ No newline at end of file
+{% endif %}
--
cgit v1.2.3