[IMP] models, registry: let the registry retrieve manual fields from database

This commit is contained in:
Raphael Collet 2015-01-15 15:25:19 +01:00
parent 5d7bba4eb7
commit cf26f7ed80
4 changed files with 24 additions and 25 deletions

View File

@ -388,9 +388,7 @@ class ir_model_fields(osv.osv):
if vals['model'].startswith('x_') and vals['name'] == 'x_name':
model._rec_name = 'x_name'
if self.pool.fields_by_model is not None:
cr.execute('SELECT * FROM ir_model_fields WHERE id=%s', (res,))
self.pool.fields_by_model.setdefault(vals['model'], []).append(cr.dictfetchone())
self.pool.clear_manual_fields()
# re-initialize model in registry
model.__init__(self.pool, cr)

View File

@ -694,15 +694,10 @@ class BaseModel(object):
@classmethod
def _init_manual_fields(cls, cr, partial):
# Check whether the query is already done
if cls.pool.fields_by_model is not None:
manual_fields = cls.pool.fields_by_model.get(cls._name, [])
else:
cr.execute('SELECT * FROM ir_model_fields WHERE model=%s AND state=%s', (cls._name, 'manual'))
manual_fields = cr.dictfetchall()
manual_fields = cls.pool.get_manual_fields(cr, cls._name)
for field in manual_fields:
if field['name'] in cls._fields:
for name, field in manual_fields.iteritems():
if name in cls._fields:
continue
attrs = {
'manual': True,
@ -734,11 +729,11 @@ class BaseModel(object):
attrs['comodel_name'] = field['relation']
_rel1 = field['relation'].replace('.', '_')
_rel2 = field['model'].replace('.', '_')
attrs['relation'] = 'x_%s_%s_%s_rel' % (_rel1, _rel2, field['name'])
attrs['relation'] = 'x_%s_%s_%s_rel' % (_rel1, _rel2, name)
attrs['column1'] = 'id1'
attrs['column2'] = 'id2'
attrs['domain'] = eval(field['domain']) if field['domain'] else None
cls._add_field(field['name'], Field.by_type[field['ttype']](**attrs))
cls._add_field(name, Field.by_type[field['ttype']](**attrs))
@classmethod
def _init_constraints_onchanges(cls):

View File

@ -126,13 +126,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
migrations = openerp.modules.migration.MigrationManager(cr, graph)
_logger.info('loading %d modules...', len(graph))
# Query manual fields for all models at once and save them on the registry
# so the initialization code for each model does not have to do it
# one model at a time.
registry.fields_by_model = {}
cr.execute('SELECT * FROM ir_model_fields WHERE state=%s', ('manual',))
for field in cr.dictfetchall():
registry.fields_by_model.setdefault(field['model'], []).append(field)
registry.clear_manual_fields()
# register, instantiate and initialize models for each modules
t0 = time.time()
@ -227,9 +221,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
_logger.log(25, "%s modules loaded in %.2fs, %s queries", len(graph), time.time() - t0, openerp.sql_db.sql_counter - t0_sql)
# The query won't be valid for models created later (i.e. custom model
# created after the registry has been loaded), so empty its result.
registry.fields_by_model = None
registry.clear_manual_fields()
cr.commit()

View File

@ -22,7 +22,7 @@
""" Models registries.
"""
from collections import Mapping
from collections import Mapping, defaultdict
import logging
import os
import threading
@ -51,7 +51,7 @@ class Registry(Mapping):
self._init = True
self._init_parent = {}
self._assertion_report = assertion_report.assertion_report()
self.fields_by_model = None
self._fields_by_model = None
# modules fully loaded (maintained during init phase by `loading` module)
self._init_modules = set()
@ -114,6 +114,20 @@ class Registry(Mapping):
fields.append(model_fields[fname])
return fields
def clear_manual_fields(self):
""" Invalidate the cache for manual fields. """
self._fields_by_model = None
def get_manual_fields(self, cr, model_name):
""" Return the manual fields (as a dict) for the given model. """
if self._fields_by_model is None:
# Query manual fields for all models at once
self._fields_by_model = dic = defaultdict(dict)
cr.execute('SELECT * FROM ir_model_fields WHERE state=%s', ('manual',))
for field in cr.dictfetchall():
dic[field['model']][field['name']] = field
return self._fields_by_model[model_name]
def do_parent_store(self, cr):
for o in self._init_parent:
self.get(o)._parent_store_compute(cr)