1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
import re
from functools import lru_cache
import sqlparse
from django.utils.html import escape
from sqlparse import tokens as T
from debug_toolbar import settings as dt_settings
class BoldKeywordFilter:
"""sqlparse filter to bold SQL keywords"""
def process(self, stream):
"""Process the token stream"""
for token_type, value in stream:
is_keyword = token_type in T.Keyword
if is_keyword:
yield T.Text, "<strong>"
yield token_type, escape(value)
if is_keyword:
yield T.Text, "</strong>"
def reformat_sql(sql, with_toggle=False):
formatted = parse_sql(sql, aligned_indent=True)
if not with_toggle:
return formatted
simple = simplify(parse_sql(sql, aligned_indent=False))
uncollapsed = f'<span class="djDebugUncollapsed">{simple}</span>'
collapsed = f'<span class="djDebugCollapsed djdt-hidden">{formatted}</span>'
return collapsed + uncollapsed
def parse_sql(sql, aligned_indent=False):
return _parse_sql(
sql,
dt_settings.get_config()["PRETTIFY_SQL"],
aligned_indent,
)
@lru_cache(maxsize=128)
def _parse_sql(sql, pretty, aligned_indent):
stack = get_filter_stack(pretty, aligned_indent)
return "".join(stack.run(sql))
@lru_cache(maxsize=None)
def get_filter_stack(prettify, aligned_indent):
stack = sqlparse.engine.FilterStack()
if prettify:
stack.enable_grouping()
if aligned_indent:
stack.stmtprocess.append(
sqlparse.filters.AlignedIndentFilter(char=" ", n="<br/>")
)
stack.preprocess.append(BoldKeywordFilter()) # add our custom filter
stack.postprocess.append(sqlparse.filters.SerializerUnicode()) # tokens -> strings
return stack
simplify_re = re.compile(r"SELECT</strong> (...........*?) <strong>FROM")
def simplify(sql):
return simplify_re.sub(r"SELECT</strong> ••• <strong>FROM", sql)
def contrasting_color_generator():
"""
Generate contrasting colors by varying most significant bit of RGB first,
and then vary subsequent bits systematically.
"""
def rgb_to_hex(rgb):
return "#%02x%02x%02x" % tuple(rgb)
triples = [
(1, 0, 0),
(0, 1, 0),
(0, 0, 1),
(1, 1, 0),
(0, 1, 1),
(1, 0, 1),
(1, 1, 1),
]
n = 1 << 7
so_far = [[0, 0, 0]]
while True:
if n == 0: # This happens after 2**24 colours; presumably, never
yield "#000000" # black
copy_so_far = list(so_far)
for triple in triples:
for previous in copy_so_far:
rgb = [n * triple[i] + previous[i] for i in range(3)]
so_far.append(rgb)
yield rgb_to_hex(rgb)
n >>= 1
|