summaryrefslogtreecommitdiff
path: root/openerp/modules
diff options
context:
space:
mode:
Diffstat (limited to 'openerp/modules')
-rw-r--r--openerp/modules/loading.py5
-rw-r--r--openerp/modules/module.py2
-rw-r--r--openerp/modules/registry.py105
3 files changed, 70 insertions, 42 deletions
diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py
index d81461d6a77..eb703e25eb6 100644
--- a/openerp/modules/loading.py
+++ b/openerp/modules/loading.py
@@ -162,6 +162,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
loaded_modules.append(package.name)
if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
+ registry.setup_models(cr)
init_module_models(cr, package.name, models)
status['progress'] = float(index) / len(graph)
@@ -188,6 +189,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
status['progress'] = (index + 0.75) / len(graph)
_load_data(cr, module_name, idref, mode, kind='demo')
cr.execute('update ir_module_module set demo=%s where id=%s', (True, module_id))
+ modobj.invalidate_cache(cr, SUPERUSER_ID, ['demo'], [module_id])
migrations.migrate_module(package, 'post')
@@ -228,6 +230,8 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
registry._init_modules.add(package.name)
cr.commit()
+ registry.setup_models(cr)
+
_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
@@ -332,6 +336,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
modobj.button_upgrade(cr, SUPERUSER_ID, ids)
cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base'))
+ modobj.invalidate_cache(cr, SUPERUSER_ID, ['state'])
# STEP 3: Load marked modules (skipping base which was done in STEP 1)
diff --git a/openerp/modules/module.py b/openerp/modules/module.py
index 0dd93629830..505e51b0394 100644
--- a/openerp/modules/module.py
+++ b/openerp/modules/module.py
@@ -278,7 +278,7 @@ def init_module_models(cr, module_name, obj_list):
for obj in obj_list:
obj._auto_end(cr, {'module': module_name})
cr.commit()
- todo.sort()
+ todo.sort(key=lambda x: x[0])
for t in todo:
t[1](cr, *t[2])
cr.commit()
diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py
index eb591c53521..1d68e228b8f 100644
--- a/openerp/modules/registry.py
+++ b/openerp/modules/registry.py
@@ -27,12 +27,9 @@ from contextlib import contextmanager
import logging
import threading
-import openerp.sql_db
-import openerp.osv.orm
-import openerp.tools
-import openerp.modules.db
-import openerp.tools.config
-from openerp.tools import assertion_report
+import openerp
+from .. import SUPERUSER_ID
+from openerp.tools import assertion_report, lazy_property
_logger = logging.getLogger(__name__)
@@ -49,6 +46,7 @@ class Registry(Mapping):
self.models = {} # model name/model instance mapping
self._sql_error = {}
self._store_function = {}
+ self._pure_function_fields = {} # {model: [field, ...], ...}
self._init = True
self._init_parent = {}
self._assertion_report = assertion_report.assertion_report()
@@ -97,10 +95,6 @@ class Registry(Mapping):
""" Return an iterator over all model names. """
return iter(self.models)
- def __contains__(self, model_name):
- """ Test whether the model with the given name exists. """
- return model_name in self.models
-
def __getitem__(self, model_name):
""" Return the model with the given name or raise KeyError if it doesn't exist."""
return self.models[model_name]
@@ -109,6 +103,16 @@ class Registry(Mapping):
""" Same as ``self[model_name]``. """
return self.models[model_name]
+ @lazy_property
+ def pure_function_fields(self):
+ """ Return the list of pure function fields (field objects) """
+ fields = []
+ for mname, fnames in self._pure_function_fields.iteritems():
+ model_fields = self[mname]._fields
+ for fname in fnames:
+ fields.append(model_fields[fname])
+ return fields
+
def do_parent_store(self, cr):
for o in self._init_parent:
self.get(o)._parent_store_compute(cr)
@@ -131,17 +135,35 @@ class Registry(Mapping):
and registers them in the registry.
"""
+ from .. import models
+
models_to_load = [] # need to preserve loading order
+ lazy_property.reset_all(self)
+
# Instantiate registered classes (via the MetaModel automatic discovery
# or via explicit constructor call), and add them to the pool.
- for cls in openerp.osv.orm.MetaModel.module_to_models.get(module.name, []):
+ for cls in models.MetaModel.module_to_models.get(module.name, []):
# models register themselves in self.models
- model = cls.create_instance(self, cr)
+ model = cls._build_model(self, cr)
if model._name not in models_to_load:
# avoid double-loading models whose declaration is split
models_to_load.append(model._name)
+
return [self.models[m] for m in models_to_load]
+ def setup_models(self, cr):
+ """ Complete the setup of models.
+ This must be called after loading modules and before using the ORM.
+ """
+ # prepare the setup on all models
+ for model in self.models.itervalues():
+ model._prepare_setup_fields(cr, SUPERUSER_ID)
+
+ # do the actual setup from a clean state
+ self._m2m = {}
+ for model in self.models.itervalues():
+ model._setup_fields(cr, SUPERUSER_ID)
+
def clear_caches(self):
""" Clear the caches
This clears the caches associated to methods decorated with
@@ -151,7 +173,7 @@ class Registry(Mapping):
model.clear_caches()
# Special case for ir_ui_menu which does not use openerp.tools.ormcache.
ir_ui_menu = self.models.get('ir.ui.menu')
- if ir_ui_menu:
+ if ir_ui_menu is not None:
ir_ui_menu.clear_cache()
@@ -282,36 +304,37 @@ class RegistryManager(object):
"""
import openerp.modules
with cls.lock():
- registry = Registry(db_name)
-
- # Initializing a registry will call general code which will in turn
- # call registries.get (this object) to obtain the registry being
- # initialized. Make it available in the registries dictionary then
- # remove it if an exception is raised.
- cls.delete(db_name)
- cls.registries[db_name] = registry
- try:
- with registry.cursor() as cr:
- seq_registry, seq_cache = Registry.setup_multi_process_signaling(cr)
- registry.base_registry_signaling_sequence = seq_registry
- registry.base_cache_signaling_sequence = seq_cache
- # This should be a method on Registry
- openerp.modules.load_modules(registry._db, force_demo, status, update_module)
- except Exception:
- del cls.registries[db_name]
- raise
+ with openerp.api.Environment.manage():
+ registry = Registry(db_name)
- # load_modules() above can replace the registry by calling
- # indirectly new() again (when modules have to be uninstalled).
- # Yeah, crazy.
- registry = cls.registries[db_name]
+ # Initializing a registry will call general code which will in
+ # turn call registries.get (this object) to obtain the registry
+ # being initialized. Make it available in the registries
+ # dictionary then remove it if an exception is raised.
+ cls.delete(db_name)
+ cls.registries[db_name] = registry
+ try:
+ with registry.cursor() as cr:
+ seq_registry, seq_cache = Registry.setup_multi_process_signaling(cr)
+ registry.base_registry_signaling_sequence = seq_registry
+ registry.base_cache_signaling_sequence = seq_cache
+ # This should be a method on Registry
+ openerp.modules.load_modules(registry._db, force_demo, status, update_module)
+ except Exception:
+ del cls.registries[db_name]
+ raise
+
+ # load_modules() above can replace the registry by calling
+ # indirectly new() again (when modules have to be uninstalled).
+ # Yeah, crazy.
+ registry = cls.registries[db_name]
- cr = registry.cursor()
- try:
- registry.do_parent_store(cr)
- cr.commit()
- finally:
- cr.close()
+ cr = registry.cursor()
+ try:
+ registry.do_parent_store(cr)
+ cr.commit()
+ finally:
+ cr.close()
registry.ready = True