-from debug_toolbar.panels import DebugPanel
-from django.db import connection
-from django.db.backends import util
-from django.template.loader import render_to_string
-from django.shortcuts import render_to_response
-from django.http import HttpResponse
-from django.utils import simplejson
-from time import time
-
-class DatabaseStatTracker(util.CursorDebugWrapper):
- """Replacement for CursorDebugWrapper which stores additional information
- in `connection.queries`."""
- def execute(self, sql, params=()):
- start = time()
- try:
- return self.cursor.execute(sql, params)
- finally:
- stop = time()
- # We keep `sql` to maintain backwards compatibility
- self.db.queries.append({
- 'sql': self.db.ops.last_executed_query(self.cursor, sql, params),
- 'time': stop - start,
- 'raw_sql': sql,
- 'params': params,
- })
-
-util.CursorDebugWrapper = DatabaseStatTracker
-
-class SQLDebugPanel(DebugPanel):
- """
- Panel that displays information about the SQL queries run while processing the request.
- """
- name = 'SQL'
-
- def reformat_sql(self, sql):
- sql = sql.replace('`,`', '`, `')
- sql = sql.replace('` FROM `', '` \n FROM `')
- sql = sql.replace('` WHERE ', '` \n WHERE ')
- sql = sql.replace('`) WHERE ', '`) \n WHERE ')
- sql = sql.replace(' ORDER BY ', ' \n ORDER BY ')
- return sql
-
- def process_ajax(self, request):
- action = request.GET.get('op')
- if action == 'explain':
- # XXX: loop through each sql statement to output explain?
- sql = request.GET.get('sql', '').split(';')[0]
- if sql.lower().startswith('select'):
- if 'params' in request.GET:
- params = simplejson.loads(request.GET['params'])
- else:
- params = []
- cursor = connection.cursor()
- cursor.execute("EXPLAIN %s" % (sql,), params)
- response = cursor.fetchall()
- cursor.close()
- context = {'explain': response, 'sql': self.reformat_sql(sql), 'params': params}
- return render_to_response('debug_toolbar/panels/sql_explain.html', context)
- else:
- return HttpResponse('Invalid SQL', mimetype="text/plain", status_code=403)
-
- def process_request(self, request):
- self.queries_offset = len(connection.queries)
-
- def process_response(self, request, response):
- self.queries = connection.queries[self.queries_offset:]
- self.total_time = sum(map(lambda q: float(q['time'])*1000, self.queries))
- return response
-
- def title(self):
- return 'SQL: %.2fms (%d queries)' % (self.total_time, len(self.queries))
-
- def url(self):
- return ''
-
- def content(self):
- queries = [(q['time'], q['sql'], q['raw_sql'], simplejson.dumps(q['params'])) for q in sorted(self.queries, key=lambda x: x['time'])[::-1]]
- context = {'queries': queries}
- return render_to_string('debug_toolbar/panels/sql.html', context)
\ No newline at end of file