Thibault Delavallée (OpenERP) has proposed merging 
lp:~openerp-dev/openobject-server/trunk-chatter-reaches-light-speed-tde into 
lp:openobject-server.

Requested reviews:
  OpenERP Core Team (openerp)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-chatter-reaches-light-speed-tde/+merge/135716

Chatter, needaction: make it fast !
-- 
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-chatter-reaches-light-speed-tde/+merge/135716
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openobject-server/trunk-chatter-reaches-light-speed-tde.
=== modified file 'openerp/addons/base/ir/ir_needaction.py'
--- openerp/addons/base/ir/ir_needaction.py	2012-09-04 10:32:42 +0000
+++ openerp/addons/base/ir/ir_needaction.py	2012-11-22 15:29:21 +0000
@@ -60,4 +60,6 @@
         dom = self._needaction_domain_get(cr, uid, context=context)
         if not dom:
             return 0
-        return self.search(cr, uid, (domain or []) +dom, context=context, count=True)
+        context = context or {}
+        context['__exp_force_ids'] = True
+        return self.search(cr, uid, (domain or []) + dom, limit=100, context=context, count=True)

=== modified file 'openerp/addons/base/ir/ir_ui_menu.py'
--- openerp/addons/base/ir/ir_ui_menu.py	2012-10-29 10:46:36 +0000
+++ openerp/addons/base/ir/ir_ui_menu.py	2012-11-22 15:29:21 +0000
@@ -265,17 +265,17 @@
 
         return res
 
-    def _get_needaction(self, cr, uid, ids, field_names, args, context=None):
+    def get_needaction_data(self, cr, uid, ids, context=None):
         res = {}
         for menu in self.browse(cr, uid, ids, context=context):
             res[menu.id] = {
                 'needaction_enabled': False,
                 'needaction_counter': False,
             }
-            if menu.action and menu.action.type in ('ir.actions.act_window','ir.actions.client') and menu.action.res_model:
+            if menu.action and menu.action.type in ('ir.actions.act_window', 'ir.actions.client') and menu.action.res_model:
                 obj = self.pool.get(menu.action.res_model)
                 if obj and obj._needaction:
-                    if menu.action.type=='ir.actions.act_window':
+                    if menu.action.type == 'ir.actions.act_window':
                         dom = menu.action.domain and eval(menu.action.domain, {'uid': uid}) or []
                     else:
                         dom = eval(menu.action.params_store or '{}', {'uid': uid}).get('domain')
@@ -283,10 +283,19 @@
                     res[menu.id]['needaction_counter'] = obj._needaction_count(cr, uid, dom, context=context)
         return res
 
