123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- from __future__ import absolute_import, unicode_literals
-
- from django.http import HttpResponseBadRequest
- from django.template.response import SimpleTemplateResponse
- from django.views.decorators.csrf import csrf_exempt
-
- from debug_toolbar.decorators import require_show_toolbar
- from debug_toolbar.panels.sql.forms import SQLSelectForm
-
-
- @csrf_exempt
- @require_show_toolbar
- def sql_select(request):
- """Returns the output of the SQL SELECT statement"""
- form = SQLSelectForm(request.POST or None)
-
- if form.is_valid():
- sql = form.cleaned_data['raw_sql']
- params = form.cleaned_data['params']
- cursor = form.cursor
- cursor.execute(sql, params)
- headers = [d[0] for d in cursor.description]
- result = cursor.fetchall()
- cursor.close()
- context = {
- 'result': result,
- 'sql': form.reformat_sql(),
- 'duration': form.cleaned_data['duration'],
- 'headers': headers,
- 'alias': form.cleaned_data['alias'],
- }
- # Using SimpleTemplateResponse avoids running global context processors.
- return SimpleTemplateResponse('debug_toolbar/panels/sql_select.html', context)
- return HttpResponseBadRequest('Form errors')
-
-
- @csrf_exempt
- @require_show_toolbar
- def sql_explain(request):
- """Returns the output of the SQL EXPLAIN on the given query"""
- form = SQLSelectForm(request.POST or None)
-
- if form.is_valid():
- sql = form.cleaned_data['raw_sql']
- params = form.cleaned_data['params']
- vendor = form.connection.vendor
- cursor = form.cursor
-
- if vendor == 'sqlite':
- # SQLite's EXPLAIN dumps the low-level opcodes generated for a query;
- # EXPLAIN QUERY PLAN dumps a more human-readable summary
- # See https://www.sqlite.org/lang_explain.html for details
- cursor.execute("EXPLAIN QUERY PLAN %s" % (sql,), params)
- elif vendor == 'postgresql':
- cursor.execute("EXPLAIN ANALYZE %s" % (sql,), params)
- else:
- cursor.execute("EXPLAIN %s" % (sql,), params)
-
- headers = [d[0] for d in cursor.description]
- result = cursor.fetchall()
- cursor.close()
- context = {
- 'result': result,
- 'sql': form.reformat_sql(),
- 'duration': form.cleaned_data['duration'],
- 'headers': headers,
- 'alias': form.cleaned_data['alias'],
- }
- # Using SimpleTemplateResponse avoids running global context processors.
- return SimpleTemplateResponse('debug_toolbar/panels/sql_explain.html', context)
- return HttpResponseBadRequest('Form errors')
-
-
- @csrf_exempt
- @require_show_toolbar
- def sql_profile(request):
- """Returns the output of running the SQL and getting the profiling statistics"""
- form = SQLSelectForm(request.POST or None)
-
- if form.is_valid():
- sql = form.cleaned_data['raw_sql']
- params = form.cleaned_data['params']
- cursor = form.cursor
- result = None
- headers = None
- result_error = None
- try:
- cursor.execute("SET PROFILING=1") # Enable profiling
- cursor.execute(sql, params) # Execute SELECT
- cursor.execute("SET PROFILING=0") # Disable profiling
- # The Query ID should always be 1 here but I'll subselect to get
- # the last one just in case...
- cursor.execute("""
- SELECT *
- FROM information_schema.profiling
- WHERE query_id = (
- SELECT query_id
- FROM information_schema.profiling
- ORDER BY query_id DESC
- LIMIT 1
- )
- """)
- headers = [d[0] for d in cursor.description]
- result = cursor.fetchall()
- except Exception:
- result_error = "Profiling is either not available or not supported by your database."
- cursor.close()
- context = {
- 'result': result,
- 'result_error': result_error,
- 'sql': form.reformat_sql(),
- 'duration': form.cleaned_data['duration'],
- 'headers': headers,
- 'alias': form.cleaned_data['alias'],
- }
- # Using SimpleTemplateResponse avoids running global context processors.
- return SimpleTemplateResponse('debug_toolbar/panels/sql_profile.html', context)
- return HttpResponseBadRequest('Form errors')
|