[MERGE] trunk
[odoo/odoo.git] / openerp / addons / base / ir / ir_model_relation.py
1 import logging
2
3 import openerp
4 from openerp import SUPERUSER_ID
5 from openerp.osv import fields
6 from openerp.osv.orm import Model
7
8 _logger = logging.getLogger(__name__)
9
10 class ir_model_relation(Model):
11     """
12     This model tracks PostgreSQL tables used to implement OpenERP many2many
13     relations.
14     """
15     _name = 'ir.model.relation'
16     _columns = {
17         'name': fields.char('Relation Name', required=True, size=128, select=1,
18             help="PostgreSQL table name implementing a many2many relation."),
19         'model': fields.many2one('ir.model', string='Model',
20             required=True, select=1),
21         'module': fields.many2one('ir.module.module', string='Module',
22             required=True, select=1),
23         'date_update': fields.datetime('Update Date'),
24         'date_init': fields.datetime('Initialization Date')
25     }
26
27     def _module_data_uninstall(self, cr, uid, ids, context=None):
28         """
29         Delete PostgreSQL many2many relations tracked by this model.
30         """ 
31
32         if uid != SUPERUSER_ID and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"):
33             raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module')))
34
35         ids_set = set(ids)
36         to_drop_table = []
37         ids.sort()
38         ids.reverse()
39         to_unlink = []
40         for data in self.browse(cr, uid, ids, context):
41             model = data.model
42             model_obj = self.pool.get(model)
43             name = openerp.tools.ustr(data.name)
44
45             # double-check we are really going to delete all the owners of this schema element
46             cr.execute("""SELECT id from ir_model_relation where name = %s""", (data.name,))
47             external_ids = [x[0] for x in cr.fetchall()]
48             if (set(external_ids)-ids_set):
49                 # as installed modules have defined this element we must not delete it!
50                 continue
51
52             cr.execute("SELECT 1 FROM information_schema.tables WHERE table_name=%s", (name,))
53             if cr.fetchone() and not name in to_drop_table:
54                 to_drop_table.append(name)
55
56             to_unlink.append(data.id)
57
58         self.unlink(cr, uid, to_unlink, context)
59
60         # drop m2m relation tables
61         for table in to_drop_table:
62             cr.execute('DROP TABLE %s CASCADE'% (table),)
63             _logger.info('Dropped table %s', table)
64
65         cr.commit()