+    def _get_needaction_enabled(self, cr, uid, ids, field_names, args, context=None):
+        res = dict.fromkeys(ids, False)
+        for menu in self.browse(cr, uid, ids, context=context):
+            if menu.action and menu.action.type in ('ir.actions.act_window', 'ir.actions.client') and menu.action.res_model:
+                obj = self.pool.get(menu.action.res_model)
+                if obj and obj._needaction:
+                    res[menu.id] = True
+        return res
+
     _columns = {
         'name': fields.char('Menu', size=64, required=True, translate=True),
         'sequence': fields.integer('Sequence'),
-        'child_id' : fields.one2many('ir.ui.menu', 'parent_id','Child IDs'),
+        'child_id': fields.one2many('ir.ui.menu', 'parent_id', 'Child IDs'),
         'parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', select=True),
         'groups_id': fields.many2many('res.groups', 'ir_ui_menu_group_rel',
             'menu_id', 'gid', 'Groups', help="If you have groups, the visibility of this menu will be based on these groups. "\
@@ -296,11 +305,14 @@
         'icon': fields.selection(tools.icons, 'Icon', size=64),
         'icon_pict': fields.function(_get_icon_pict, type='char', size=32),
         'web_icon': fields.char('Web Icon File', size=128),
-        'web_icon_hover':fields.char('Web Icon File (hover)', size=128),
+        'web_icon_hover': fields.char('Web Icon File (hover)', size=128),
         'web_icon_data': fields.function(_get_image_icon, string='Web Icon Image', type='binary', readonly=True, store=True, multi='icon'),
-        'web_icon_hover_data':fields.function(_get_image_icon, string='Web Icon Image (hover)', type='binary', readonly=True, store=True, multi='icon'),
-        'needaction_enabled': fields.function(_get_needaction, string='Target model uses the need action mechanism', type='boolean', help='If the menu entry action is an act_window action, and if this action is related to a model that uses the need_action mechanism, this field is set to true. Otherwise, it is false.', multi='_get_needaction'),
-        'needaction_counter': fields.function(_get_needaction, string='Number of actions the user has to perform', type='integer', help='If the target model uses the need action mechanism, this field gives the number of actions the current user has to perform.', multi='_get_needaction'),
+        'web_icon_hover_data': fields.function(_get_image_icon, string='Web Icon Image (hover)', type='binary', readonly=True, store=True, multi='icon'),
+        'needaction_enabled': fields.function(_get_needaction_enabled, string='Target model uses the need action mechanism',
+            type='boolean', store=True,
+            # multi='_get_needaction_enabled',
+            help='If the menu entry action is an act_window action, and if this action is related to a model that uses the need_action mechanism, this field is set to true. Otherwise, it is false.',),
+        # 'needaction_counter': fields.function(_get_needaction, string='Number of actions the user has to perform', type='integer', help='If the target model uses the need action mechanism, this field gives the number of actions the current user has to perform.', multi='_get_needaction'),
         'action': fields.function(_action, fnct_inv=_action_inv,
             type='reference', string='Action',
             selection=[

=== modified file 'openerp/osv/expression.py'
--- openerp/osv/expression.py	2012-10-18 12:47:50 +0000
+++ openerp/osv/expression.py	2012-11-22 15:29:21 +0000
@@ -674,6 +674,60 @@
 
                     self.__exp[i] = ('id', 'inselect', (subselect, params))
 
+        context = dict(context or {})
+        if context.get('__exp_force_ids'):
+            context.pop('__exp_force_ids')
+            for i, e in enumerate(self.__exp):
+                if is_operator(e) or e == TRUE_LEAF or e == FALSE_LEAF:
+                    continue
+                left, op, right = e
+                if left != 'id':
+                    assert left in self.__main_table._columns, "WTF?"
+                    if op in NEGATIVE_TERM_OPERATORS:
+                        op2 = 'not in'
+                    else:
+                        op2 = 'in'
+                    self.__exp[i] = ('id', op2, self.__main_table.search(cr, uid, [e], context=context))
+
+            all_ids = set(self.__main_table.search(cr, uid, [], context=context))
+            # print "==> len all_ids:", len(all_ids)
+            stack = []
+            # Process the domain from right to left, using a stack, to generate a SQL expression.
+            for i, e in reverse_enumerate(self.__exp):
+                if e == TRUE_LEAF:
+                    # print "--> TRUE: push set with len ", len(all_ids)
+                    stack.append(all_ids)
+                elif e == FALSE_LEAF:
+                    # print "--> FALSE: push empty set"
+                    stack.append(set())
+                elif e == AND_OPERATOR:
+                    s = stack.pop().intersection(stack.pop())
+                    # print "--> AND: push set with len ", len(s)
+                    stack.append(s)
+                elif e == OR_OPERATOR:
+                    s = stack.pop().union(stack.pop())
+                    # print "--> OR: push set with len ", len(s)
+                    stack.append(s)
+                elif is_leaf(e, internal=True):
+                    l, o, r = e
+                    if o.lower() == 'not in':
+                        s = all_ids.difference(r)
+                    elif o.lower() == 'in':
+                        s = set(r)
+                    elif o == '=':
+                        s = set([r])
+                    elif o == '!=':
+                        s = all_ids.difference([r])
+                    else:
+                        raise Exception('unknown op: %r in %r' % (o, e))
+                    # print "--> ", l, o, ": push set with len ", len(s)
+                    stack.append(s)
+                else:
+                    raise Exception('WTF is this leaf: %r' % e)
+            assert len(stack) == 1, 'Invalid stack state: %r' % stack
+            # print "==> final result with %s ids" % len(stack[0])
+            self.__exp = [('id', 'in', list(stack[0]))]
+
     def __leaf_to_sql(self, leaf, table):
         left, operator, right = leaf
 

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : openerp-dev-gtk@lists.launchpad.net
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to