Skip to content

Commit 3fb2745

Browse files
committed
WIP
1 parent 54ff730 commit 3fb2745

File tree

20 files changed

+208
-44
lines changed

20 files changed

+208
-44
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ package-lock.json: package.json
2929
touch $@
3030

3131
test:
32-
DJANGO_SETTINGS_MODULE=tests.settings \
32+
DB_BACKEND=sqlite3 DB_NAME=":memory:" DJANGO_SETTINGS_MODULE=tests.settings \
3333
python -m django test $${TEST_ARGS:-tests}
3434

3535
test_selenium:

debug_toolbar/db_store.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from debug_toolbar import store
2+
from debug_toolbar.models import PanelStore, ToolbarStore
3+
4+
5+
class DBStore(store.BaseStore):
6+
@classmethod
7+
def ids(cls):
8+
return (
9+
ToolbarStore.objects.using("debug_toolbar")
10+
.values_list("key", flat=True)
11+
.order_by("created")
12+
)
13+
14+
@classmethod
15+
def exists(cls, store_id):
16+
return ToolbarStore.objects.using("debug_toolbar").filter(key=store_id).exists()
17+
18+
@classmethod
19+
def set(cls, store_id):
20+
_, created = ToolbarStore.objects.using("debug_toolbar").get_or_create(
21+
key=store_id
22+
)
23+
if (
24+
created
25+
and ToolbarStore.objects.using("debug_toolbar").all().count()
26+
> cls.config["RESULTS_CACHE_SIZE"]
27+
):
28+
ToolbarStore.objects.using("debug_toolbar").earliest("created").delete()
29+
30+
@classmethod
31+
def delete(cls, store_id):
32+
ToolbarStore.objects.using("debug_toolbar").filter(key=store_id).delete()
33+
34+
@classmethod
35+
def save_panel(cls, store_id, panel_id, stats=None):
36+
toolbar, _ = ToolbarStore.objects.using("debug_toolbar").get_or_create(
37+
key=store_id
38+
)
39+
toolbar.panelstore_set.update_or_create(
40+
panel=panel_id, defaults={"data": store.serialize(stats)}
41+
)
42+
43+
@classmethod
44+
def panel(cls, store_id, panel_id):
45+
panel = (
46+
PanelStore.objects.using("debug_toolbar")
47+
.filter(toolbar__key=store_id, panel=panel_id)
48+
.first()
49+
)
50+
return {} if not panel else store.deserialize(panel.data)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Generated by Django 3.1.5 on 2021-01-09 17:02
2+
import django.db.models.deletion
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
initial = True
8+
9+
dependencies = []
10+
11+
operations = [
12+
migrations.CreateModel(
13+
name="ToolbarStore",
14+
fields=[
15+
(
16+
"id",
17+
models.AutoField(
18+
auto_created=True,
19+
primary_key=True,
20+
serialize=False,
21+
verbose_name="ID",
22+
),
23+
),
24+
("created", models.DateTimeField(auto_now_add=True)),
25+
("key", models.CharField(max_length=64, unique=True)),
26+
],
27+
),
28+
migrations.CreateModel(
29+
name="PanelStore",
30+
fields=[
31+
(
32+
"id",
33+
models.AutoField(
34+
auto_created=True,
35+
primary_key=True,
36+
serialize=False,
37+
verbose_name="ID",
38+
),
39+
),
40+
("created", models.DateTimeField(auto_now_add=True)),
41+
("panel", models.CharField(max_length=128)),
42+
("data", models.TextField()),
43+
(
44+
"toolbar",
45+
models.ForeignKey(
46+
on_delete=django.db.models.deletion.CASCADE,
47+
to="debug_toolbar.toolbarstore",
48+
),
49+
),
50+
],
51+
),
52+
migrations.AddConstraint(
53+
model_name="panelstore",
54+
constraint=models.UniqueConstraint(
55+
fields=("toolbar", "panel"), name="unique_toolbar_panel"
56+
),
57+
),
58+
]

debug_toolbar/migrations/__init__.py

Whitespace-only changes.

debug_toolbar/models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from django.db import models
2+
3+
4+
class ToolbarStore(models.Model):
5+
created = models.DateTimeField(auto_now_add=True)
6+
key = models.CharField(max_length=64, unique=True)
7+
8+
9+
class PanelStore(models.Model):
10+
created = models.DateTimeField(auto_now_add=True)
11+
toolbar = models.ForeignKey(ToolbarStore, on_delete=models.CASCADE)
12+
panel = models.CharField(max_length=128)
13+
data = models.TextField()

debug_toolbar/panels/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.template.loader import render_to_string
22

33
from debug_toolbar import settings as dt_settings
4-
from debug_toolbar.store import store
4+
from debug_toolbar.store import get_store
55
from debug_toolbar.utils import get_name_from_obj
66

77

@@ -44,7 +44,7 @@ def enabled(self):
4444
== "on"
4545
)
4646
else:
47-
return bool(store.panel(self.toolbar.store_id, self.panel_id))
47+
return bool(get_store().panel(self.toolbar.store_id, self.panel_id))
4848

