[range facet] closes #1806937: simply retrieve min/max values when computing vocabulary/possible_values, this is enough
--- a/web/facet.py Thu Jul 07 13:53:00 2011 +0200
+++ b/web/facet.py Thu Jul 07 16:22:08 2011 +0200
@@ -1176,6 +1176,47 @@
def wdgclass(self):
return FacetRangeWidget
+ def _range_rset(self):
+ select = self.select
+ select.save_state()
+ try:
+ filtered_variable = self.filtered_variable
+ cleanup_select(select, filtered_variable)
+ newvar = _add_rtype_relation(select, filtered_variable, self.rtype, self.role)[0]
+ minf = nodes.Function('MIN')
+ minf.append(nodes.VariableRef(newvar))
+ select.add_selected(minf)
+ maxf = nodes.Function('MAX')
+ maxf.append(nodes.VariableRef(newvar))
+ select.add_selected(maxf)
+ # add is restriction if necessary
+ if filtered_variable.stinfo['typerel'] is None:
+ etypes = frozenset(sol[filtered_variable.name] for sol in select.solutions)
+ select.add_type_restriction(filtered_variable, etypes)
+ try:
+ return self.rqlexec(select.as_string(), self.cw_rset.args)
+ except Exception:
+ self.exception('error while getting vocabulary for %s, rql: %s',
+ self, select.as_string())
+ return ()
+ finally:
+ select.recover()
+
+ def vocabulary(self):
+ """return vocabulary for this facet, eg a list of 2-uple (label, value)
+ """
+ rset = self._range_rset()
+ if rset:
+ minv, maxv = rset[0]
+ return [(unicode(minv), minv), (unicode(maxv), maxv)]
+ return []
+
+ def possible_values(self):
+ """Return a list of possible values (as string since it's used to
+ compare to a form value in javascript) for this facet.
+ """
+ return [strval for strval, val in self.vocabulary()]
+
def get_widget(self):
"""return the widget instance to use to display this facet"""
values = set(value for _, value in self.vocabulary() if value is not None)
--- a/web/test/unittest_facet.py Thu Jul 07 13:53:00 2011 +0200
+++ b/web/test/unittest_facet.py Thu Jul 07 16:22:08 2011 +0200
@@ -135,27 +135,27 @@
select=rqlst.children[0],
filtered_variable=filtered_variable)
f.rtype = 'creation_date'
- dates = self.execute('Any CD ORDERBY CD WHERE X is CWUser, X creation_date CD')
+ mind, maxd = self.execute('Any MIN(CD), MAX(CD) WHERE X is CWUser, X creation_date CD')[0]
self.assertEqual(f.vocabulary(),
- [(str(dates[0][0]), dates[0][0]),
- (str(dates[1][0]), dates[1][0])])
+ [(str(mind), mind),
+ (str(maxd), maxd)])
# ensure rqlst is left unmodified
self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
#rqlst = rset.syntax_tree()
self.assertEqual(f.possible_values(),
- [str(dates[0][0]), str(dates[1][0])])
+ [str(mind), str(maxd)])
# ensure rqlst is left unmodified
self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
- req.form['%s_inf' % f.__regid__] = str(datetime2ticks(dates[0][0]))
- req.form['%s_sup' % f.__regid__] = str(datetime2ticks(dates[0][0]))
+ req.form['%s_inf' % f.__regid__] = str(datetime2ticks(mind))
+ req.form['%s_sup' % f.__regid__] = str(datetime2ticks(mind))
f.add_rql_restrictions()
# selection is cluttered because rqlst has been prepared for facet (it
# is not in real life)
self.assertEqual(f.select.as_string(),
'DISTINCT Any WHERE X is CWUser, X creation_date >= "%s", '
'X creation_date <= "%s"'
- % (dates[0][0].strftime('%Y/%m/%d'),
- dates[0][0].strftime('%Y/%m/%d')))
+ % (mind.strftime('%Y/%m/%d'),
+ mind.strftime('%Y/%m/%d')))
def test_attribute(self):
req, rset, rqlst, filtered_variable = self.prepare_rqlst()