/
mingorm.py
130 lines (104 loc) · 3.67 KB
/
mingorm.py
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import time
import inspect
from tg._compat import unicode_text
try:
import json
except:
import simplejson as json
import tg
from tg import config, request
from tg.i18n import ugettext as _
from tg.render import render
from tgext.debugbar.sections.base import DebugSection
from tgext.debugbar.utils import format_json
try:
from pymongo import json_util
except ImportError:
try:
from bson import json_util
except ImportError:
has_ming = False
try:
import ming
import ming.odm
from ming.odm.odmsession import SessionExtension
class TraceCursorExtension(SessionExtension):
def cursor_created(self, cursor, action, *args, **kw):
if action in ('find'):
cursor.tgdb_action = action
cursor.tgdb_class = inspect.isclass(
args[0]) and args[0].__name__ or args[0]
try:
cursor.tgdb_args = [[args[1], kw]]
except:
cursor.tgdb_args = [{}]
elif action in ('limit', 'sort', 'skip', 'hint'):
parent_cursor = args[0]
cursor.tgdb_action = parent_cursor.tgdb_action + '.' + action
cursor.tgdb_class = parent_cursor.tgdb_class
cursor.tgdb_args = parent_cursor.tgdb_args + [args[1:]]
def before_cursor_next(self, cursor):
cursor.tgdb_ming_timer = time.time()
def after_cursor_next(self, cursor):
spent = (time.time() - cursor.tgdb_ming_timer) * 1000
try:
req = request._current_obj()
except Exception:
req = None
if req is not None:
try:
active_cursors = req.tgdb_ming_cursors
except Exception:
active_cursors = req.tgdb_ming_cursors = {}
info = active_cursors.setdefault(id(cursor), {
'duration': 0,
'command': '',
'collection': '',
'params': ''})
info['duration'] += spent
if not hasattr(cursor, 'tgdb_action'):
return
info['command'] = cursor.tgdb_action
info['collection'] = cursor.tgdb_class
info['params'] = cursor.tgdb_args
has_ming = True
except ImportError:
has_ming = False
def hook_ming(*args, **kw):
global has_ming
if not has_ming:
return
try:
config['package'].model.DBSession.register_extension(
TraceCursorExtension)
except Exception:
has_ming = False
class MingDebugSection(DebugSection):
name = 'Ming'
hooks = dict(startup=[hook_ming])
@property
def is_active(self):
if not has_ming:
return False
return config.get('use_ming', False)
def title(self):
return _('Ming')
def content(self):
queries = getattr(request, 'tgdb_ming_cursors', [])
if not queries:
return 'No queries in executed by the controller.'
data = []
for query in queries.values():
params = json.dumps(query['params'], default=json_util.default)
data.append({
'duration': query['duration'],
'command': query['command'],
'collection': query['collection'],
'filter': format_json(params),
'params': params
})
delattr(request, 'tgdb_ming_cursors')
return unicode_text(render(
dict(queries=data, tg=tg),
config['debugbar.engine'], 'tgext.debugbar.sections.templates.ming!html'
).split('\n', 1)[-1])