4949
# Titles and content
5050

@@ -182,15 +182,17 @@ def record_stats(self, stats):
182182
Each call to ``record_stats`` updates the statistics dictionary.
183183
"""
184184
self.toolbar.stats.setdefault(self.panel_id, {}).update(stats)
185-
store.save_panel(
185+
get_store().save_panel(
186186
self.toolbar.store_id, self.panel_id, self.serialize_stats(stats)
187187
)
188188

189189
def get_stats(self):
190190
"""
191191
Access data stored by the panel. Returns a :class:`dict`.
192192
"""
193-
return self.deserialize_stats(store.panel(self.toolbar.store_id, self.panel_id))
193+
return self.deserialize_stats(
194+
get_store().panel(self.toolbar.store_id, self.panel_id)
195+
)
194196

195197
def record_server_timing(self, key, title, value):
196198
"""

debug_toolbar/panels/cache.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,14 +246,15 @@ def _store_call_info(
246246

247247
@property
248248
def nav_subtitle(self):
249-
cache_calls = len(self.calls)
249+
stats = self.get_stats()
250+
cache_calls = len(stats["calls"])
250251
return (
251252
ngettext(
252253
"%(cache_calls)d call in %(time).2fms",
253254
"%(cache_calls)d calls in %(time).2fms",
254255
cache_calls,
255256
)
256-
% {"cache_calls": cache_calls, "time": self.total_time}
257+
% {"cache_calls": cache_calls, "time": stats["total_time"]}
257258
)
258259

259260
@property

debug_toolbar/panels/history/panel.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from debug_toolbar.panels import Panel
1313
from debug_toolbar.panels.history import views
1414
from debug_toolbar.panels.history.forms import HistoryStoreForm
15-
from debug_toolbar.store import store
15+
from debug_toolbar.store import get_store
1616

1717

1818
class HistoryPanel(Panel):
@@ -82,13 +82,15 @@ def content(self):
8282
Fetch every store for the toolbar and include it in the template.
8383
"""
8484
histories = OrderedDict()
85-
for id in reversed(store.ids()):
86-
histories[id] = {
87-
"stats": self.deserialize_stats(store.panel(id, self.panel_id)),
88-
"form": SignedDataForm(
89-
initial=HistoryStoreForm(initial={"store_id": id}).initial
90-
),
91-
}
85+
for id in reversed(get_store().ids()):
86+
stats = self.deserialize_stats(get_store().panel(id, self.panel_id))
87+
if stats:
88+
histories[id] = {
89+
"stats": stats,
90+
"form": SignedDataForm(
91+
initial=HistoryStoreForm(initial={"store_id": str(id)}).initial
92+
),
93+
}
9294

9395
return render_to_string(
9496
self.template,

debug_toolbar/panels/history/views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from debug_toolbar.decorators import require_show_toolbar, signed_data_view
55
from debug_toolbar.forms import SignedDataForm
66
from debug_toolbar.panels.history.forms import HistoryStoreForm
7-
from debug_toolbar.store import store
7+
from debug_toolbar.store import get_store
88
from debug_toolbar.toolbar import stats_only_toolbar
99

1010

@@ -48,7 +48,7 @@ def history_refresh(request, verified_data):
4848

4949
if form.is_valid():
5050
requests = []
51-
for id in reversed(store.ids()):
51+
for id in reversed(get_store().ids()):
5252
toolbar = stats_only_toolbar(id)
5353
requests.append(
5454
{

debug_toolbar/panels/sql/panel.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,20 @@ def record(self, alias, **kwargs):
110110

111111
@property
112112
def nav_subtitle(self):
113+
stats = self.get_stats()
114+
num_queries = len(stats["queries"])
113115
return ngettext(
114116
"%(query_count)d query in %(sql_time).2fms",
115117
"%(query_count)d queries in %(sql_time).2fms",
116-
self._num_queries,
118+
num_queries,
117119
) % {
118-
"query_count": self._num_queries,
119-
"sql_time": self._sql_time,
120+
"query_count": num_queries,
121+
"sql_time": stats["sql_time"],
120122
}
121123

122124
@property
123125
def title(self):
124-
count = len(self._databases)
126+
count = len(self.get_stats()["databases"])
125127
return (
126128
ngettext(
127129
"SQL queries from %(count)d connection",
@@ -144,10 +146,14 @@ def get_urls(cls):
144146
def enable_instrumentation(self):
145147
# This is thread-safe because database connections are thread-local.
146148
for connection in connections.all():
149+
if connection.alias == "debug_toolbar":
150+
continue
147151
wrap_cursor(connection, self)
148152

149153
def disable_instrumentation(self):
150154
for connection in connections.all():
155+
if connection.alias == "debug_toolbar":
156+
continue
151157
unwrap_cursor(connection)
152158

153159
def generate_stats(self, request, response):

0 commit comments

Comments
 (0)