From 7a7e89bb103ea3e055678b1360ddfaad3fc269fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sun, 3 Jul 2011 18:01:47 +0200 Subject: [PATCH] Remove support of Many2Many field in record XML issue1994 review35005 --- CHANGELOG | 1 + trytond/backend/mysql/init.sql | 8 +- trytond/backend/postgresql/init.sql | 8 +- trytond/backend/sqlite/init.sql | 4 +- trytond/convert.py | 46 +----- trytond/ir/action.py | 2 +- trytond/ir/model.py | 8 +- trytond/ir/rule.py | 24 +-- trytond/ir/ui/menu.py | 2 +- trytond/res/group.py | 4 +- trytond/res/group.xml | 7 +- trytond/res/ir.py | 42 ++++- trytond/res/ir.xml | 230 +++++++++++++++++----------- trytond/res/request.xml | 13 +- trytond/res/user.py | 14 +- trytond/res/user.xml | 11 +- trytond/webdav/webdav.xml | 20 ++- trytond/workflow/workflow.xml | 40 ++++- 18 files changed, 296 insertions(+), 188 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ae3c547e2a..82469db2eb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Remove support of Many2Many field in record XML * Change Pool into a Singleton * Remove support of zipped modules diff --git a/trytond/backend/mysql/init.sql b/trytond/backend/mysql/init.sql index bb500939fd..a74b656807 100644 --- a/trytond/backend/mysql/init.sql +++ b/trytond/backend/mysql/init.sql @@ -84,10 +84,10 @@ CREATE TABLE res_group ( ) ENGINE=InnoDB; CREATE TABLE `res_user-res_group` ( - uid BIGINT NOT NULL, - gid BIGINT NOT NULL, - CONSTRAINT `res_user-res_group_uid_fkey` FOREIGN KEY (uid) REFERENCES res_user (id) ON DELETE CASCADE, - CONSTRAINT `res_user-res_group_gid_fkey` FOREIGN KEY (gid) REFERENCES res_group (id) ON DELETE CASCADE + `user` BIGINT NOT NULL, + `group` BIGINT NOT NULL, + CONSTRAINT `res_user-res_group_user_fkey` FOREIGN KEY (`user`) REFERENCES res_user (id) ON DELETE CASCADE, + CONSTRAINT `res_user-res_group_group_fkey` FOREIGN KEY (`group`) REFERENCES res_group (id) ON DELETE CASCADE ) ENGINE=InnoDB; CREATE TABLE wkf ( diff --git a/trytond/backend/postgresql/init.sql b/trytond/backend/postgresql/init.sql index be4da11b13..3e3c4229c5 100644 --- a/trytond/backend/postgresql/init.sql +++ b/trytond/backend/postgresql/init.sql @@ -102,10 +102,10 @@ CREATE SEQUENCE "res_user-res_group_id_seq"; CREATE TABLE "res_user-res_group" ( id INTEGER DEFAULT NEXTVAL('res_user-res_group_id_seq') NOT NULL, - uid INTEGER NOT NULL, - gid INTEGER NOT NULL, - FOREIGN KEY (uid) REFERENCES res_user (id) ON DELETE CASCADE, - FOREIGN KEY (gid) REFERENCES res_group (id) ON DELETE CASCADE, + "user" INTEGER NOT NULL, + "group" INTEGER NOT NULL, + FOREIGN KEY ("user") REFERENCES res_user (id) ON DELETE CASCADE, + FOREIGN KEY ("group") REFERENCES res_group (id) ON DELETE CASCADE, PRIMARY KEY(id) ); diff --git a/trytond/backend/sqlite/init.sql b/trytond/backend/sqlite/init.sql index 52bbf66e15..9d1879c227 100644 --- a/trytond/backend/sqlite/init.sql +++ b/trytond/backend/sqlite/init.sql @@ -73,8 +73,8 @@ CREATE TABLE res_group ( CREATE TABLE "res_user-res_group" ( id INTEGER PRIMARY KEY AUTOINCREMENT, - uid INTEGER, - gid INTEGER + "user" INTEGER, + "group" INTEGER ); CREATE TABLE wkf ( diff --git a/trytond/convert.py b/trytond/convert.py index 03ba03d2a6..406708be55 100644 --- a/trytond/convert.py +++ b/trytond/convert.py @@ -110,16 +110,7 @@ class MenuitemTagHandler: values['icon'] = 'tryton-new' if values.get('groups'): - g_names = values['groups'].split(',') - groups_value = [] - for group in g_names: - if group.startswith('-'): - group_id = self.mh.get_id(group[1:]) - groups_value.append(('remove', group_id)) - else: - group_id = self.mh.get_id(group) - groups_value.append(('add', group_id)) - values['groups'] = groups_value + raise Exception("Please use separate records for groups") if not values.get('name'): if not action_name: @@ -205,17 +196,8 @@ class RecordTagHandler: search_model = self.model._columns[field_name].model_name f_obj = self.mh.pool.get(search_model) with Transaction().set_context(active_test=False): - answer = f_obj.browse(f_obj.search(safe_eval(search_attr))) - - if not answer: return - - if self.model._columns[field_name]._type == 'many2many': - self.values[field_name] = [ - ('set', [x['id'] for x in answer]), - ] - - elif self.model._columns[field_name]._type == 'many2one': - self.values[field_name] = answer[0]['id'] + self.values[field_name], = \ + f_obj.search(safe_eval(search_attr)) elif ref_attr: self.values[field_name] = self.mh.get_id(ref_attr) @@ -527,7 +509,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): ref_id = ref_id[0] return ref_mode + ',' + str(ref_id) elif field_type in ['one2many', 'many2many']: - raise Unhandled_field() + raise Unhandled_field("Unhandled field %s" % key) else: return browse_record[key] @@ -695,13 +677,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): to_update = {} for key in values: - try: - db_field = self._clean_value(key, db_val, object_ref) - except Unhandled_field: - logging.getLogger("convert").info( - 'Field %s on %s : integrity not tested.'%(key, model)) - to_update[key] = values[key] - continue + db_field = self._clean_value(key, db_val, object_ref) # if the fs value is the same has in the db, whe ignore it val = values[key] @@ -813,11 +789,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): if not db_val: db_val = object_ref.browse(db_id) for key in to_update: - try: - values[key] = self._clean_value( - key, db_val, object_ref) - except Unhandled_field: - continue + values[key] = self._clean_value( key, db_val, object_ref) if module != self.module: temp_values = old_values.copy() @@ -904,11 +876,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): # in the model_data table: db_val = object_ref.browse(db_id) for key in values: - try: - values[key] = self._clean_value(key, db_val, - object_ref) - except Unhandled_field: - continue + values[key] = self._clean_value(key, db_val, object_ref) for table in inherit_db_ids.keys(): self.modeldata_obj.create({ diff --git a/trytond/ir/action.py b/trytond/ir/action.py index 06611031cb..5af846d398 100644 --- a/trytond/ir/action.py +++ b/trytond/ir/action.py @@ -21,7 +21,7 @@ class Action(ModelSQL, ModelView): usage = fields.Char('Usage') keywords = fields.One2Many('ir.action.keyword', 'action', 'Keywords') - groups = fields.Many2Many('ir.action-res.group', 'action_id', 'gid', + groups = fields.Many2Many('ir.action-res.group', 'action', 'group', 'Groups') icon = fields.Many2One('ir.ui.icon', 'Icon') active = fields.Boolean('Active', select=2) diff --git a/trytond/ir/model.py b/trytond/ir/model.py index a458af1d87..65d0da6ce8 100644 --- a/trytond/ir/model.py +++ b/trytond/ir/model.py @@ -264,8 +264,8 @@ class ModelAccess(ModelSQL, ModelView): 'JOIN "%s" AS m ' 'ON (a.model = m.id) ' 'LEFT JOIN "%s" AS gu ' - 'ON (gu.gid = a."group") ' - 'WHERE m.model = %%s AND (gu.uid = %%s OR a."group" IS NULL)' + 'ON (gu."group" = a."group") ' + 'WHERE m.model = %%s AND (gu."user" = %%s OR a."group" IS NULL)' % (mode, self._table, ir_model_obj._table, user_group_obj._table), (model_name, Transaction().user)) @@ -383,8 +383,8 @@ class ModelFieldAccess(ModelSQL, ModelView): 'JOIN "%s" AS m ' 'ON (f.model = m.id) ' 'LEFT JOIN "%s" AS gu ' - 'ON (gu.gid = a."group") ' - 'WHERE m.model = %%s AND (gu.uid = %%s OR a."group" IS NULL) ' + 'ON (gu."group" = a."group") ' + 'WHERE m.model = %%s AND (gu."user" = %%s OR a."group" IS NULL) ' 'GROUP BY f.name' % (mode, self._table, ir_model_field_obj._table, ir_model_obj._table, user_group_obj._table), diff --git a/trytond/ir/rule.py b/trytond/ir/rule.py index e5b2dcc87d..824a2ee467 100644 --- a/trytond/ir/rule.py +++ b/trytond/ir/rule.py @@ -27,9 +27,9 @@ class RuleGroup(ModelSQL, ModelView): rules = fields.One2Many('ir.rule', 'rule_group', 'Tests', help="The rule is satisfied if at least one test is True") groups = fields.Many2Many('ir.rule.group-res.group', - 'rule_group_id', 'group_id', 'Groups') + 'rule_group', 'group', 'Groups') users = fields.Many2Many('ir.rule.group-res.user', - 'rule_group_id', 'user_id', 'Users') + 'rule_group', 'user', 'Users') perm_read = fields.Boolean('Read Access') perm_write = fields.Boolean('Write Access') perm_create = fields.Boolean('Create Access') @@ -175,14 +175,14 @@ class Rule(ModelSQL, ModelView): "WHERE m.model = %s " "AND g.perm_" + mode + " " "AND (g.id IN (" \ - 'SELECT rule_group_id ' \ + 'SELECT rule_group ' \ 'FROM "' + rule_group_user_obj._table + '" ' \ - "WHERE user_id = %s " \ - "UNION SELECT rule_group_id " \ + 'WHERE "user" = %s ' \ + "UNION SELECT rule_group " \ 'FROM "' + rule_group_group_obj._table + '" g_rel ' \ 'JOIN "' + user_group_obj._table + '" u_rel ' \ - "ON (g_rel.group_id = u_rel.gid) " \ - "WHERE u_rel.uid = %s) " \ + 'ON (g_rel."group" = u_rel."group") ' \ + 'WHERE u_rel."user" = %s) ' \ "OR default_p " \ "OR g.global_p)", (model_name, Transaction().user, Transaction().user)) @@ -224,14 +224,14 @@ class Rule(ModelSQL, ModelView): 'WHERE m.model = %s ' \ 'AND (g.id NOT IN (SELECT rule_group ' \ 'FROM "' + self._table + '")) ' \ - 'AND (g.id IN (SELECT rule_group_id ' \ + 'AND (g.id IN (SELECT rule_group ' \ 'FROM "' + rule_group_user_obj._table + '" ' \ - 'WHERE user_id = %s ' \ - 'UNION SELECT rule_group_id ' \ + 'WHERE "user" = %s ' \ + 'UNION SELECT rule_group ' \ 'FROM "' + rule_group_group_obj._table + '" g_rel ' \ 'JOIN "' + user_group_obj._table + '" u_rel ' \ - 'ON g_rel.group_id = u_rel.gid ' \ - 'WHERE u_rel.uid = %s))', + 'ON g_rel."group" = u_rel."group" ' \ + 'WHERE u_rel."user" = %s))', (model_name, user_id, user_id)) fetchone = cursor.fetchone() if fetchone: diff --git a/trytond/ir/ui/menu.py b/trytond/ir/ui/menu.py index d5c06934bd..0f58cc80bb 100644 --- a/trytond/ir/ui/menu.py +++ b/trytond/ir/ui/menu.py @@ -72,7 +72,7 @@ class UIMenu(ModelSQL, ModelView): parent = fields.Many2One('ir.ui.menu', 'Parent Menu', select=1, ondelete='CASCADE') groups = fields.Many2Many('ir.ui.menu-res.group', - 'menu_id', 'gid', 'Groups') + 'menu', 'group', 'Groups') complete_name = fields.Function(fields.Char('Complete Name', order_field='name'), 'get_rec_name', searcher='search_rec_name') icon = fields.Selection('list_icons', 'Icon') diff --git a/trytond/res/group.py b/trytond/res/group.py index dbf117116a..a38a5a3edd 100644 --- a/trytond/res/group.py +++ b/trytond/res/group.py @@ -37,10 +37,10 @@ class Group(ModelSQL, ModelView): field_access = fields.One2Many('ir.model.field.access', 'group', 'Access Field') rule_groups = fields.Many2Many('ir.rule.group-res.group', - 'group_id', 'rule_group_id', 'Rules', + 'group', 'rule_group', 'Rules', domain=[('global_p', '!=', True), ('default_p', '!=', True)]) menu_access = MenuMany2Many('ir.ui.menu-res.group', - 'gid', 'menu_id', 'Access Menu') + 'group', 'menu', 'Access Menu') def __init__(self): super(Group, self).__init__() diff --git a/trytond/res/group.xml b/trytond/res/group.xml index bc026f21c4..7994141574 100644 --- a/trytond/res/group.xml +++ b/trytond/res/group.xml @@ -57,8 +57,13 @@ this repository contains the full copyright notices and license terms. --> - + + + + + diff --git a/trytond/res/ir.py b/trytond/res/ir.py index 9a17d04128..be83198305 100644 --- a/trytond/res/ir.py +++ b/trytond/res/ir.py @@ -10,9 +10,9 @@ class UIMenuGroup(ModelSQL): "UI Menu - Group" _name = 'ir.ui.menu-res.group' _description = __doc__ - menu_id = fields.Many2One('ir.ui.menu', 'Menu', ondelete='CASCADE', + menu = fields.Many2One('ir.ui.menu', 'Menu', ondelete='CASCADE', select=1, required=True) - gid = fields.Many2One('res.group', 'Group', ondelete='CASCADE', + group = fields.Many2One('res.group', 'Group', ondelete='CASCADE', select=1, required=True) def init(self, module_name): @@ -21,6 +21,10 @@ class UIMenuGroup(ModelSQL): TableHandler.table_rename(cursor, 'ir_ui_menu_group_rel', self._table) TableHandler.sequence_rename(cursor, 'ir_ui_menu_group_rel_id_seq', self._table + '_id_seq') + # Migration from 2.0 menu_id and gid renamed into menu group + table = TableHandler(cursor, self, module_name) + table.column_rename('menu_id', 'menu') + table.column_rename('gid', 'group') super(UIMenuGroup, self).init(module_name) def create(self, vals): @@ -48,9 +52,9 @@ class ActionGroup(ModelSQL): "Action - Group" _name = 'ir.action-res.group' _description = __doc__ - action_id = fields.Many2One('ir.action', 'Action', ondelete='CASCADE', + action = fields.Many2One('ir.action', 'Action', ondelete='CASCADE', select=1, required=True) - gid = fields.Many2One('res.group', 'Group', ondelete='CASCADE', + group = fields.Many2One('res.group', 'Group', ondelete='CASCADE', select=1, required=True) def init(self, module_name): @@ -59,15 +63,27 @@ class ActionGroup(ModelSQL): TableHandler.table_rename(cursor, 'ir_action_group_rel', self._table) TableHandler.sequence_rename(cursor, 'ir_action_group_rel_id_seq', self._table + '_id_seq') + # Migration from 2.0 action_id and gid renamed into action and group + table = TableHandler(cursor, self, module_name) + table.column_rename('action_id', 'action') + table.column_rename('gid', 'group') super(ActionGroup, self).init(module_name) def create(self, vals): + action_obj = Pool().get('ir.action') + if vals.get('action'): + vals = vals.copy() + vals['action'] = action_obj.get_action_id(vals['action']) res = super(ActionGroup, self).create(vals) # Restart the cache on the domain_get method Pool().get('ir.rule').domain_get.reset() return res def write(self, ids, vals): + action_obj = Pool().get('ir.action') + if vals.get('action'): + vals = vals.copy() + vals['action'] = action_obj.get_action_id(vals['action']) res = super(ActionGroup, self).write(ids, vals) # Restart the cache on the domain_get method Pool().get('ir.rule').domain_get.reset() @@ -106,9 +122,9 @@ class RuleGroupGroup(ModelSQL): "Rule Group - Group" _name = 'ir.rule.group-res.group' _description = __doc__ - rule_group_id = fields.Many2One('ir.rule.group', 'Rule Group', + rule_group = fields.Many2One('ir.rule.group', 'Rule Group', ondelete='CASCADE', select=1, required=True) - group_id = fields.Many2One('res.group', 'Group', ondelete='CASCADE', + group = fields.Many2One('res.group', 'Group', ondelete='CASCADE', select=1, required=True) def init(self, module_name): @@ -117,6 +133,11 @@ class RuleGroupGroup(ModelSQL): TableHandler.table_rename(cursor, 'group_rule_group_rel', self._table) TableHandler.sequence_rename(cursor, 'group_rule_group_rel_id_seq', self._table + '_id_seq') + # Migration from 2.0 rule_group_id and group_id renamed into rule_group + # and group + table = TableHandler(cursor, self, module_name) + table.column_rename('rule_group_id', 'rule_group') + table.column_rename('group_id', 'group') super(RuleGroupGroup, self).init(module_name) RuleGroupGroup() @@ -126,9 +147,9 @@ class RuleGroupUser(ModelSQL): "Rule Group - User" _name = 'ir.rule.group-res.user' _description = __doc__ - rule_group_id = fields.Many2One('ir.rule.group', 'Rule Group', + rule_group = fields.Many2One('ir.rule.group', 'Rule Group', ondelete='CASCADE', select=1, required=True) - user_id = fields.Many2One('res.user', 'User', ondelete='CASCADE', + user = fields.Many2One('res.user', 'User', ondelete='CASCADE', select=1, required=True) def init(self, module_name): @@ -137,6 +158,11 @@ class RuleGroupUser(ModelSQL): TableHandler.table_rename(cursor, 'user_rule_group_rel', self._table) TableHandler.sequence_rename(cursor, 'user_rule_group_rel_id_seq', self._table + '_id_seq') + # Migration from 2.0 rule_group_id and user_id renamed into rule_group + # and user + table = TableHandler(cursor, self, module_name) + table.column_rename('rule_group_id', 'rule_group') + table.column_rename('user_id', 'user') super(RuleGroupUser, self).init(module_name) RuleGroupUser() diff --git a/trytond/res/ir.xml b/trytond/res/ir.xml index 02ad948c85..c7e2d0c63e 100644 --- a/trytond/res/ir.xml +++ b/trytond/res/ir.xml @@ -425,141 +425,186 @@ this repository contains the full copyright notices and license terms. --> False - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + ir.module.module @@ -661,9 +706,12 @@ this repository contains the full copyright notices and license terms. --> user_cron_trigger Cron Trigger - + + + + Run On Time Triggers diff --git a/trytond/res/request.xml b/trytond/res/request.xml index 29819e440a..5c07884f83 100644 --- a/trytond/res/request.xml +++ b/trytond/res/request.xml @@ -90,8 +90,13 @@ this repository contains the full copyright notices and license terms. --> - + + + + + res.request.link form @@ -136,8 +141,12 @@ this repository contains the full copyright notices and license terms. --> - + + + + res.request.history diff --git a/trytond/res/user.py b/trytond/res/user.py index 36605d8c8a..ba5c002a9b 100644 --- a/trytond/res/user.py +++ b/trytond/res/user.py @@ -37,9 +37,9 @@ class User(ModelSQL, ModelView): menu = fields.Many2One('ir.action', 'Menu Action', domain=[('usage','=','menu')], required=True) groups = fields.Many2Many('res.user-res.group', - 'uid', 'gid', 'Groups') + 'user', 'group', 'Groups') rule_groups = fields.Many2Many('ir.rule.group-res.user', - 'user_id', 'rule_group_id', 'Rules', + 'user', 'rule_group', 'Rules', domain=[('global_p', '!=', True), ('default_p', '!=', True)]) language = fields.Many2One('ir.lang', 'Language', domain=['OR', ('translatable', '=', True), ('code', '=', 'en_US')]) @@ -403,9 +403,9 @@ class UserGroup(ModelSQL): 'User - Group' _name = 'res.user-res.group' _description = __doc__ - uid = fields.Many2One('res.user', 'User', ondelete='CASCADE', select=1, + user = fields.Many2One('res.user', 'User', ondelete='CASCADE', select=1, required=True) - gid = fields.Many2One('res.group', 'Group', ondelete='CASCADE', select=1, + group = fields.Many2One('res.group', 'Group', ondelete='CASCADE', select=1, required=True) def init(self, module_name): @@ -414,6 +414,10 @@ class UserGroup(ModelSQL): TableHandler.table_rename(cursor, 'res_group_user_rel', self._table) TableHandler.sequence_rename(cursor, 'res_group_user_rel_id_seq', self._table + '_id_seq') + # Migration from 2.0 uid and gid rename into user and group + table = TableHandler(cursor, self, module_name) + table.column_rename('uid', 'user') + table.column_rename('gid', 'group') super(UserGroup, self).init(module_name) UserGroup() @@ -422,7 +426,7 @@ UserGroup() class Group(ModelSQL, ModelView): "Group" _name = "res.group" - users = fields.Many2Many('res.user-res.group', 'gid', 'uid', 'Users') + users = fields.Many2Many('res.user-res.group', 'group', 'user', 'Users') Group() diff --git a/trytond/res/user.xml b/trytond/res/user.xml index 41b8b078bd..172b1cefb6 100644 --- a/trytond/res/user.xml +++ b/trytond/res/user.xml @@ -9,7 +9,10 @@ this repository contains the full copyright notices and license terms. --> Administrator - + + + + res.user @@ -119,8 +122,12 @@ this repository contains the full copyright notices and license terms. --> - + + + + diff --git a/trytond/webdav/webdav.xml b/trytond/webdav/webdav.xml index 7706a2ae2b..12a9c7d43f 100644 --- a/trytond/webdav/webdav.xml +++ b/trytond/webdav/webdav.xml @@ -3,8 +3,13 @@ this repository contains the full copyright notices and license terms. --> - + + + + + webdav.collection tree @@ -57,8 +62,12 @@ this repository contains the full copyright notices and license terms. --> - + + + + Collections @@ -77,7 +86,10 @@ this repository contains the full copyright notices and license terms. --> + action="act_collection_form" id="menu_collection_form"/> + + + + diff --git a/trytond/workflow/workflow.xml b/trytond/workflow/workflow.xml index ac4fc6ea26..31087c0115 100644 --- a/trytond/workflow/workflow.xml +++ b/trytond/workflow/workflow.xml @@ -4,7 +4,12 @@ this repository contains the full copyright notices and license terms. --> + parent="ir.menu_administration"/> + + + + + workflow form @@ -51,8 +56,13 @@ this repository contains the full copyright notices and license terms. --> - + + + + + @@ -180,8 +190,13 @@ this repository contains the full copyright notices and license terms. --> - + + + + + @@ -254,8 +269,13 @@ this repository contains the full copyright notices and license terms. --> - + + + + + @@ -322,8 +342,12 @@ this repository contains the full copyright notices and license terms. --> - + + + + workflow.workitem @@ -373,7 +397,11 @@ this repository contains the full copyright notices and license terms. --> - + + + +