[range facet] closes #1806937: simply retrieve min/max values when computing vocabulary/possible_values, this is enough
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 07 Jul 2011 16:22:08 +0200
changeset 7629 58f11f7dad68
parent 7628 56022cf13887
child 7631 4ac19f288149
[range facet] closes #1806937: simply retrieve min/max values when computing vocabulary/possible_values, this is enough
web/facet.py
web/test/unittest_facet.py
--- 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()