def sql_select(request): """ Returns the output of the SQL SELECT statement. Expected GET variables: sql: urlencoded sql with positional arguments params: JSON encoded parameter values duration: time for SQL to execute passed in from toolbar just for redisplay hash: the hash of (secret + sql + params) for tamper checking """ from lib.debug_toolbar.panels.sql import reformat_sql sql = request.GET.get('sql', '') params = request.GET.get('params', '') alias = request.GET.get('alias', 'default') hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() if hash != request.GET.get('hash', ''): return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert if sql.lower().strip().startswith('select'): params = simplejson.loads(params) cursor = connections[alias].cursor() cursor.execute(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)), 'duration': request.GET.get('duration', 0.0), 'headers': headers, 'alias': alias, } return render_to_response('debug_toolbar/panels/sql_select.html', context) raise InvalidSQLError("Only 'select' queries are allowed.")
def sql_explain(request): """ Returns the output of the SQL EXPLAIN on the given query. Expected GET variables: sql: urlencoded sql with positional arguments params: JSON encoded parameter values duration: time for SQL to execute passed in from toolbar just for redisplay hash: the hash of (secret + sql + params) for tamper checking """ from lib.debug_toolbar.panels.sql import reformat_sql sql = request.GET.get('sql', '') params = request.GET.get('params', '') alias = request.GET.get('alias', 'default') hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() if hash != request.GET.get('hash', ''): return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert if sql.lower().strip().startswith('select'): params = simplejson.loads(params) cursor = connections[alias].cursor() conn = connections[alias].connection engine = conn.__class__.__module__.split('.', 1)[0] if engine == "sqlite3": # SQLite's EXPLAIN dumps the low-level opcodes generated for a query; # EXPLAIN QUERY PLAN dumps a more human-readable summary # See http://www.sqlite.org/lang_explain.html for details cursor.execute("EXPLAIN QUERY PLAN %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': reformat_sql(cursor.db.ops.last_executed_query(cursor, sql, params)), 'duration': request.GET.get('duration', 0.0), 'headers': headers, 'alias': alias, } return render_to_response('debug_toolbar/panels/sql_explain.html', context) raise InvalidSQLError("Only 'select' queries are allowed.")
def sql_profile(request): """ Returns the output of running the SQL and getting the profiling statistics. Expected GET variables: sql: urlencoded sql with positional arguments params: JSON encoded parameter values duration: time for SQL to execute passed in from toolbar just for redisplay hash: the hash of (secret + sql + params) for tamper checking """ from lib.debug_toolbar.panels.sql import reformat_sql sql = request.GET.get('sql', '') params = request.GET.get('params', '') alias = request.GET.get('alias', 'default') hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() if hash != request.GET.get('hash', ''): return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert if sql.lower().strip().startswith('select'): params = simplejson.loads(params) cursor = connections[alias].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: result_error = "Profiling is either not available or not supported by your database." cursor.close() context = { 'result': result, 'result_error': result_error, 'sql': reformat_sql(cursor.db.ops.last_executed_query(cursor, sql, params)), 'duration': request.GET.get('duration', 0.0), 'headers': headers, 'alias': alias, } return render_to_response('debug_toolbar/panels/sql_profile.html', context) raise InvalidSQLError("Only 'select' queries are allowed.")