From bc173660992b562b93063ecefb1a0f3133dbcf1e Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Fri, 10 Jun 2011 12:45:33 +0300 Subject: [PATCH] ir.module: refactor _get_views(), significantly optimize Since that fn() is usually called for a single module, it is not worth fetching all modules' data, but rather group by the menus/reports/views models. In the "account-fr" test, this reduces around 2k sql calls. bzr revid: xrg@linux.gr-20110610094533-0dwg4a4mx3hqmfji --- openerp/addons/base/module/module.py | 75 ++++++++++++++++++---------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 51fdb224918..6cb6d9439b1 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -97,45 +97,66 @@ class module(osv.osv): view_obj = self.pool.get('ir.ui.view') report_obj = self.pool.get('ir.actions.report.xml') menu_obj = self.pool.get('ir.ui.menu') - mlist = self.browse(cr, uid, ids, context=context) - mnames = {} - for m in mlist: - # skip uninstalled modules below, - # no data to find anyway - if m.state in ('installed', 'to upgrade', 'to remove'): - mnames[m.name] = m.id - res[m.id] = { + + dmodels = [] + if field_name is None or 'views_by_module' in field_name: + dmodels.append('ir.ui.view') + if field_name is None or 'reports_by_module' in field_name: + dmodels.append('ir.actions.report.xml') + if field_name is None or 'menus_by_module' in field_name: + dmodels.append('ir.ui.menu') + assert dmodels, "no models for %s" % field_name + + for module_rec in self.browse(cr, uid, ids, context=context): + # we loop over the modules, usually this _get_views is only + # called for one module at a time + + res[module_rec.id] = { 'menus_by_module':[], 'reports_by_module':[], 'views_by_module': [] } - if not mnames: - return res + # skip uninstalled modules below, + # no data to find anyway + if module_rec.state not in ('installed', 'to upgrade', 'to remove'): + continue - view_id = model_data_obj.search(cr,uid,[('module','in', mnames.keys()), - ('model','in',('ir.ui.view','ir.actions.report.xml','ir.ui.menu'))]) - for data_id in model_data_obj.browse(cr,uid,view_id,context): + # then, search and group ir.model.data records + imd_models = dict( [(m,[]) for m in dmodels]) + imd_ids = model_data_obj.search(cr,uid,[('module','=', module_rec.name), + ('model','in',tuple(dmodels))]) + + for imd_res in model_data_obj.read(cr, uid, imd_ids, ['model', 'res_id'], context=context): + imd_models[imd_res['model']].append(imd_res['res_id']) + + # For each one of the models, get the names of these ids # We use try except, because views or menus may not exist try: - key = data_id.model - res_mod_dic = res[mnames[data_id.module]] - if key=='ir.ui.view': - v = view_obj.browse(cr,uid,data_id.res_id) - aa = v.inherit_id and '* INHERIT ' or '' - res_mod_dic['views_by_module'].append(aa + v.name + '('+v.type+')') - elif key=='ir.actions.report.xml': - res_mod_dic['reports_by_module'].append(report_obj.browse(cr,uid,data_id.res_id).name) - elif key=='ir.ui.menu': - res_mod_dic['menus_by_module'].append(menu_obj.browse(cr,uid,data_id.res_id).complete_name) + res_mod_dic = res[module_rec.id] + if imd_models.get('ir.ui.view', False): + for v in view_obj.browse(cr, uid, imd_models['ir.ui.view'], context=context): + aa = v.inherit_id and '* INHERIT ' or '' + res_mod_dic['views_by_module'].append(aa + v.name + '('+v.type+')') + + if imd_models.get('ir.actions.report.xml', False): + for rx in report_obj.browse(cr,uid, imd_models['ir.actions.report.xml'], context=context): + res_mod_dic['reports_by_module'].append(rx.name) + + if imd_models.get('ir.ui.menu', False): + for um in menu_obj.browse(cr,uid,imd_models['ir.ui.menu'], context=context): + res_mod_dic['menus_by_module'].append(um.complete_name) except KeyError, e: self.__logger.warning( - 'Data not found for reference %s[%s:%s.%s]', data_id.model, - data_id.res_id, data_id.model, data_id.name, exc_info=True) + 'Data not found for items of %s', module_rec.name) + pass + except AttributeError, e: + self.__logger.warning( + 'Data not found for items of %s %s', module_rec.name, str(e)) pass except Exception, e: - self.__logger.warning('Unknown error while browsing %s[%s]', - data_id.model, data_id.res_id, exc_info=True) + self.__logger.warning('Unknown error while fetching data of %s', + module_rec.name, exc_info=True) pass for key, value in res.iteritems(): for k, v in res[key].iteritems() :