[REF] base: Changed code to avoid overriding of context values.
[odoo/odoo.git] / openerp / modules / registry.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 """ Models registries.
23
24 """
25
26 import openerp.sql_db
27 import openerp.osv.orm
28
29
30 class Registry(object):
31     """ Model registry for a particular database.
32
33     The registry is essentially a mapping between model names and model
34     instances. There is one registry instance per database.
35
36     """
37
38     def __init__(self, db_name):
39         self.models = {} # model name/model instance mapping
40         self._sql_error = {}
41         self._store_function = {}
42         self._init = True
43         self._init_parent = {}
44         self.db_name = db_name
45         self.db = openerp.sql_db.db_connect(db_name)
46
47     def do_parent_store(self, cr):
48         for o in self._init_parent:
49             self.get(o)._parent_store_compute(cr)
50         self._init = False
51
52     def obj_list(self):
53         """ Return the list of model names in this registry."""
54         return self.models.keys()
55
56     def add(self, model_name, model):
57         """ Add or replace a model in the registry."""
58         self.models[model_name] = model
59
60     def get(self, model_name):
61         """ Return a model for a given name or None if it doesn't exist."""
62         return self.models.get(model_name)
63
64     def __getitem__(self, model_name):
65         """ Return a model for a given name or raise KeyError if it doesn't exist."""
66         return self.models[model_name]
67
68     def instanciate(self, module, cr):
69         """ Instanciate all the classes of a given module for a particular db."""
70
71         res = []
72
73         # Instanciate classes registered through their constructor and
74         # add them to the pool.
75         for klass in openerp.osv.orm.module_class_list.get(module, []):
76             res.append(klass.createInstance(self, cr))
77
78         # Instanciate classes automatically discovered.
79         for cls in openerp.osv.orm.MetaModel.module_to_models.get(module, []):
80             if cls not in openerp.osv.orm.module_class_list.get(module, []):
81                 res.append(cls.createInstance(self, cr))
82
83         return res
84
85
86 class RegistryManager(object):
87     """ Model registries manager.
88
89         The manager is responsible for creation and deletion of model
90         registries (essentially database connection/model registry pairs).
91
92     """
93
94     # Mapping between db name and model registry.
95     # Accessed through the methods below.
96     registries = {}
97
98
99     @classmethod
100     def get(cls, db_name, force_demo=False, status=None, update_module=False,
101             pooljobs=True):
102         """ Return a registry for a given database name."""
103
104         if db_name in cls.registries:
105             registry = cls.registries[db_name]
106         else:
107             registry = cls.new(db_name, force_demo, status,
108                 update_module, pooljobs)
109         return registry
110
111
112     @classmethod
113     def new(cls, db_name, force_demo=False, status=None,
114             update_module=False, pooljobs=True):
115         """ Create and return a new registry for a given database name.
116
117         The (possibly) previous registry for that database name is discarded.
118
119         """
120
121         import openerp.modules
122         registry = Registry(db_name)
123
124         # Initializing a registry will call general code which will in turn
125         # call registries.get (this object) to obtain the registry being
126         # initialized. Make it available in the registries dictionary then
127         # remove it if an exception is raised.
128         cls.delete(db_name)
129         cls.registries[db_name] = registry
130         try:
131             # This should be a method on Registry
132             openerp.modules.load_modules(registry.db, force_demo, status, update_module)
133         except Exception:
134             del cls.registries[db_name]
135             raise
136
137         cr = registry.db.cursor()
138         try:
139             registry.do_parent_store(cr)
140             registry.get('ir.actions.report.xml').register_all(cr)
141             cr.commit()
142         finally:
143             cr.close()
144
145         if pooljobs:
146             registry.get('ir.cron').restart(registry.db.dbname)
147
148         return registry
149
150
151     @classmethod
152     def delete(cls, db_name):
153         """ Delete the registry linked to a given database. """
154         if db_name in cls.registries:
155             del cls.registries[db_name]
156
157
158 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: