----- Forwarded message from [email protected] -----

Please review this at http://codereview.appspot.com/3977044/

I think I will transplant this fix on every series even if it add a new method
in the API.
So please test it very well to be sure it doesn't break anything.


Affected files:
  M trytond/model/modelstorage.py
  M trytond/tests/test_tools.py
  M trytond/tools/misc.py


Index: trytond/model/modelstorage.py
===================================================================
--- a/trytond/model/modelstorage.py
+++ b/trytond/model/modelstorage.py
@@ -17,7 +17,7 @@
 from trytond.model.browse import BrowseRecordList, BrowseRecord, \
         BrowseRecordNull
 from trytond.model.browse import EvalEnvironment
-from trytond.tools import safe_eval
+from trytond.tools import safe_eval, reduce_domain
 from trytond.pyson import PYSONEncoder, PYSONDecoder, PYSON
 from trytond.const import OPERATORS
 from trytond.transaction import Transaction
@@ -429,7 +429,7 @@
         return res

     def _search_domain_active(self, domain, active_test=True):
-        domain = domain[:]
+        domain = reduce_domain(domain[:])
         # if the object has a field named 'active', filter out all inactive
         # records unless they were explicitely asked for
         if not (('active' in self._columns
Index: trytond/tests/test_tools.py
===================================================================
--- a/trytond/tests/test_tools.py
+++ b/trytond/tests/test_tools.py
@@ -5,7 +5,8 @@

 import unittest
 import datetime
-from trytond.tools import reduce_ids, safe_eval, datetime_strftime
+from trytond.tools import reduce_ids, safe_eval, datetime_strftime, \
+        reduce_domain


 class ToolsTestCase(unittest.TestCase):
@@ -94,6 +95,34 @@
         self.assert_(datetime_strftime(datetime.date(1805, 3, 2),
             '%Y-%m-%d'), '1805-03-02')

+    def test_reduce_domain(self):
+        '''
+        Test reduce_domain
+        '''
+        clause = ('x', '=', 'x')
+        tests = (
+            ([clause], ['AND', clause]),
+            ([clause, [clause]], ['AND', clause, clause]),
+            (['AND', clause, [clause]], ['AND', clause, clause]),
+            ([clause, ['AND', clause]], ['AND', clause, clause]),
+            ([clause, ['AND', clause, clause]],
+                ['AND', clause, clause, clause]),
+            (['AND', clause, ['AND', clause]], ['AND', clause, clause]),
+            ([[[clause]]], ['AND', clause]),
+            (['OR', clause], ['OR', clause]),
+            (['OR', clause, [clause]], ['OR', clause, ['AND', clause]]),
+            (['OR', clause, [clause, clause]],
+                ['OR', clause, ['AND', clause, clause]]),
+            (['OR', clause, ['OR', clause]], ['OR', clause, clause]),
+            (['OR', clause, [clause, ['OR', clause, clause]]],
+                ['OR', clause, ['AND', clause, ['OR', clause, clause]]]),
+            (['OR', [clause]], ['OR', ['AND', clause]]),
+            ([], []),
+        )
+        for i, j in tests:
+            self.assertEqual(reduce_domain(i), j,
+                    '%s -> %s != %s' % (i, reduce_domain(i), j))
+
 def suite():
     return unittest.TestLoader().loadTestsFromTestCase(ToolsTestCase)

Index: trytond/tools/misc.py
===================================================================
--- a/trytond/tools/misc.py
+++ b/trytond/tools/misc.py
@@ -16,6 +16,7 @@
 import dis
 from decimal import Decimal
 from trytond.config import CONFIG
+from trytond.const import OPERATORS

 def find_in_path(name):
     if os.name == "nt":
@@ -439,3 +440,34 @@
         'round': round,
         'Decimal': Decimal,
         }}, data)
+
+def reduce_domain(domain):
+    '''
+    Reduce domain
+    '''
+    if not domain:
+        return domain
+    i = 0
+    operator = 'AND'
+    if isinstance(domain[0], basestring):
+        operator = domain[0]
+        domain = domain[1:]
+    result = [operator]
+    while i < len(domain):
+        arg = domain[i]
+        if (isinstance(arg, tuple) or
+                (isinstance(arg, list) and
+                    len(arg) > 2 and
+                    arg[1] in OPERATORS)):
+            #clause
+            result.append(arg)
+        elif isinstance(arg, list) and arg:
+            #sub-domain
+            sub_domain = reduce_domain(arg)
+            sub_operator = sub_domain[0]
+            if sub_operator == operator:
+                result.extend(sub_domain[1:])
+            else:
+                result.append(sub_domain)
+        i += 1
+    return result



-- 
Cédric Krier

B2CK SPRL
Rue de Rotterdam, 4
4000 Liège
Belgium
Tel: +32 472 54 46 59
Email/Jabber: [email protected]
Website: http://www.b2ck.com/

Attachment: pgpDhYbs68Bzl.pgp
Description: PGP signature

Reply via email to