aboutsummaryrefslogtreecommitdiffstats
path: root/debug_toolbar
diff options
context:
space:
mode:
Diffstat (limited to 'debug_toolbar')
-rw-r--r--debug_toolbar/urls.py5
-rw-r--r--debug_toolbar/utils/tracking/db.py41
-rw-r--r--debug_toolbar/views.py16
3 files changed, 46 insertions, 16 deletions
diff --git a/debug_toolbar/urls.py b/debug_toolbar/urls.py
index 1446d99..0053ae7 100644
--- a/debug_toolbar/urls.py
+++ b/debug_toolbar/urls.py
@@ -4,7 +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 *
+try:
+ from django.conf.urls import patterns, url
+except ImportError: # django < 1.4
+ from django.conf.urls.defaults import patterns, url
_PREFIX = '__debug__'
diff --git a/debug_toolbar/utils/tracking/db.py b/debug_toolbar/utils/tracking/db.py
index 0dc22a6..0ff3359 100644
--- a/debug_toolbar/utils/tracking/db.py
+++ b/debug_toolbar/utils/tracking/db.py
@@ -5,7 +5,6 @@ from threading import local
from django.conf import settings
from django.template import Node
-from django.utils import simplejson
from django.utils.encoding import force_unicode, smart_str
from debug_toolbar.utils import ms_from_timedelta, tidy_stacktrace, \
@@ -13,8 +12,13 @@ from debug_toolbar.utils import ms_from_timedelta, tidy_stacktrace, \
from debug_toolbar.utils.compat.db import connections
try:
+ import json
+except ImportError: # python < 2.6
+ from django.utils import simplejson as json
+
+try:
from hashlib import sha1
-except ImportError:
+except ImportError: # python < 2.5
from django.utils.hashcompat import sha_constructor as sha1
# TODO:This should be set in the toolbar loader as a default and panels should
@@ -87,12 +91,25 @@ class NormalCursorWrapper(object):
for key, value in params.iteritems())
return map(self._quote_expr, params)
+ def _decode(self, param):
+ try:
+ return force_unicode(param, strings_only=True)
+ except UnicodeDecodeError:
+ return '(encoded string)'
+
def execute(self, sql, params=()):
- __traceback_hide__ = True
start = datetime.now()
try:
return self.cursor.execute(sql, params)
finally:
+ # FIXME: Sometimes connections which are not in the connections
+ # dict are used (for example in test database destroying).
+ # The code below (at least get_transaction_id(alias) needs to have
+ # the connection in the connections dict. It would be good to
+ # not have this requirement at all, but for now lets just skip
+ # these connections.
+ if self.db.alias not in connections:
+ return
stop = datetime.now()
duration = ms_from_timedelta(stop - start)
enable_stacktraces = getattr(settings,
@@ -103,10 +120,8 @@ class NormalCursorWrapper(object):
stacktrace = []
_params = ''
try:
- _params = simplejson.dumps(
- [force_unicode(x, strings_only=True) for x in params]
- )
- except TypeError:
+ _params = json.dumps(map(self._decode, params))
+ except Exception:
pass # object not JSON serializable
template_info = None
@@ -124,7 +139,7 @@ class NormalCursorWrapper(object):
del cur_frame
alias = getattr(self.db, 'alias', 'default')
- conn = connections[alias].connection
+ conn = self.db.connection
# HACK: avoid imports
if conn:
engine = conn.__class__.__module__.split('.', 1)[0]
@@ -151,11 +166,17 @@ class NormalCursorWrapper(object):
}
if engine == 'psycopg2':
- from psycopg2.extensions import TRANSACTION_STATUS_INERROR
+ # If an erroneous query was ran on the connection, it might
+ # be in a state where checking isolation_level raises an
+ # exception.
+ try:
+ iso_level = conn.isolation_level
+ except conn.InternalError:
+ iso_level = 'unknown'
params.update({
'trans_id': self.logger.get_transaction_id(alias),
'trans_status': conn.get_transaction_status(),
- 'iso_level': conn.isolation_level if not conn.get_transaction_status() == TRANSACTION_STATUS_INERROR else "",
+ 'iso_level': iso_level,
'encoding': conn.encoding,
})
diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py
index a642541..4b4ebc9 100644
--- a/debug_toolbar/views.py
+++ b/debug_toolbar/views.py
@@ -9,13 +9,17 @@ import django.views.static
from django.conf import settings
from django.http import HttpResponseBadRequest
from django.shortcuts import render_to_response
-from django.utils import simplejson
from debug_toolbar.utils.compat.db import connections
try:
+ import json
+except ImportError: # python < 2.6
+ from django.utils import simplejson as json
+
+try:
from hashlib import sha1
-except ImportError:
+except ImportError: # python < 2.5
from django.utils.hashcompat import sha_constructor as sha1
@@ -45,7 +49,7 @@ def sql_select(request):
if hash != request.GET.get('hash', ''):
return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert
if sql.lower().strip().startswith('select'):
- params = simplejson.loads(params)
+ params = json.loads(params)
cursor = connections[alias].cursor()
cursor.execute(sql, params)
headers = [d[0] for d in cursor.description]
@@ -80,7 +84,7 @@ def sql_explain(request):
if hash != request.GET.get('hash', ''):
return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert
if sql.lower().strip().startswith('select'):
- params = simplejson.loads(params)
+ params = json.loads(params)
cursor = connections[alias].cursor()
conn = connections[alias].connection
@@ -91,6 +95,8 @@ def sql_explain(request):
# 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)
+ elif engine == "psycopg2":
+ cursor.execute("EXPLAIN ANALYZE %s" % (sql,), params)
else:
cursor.execute("EXPLAIN %s" % (sql,), params)
@@ -126,7 +132,7 @@ def sql_profile(request):
if hash != request.GET.get('hash', ''):
return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert
if sql.lower().strip().startswith('select'):
- params = simplejson.loads(params)
+ params = json.loads(params)
cursor = connections[alias].cursor()
result = None
headers = None