Skip to content

Commit aaffa30

Browse files
author
Gordon B. McMillan
committed
Fix the cycles (a clear method, called after render...
...that removes the bound methods from the globals dict). Use cl.filter instead of cl.list followed by sortfunc. For some backends (Metakit), filter can sort at C speeds, cutting >10 secs off of filling in the <select...> box for assigned_to when you have 600+ users.
1 parent 5d68ca2 commit aaffa30

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

roundup/htmltemplate.py

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: htmltemplate.py,v 1.93 2002-06-27 12:05:25 gmcm Exp $
18+
# $Id: htmltemplate.py,v 1.94 2002-06-27 15:38:53 gmcm Exp $
1919

2020
__doc__ = """
2121
Template engine.
2222
"""
2323

2424
import os, re, StringIO, urllib, cgi, errno, types, urllib
25-
2625
import hyperdb, date
2726
from i18n import _
2827

@@ -60,6 +59,11 @@ def __init__(self):
6059
self.cl = None
6160
self.properties = None
6261

62+
def clear(self):
63+
for key in TemplateFunctions.__dict__.keys():
64+
if key[:3] == 'do_':
65+
del self.globals[key[3:]]
66+
6367
def do_plain(self, property, escape=0, lookup=1):
6468
''' display a String property directly;
6569
@@ -199,10 +203,12 @@ def do_field(self, property, size=None, showid=0):
199203
elif isinstance(propclass, hyperdb.Password):
200204
s = '<input type="password" name="%s" size="%s">'%(property, size)
201205
elif isinstance(propclass, hyperdb.Link):
202-
sortfunc = self.make_sort_function(propclass.classname)
203206
linkcl = self.db.classes[propclass.classname]
204-
options = linkcl.list()
205-
options.sort(sortfunc)
207+
if linkcl.getprops().has_key('order'):
208+
sort_on = 'order'
209+
else:
210+
sort_on = linkcl.labelprop()
211+
options = linkcl.filter(None, {}, [sort_on], [])
206212
# TODO: make this a field display, not a menu one!
207213
l = ['<select name="%s">'%property]
208214
k = linkcl.labelprop(1)
@@ -289,8 +295,11 @@ def do_menu(self, property, size=None, height=None, showid=0,
289295
# display
290296
if isinstance(propclass, hyperdb.Multilink):
291297
linkcl = self.db.classes[propclass.classname]
292-
options = linkcl.list()
293-
options.sort(sortfunc)
298+
if linkcl.getprops().has_key('order'):
299+
sort_on = 'order'
300+
else:
301+
sort_on = linkcl.labelprop()
302+
options = linkcl.filter(None, {}, [sort_on], [])
294303
height = height or min(len(options), 7)
295304
l = ['<select multiple name="%s" size="%s">'%(property, height)]
296305
k = linkcl.labelprop(1)
@@ -326,8 +335,11 @@ def do_menu(self, property, size=None, height=None, showid=0,
326335
if value is None:
327336
s = 'selected '
328337
l.append(_('<option %svalue="-1">- no selection -</option>')%s)
329-
options = linkcl.list()
330-
options.sort(sortfunc)
338+
if linkcl.getprops().has_key('order'):
339+
sort_on = 'order'
340+
else:
341+
sort_on = linkcl.labelprop()
342+
options = linkcl.filter(None, {}, [sort_on], [])
331343
for optionid in options:
332344
option = linkcl.get(optionid, k)
333345
s = ''
@@ -759,7 +771,7 @@ def __call__(self, m, search_text=None, filter=None, columns=None,
759771
return ''
760772
if m.group('display'):
761773
command = m.group('command')
762-
return eval(command, self.globals, self.locals)
774+
return eval(command, self.globals, self.locals)
763775
return '*** unhandled match: %s'%str(m.groupdict())
764776

765777
class IndexTemplate(TemplateFunctions):
@@ -785,7 +797,6 @@ def render(self, filterspec={}, search_text='', filter=[], columns=[],
785797
self.filterspec = filterspec
786798

787799
w = self.client.write
788-
789800
# get the filter template
790801
try:
791802
filter_template = open(os.path.join(self.templates,
@@ -922,6 +933,7 @@ def render(self, filterspec={}, search_text='', filter=[], columns=[],
922933
w('</form>\n')
923934

924935
self.db = self.cl = self.properties = None
936+
self.clear()
925937

926938
def node_matches(self, match, colspan):
927939
''' display the files and messages for a node that matched a
@@ -955,7 +967,6 @@ def node_matches(self, match, colspan):
955967

956968
def filter_section(self, template, search_text, filter, columns, group,
957969
all_filters, all_columns, show_customization):
958-
959970
w = self.client.write
960971

961972
# wrap the template in a single table to ensure the whole widget
@@ -1172,6 +1183,7 @@ def render(self, nodeid):
11721183
w(replace.go(s))
11731184
w('</form>')
11741185
self.cl = self.db = self.properties = None
1186+
self.clear()
11751187

11761188

11771189
class NewItemTemplate(TemplateFunctions):
@@ -1208,9 +1220,16 @@ def render(self, form):
12081220
w(replace.go(s))
12091221
w('</form>')
12101222
self.cl = self.db = None
1223+
self.clear()
12111224

12121225
#
12131226
# $Log: not supported by cvs2svn $
1227+
# Revision 1.93 2002/06/27 12:05:25 gmcm
1228+
# Default labelprops to id.
1229+
# In history, make sure there's a .item before making a link / multilink into an href.
1230+
# Also in history, cgi.escape String properties.
1231+
# Clean up some of the reference cycles.
1232+
#
12141233
# Revision 1.92 2002/06/11 04:57:04 richard
12151234
# Added optional additional property to display in a Multilink form menu.
12161235
#

0 commit comments

Comments
 (0)