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