From 70a3ff61c8ec7486e3528b6950fb2bc16e8c1cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 3 Dec 2008 17:30:12 +0100 Subject: [PATCH 1/9] Fix query to fetch constrains definitions --- trytond/sql_db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trytond/sql_db.py b/trytond/sql_db.py index 8e557f1584..c21fdd7c86 100644 --- a/trytond/sql_db.py +++ b/trytond/sql_db.py @@ -269,7 +269,7 @@ class table_handler: "LEFT JOIN pg_class cl on (co.conrelid = cl.oid) "\ "LEFT JOIN pg_class cl2 on (co.confrelid = cl2.oid) "\ "LEFT JOIN pg_attribute at on (co.conkey[1] = at.attnum) "\ - "WHERE cl.relname = %s", + "WHERE cl.relname = %s AND at.attrelid = cl.oid", (self.table_name,)) self.constraint = [] self.fk_deltype = {} From 411e5434095416ee4799679136079a5a00df58f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 3 Dec 2008 21:18:59 +0100 Subject: [PATCH 2/9] Fix check_xml_record for inherited model data for issue639 --- trytond/osv/orm.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/trytond/osv/orm.py b/trytond/osv/orm.py index b74a379496..77332f4516 100644 --- a/trytond/osv/orm.py +++ b/trytond/osv/orm.py @@ -1539,6 +1539,8 @@ class ORM(object): if values == None: return False for line in cursor.fetchall(): + if not line[0]: + continue xml_values = eval(line[0], { 'Decimal': Decimal, 'datetime': datetime, From 61727f1ab5639267267f2e139d2e54606429c572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 3 Dec 2008 22:13:54 +0100 Subject: [PATCH 3/9] Add values to model data records for inherited records --- trytond/tools/convert.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/trytond/tools/convert.py b/trytond/tools/convert.py index 452034ccba..5b50196ec4 100644 --- a/trytond/tools/convert.py +++ b/trytond/tools/convert.py @@ -519,6 +519,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): [self.fs2db.get(module, fs_id)[x] for x in \ ["db_id","model","id","values"]] inherit_db_ids = {} + inherit_mdata_ids = [] if not old_values: old_values = {} @@ -582,13 +583,14 @@ class TrytondXmlHandler(sax.handler.ContentHandler): 'inherit': True, }) else: - self.modeldata_obj.create(cursor, user, { + data_id = self.modeldata_obj.create(cursor, user, { 'fs_id': fs_id, 'module': module, 'model': table, 'db_id': inherit_db_ids[table], 'inherit': True, }) + inherit_mdata_ids.append((table, data_id)) data_id = self.modeldata_obj.search(cursor, user, [ ('fs_id', '=', fs_id), @@ -654,6 +656,14 @@ class TrytondXmlHandler(sax.handler.ContentHandler): for table, field_name, field in \ object_ref._inherit_fields.values(): inherit_db_ids[table] = object[field_name].id + if not inherit_mdata_ids: + for table in inherit_db_ids.keys(): + data_id = self.modeldata_obj.search(cursor, user, [ + ('fs_id', '=', fs_id), + ('module', '=', module), + ('model', '=', table), + ], limit=1) + inherit_mdata_ids.append((table, data_id)) #Update/Create translation record for field translatable for field_name in object_ref._columns.keys() + \ @@ -716,6 +726,15 @@ class TrytondXmlHandler(sax.handler.ContentHandler): 'values': values, 'date_update': time.strftime('%Y-%m-%d %H:%M:%S'), }) + for table, inherit_mdata_id in inherit_mdata_ids: + self.modeldata_obj.write(cursor, user, inherit_mdata_id, { + 'fs_id': fs_id, + 'model': table, + 'module': module, + 'db_id': inherit_db_ids[table], + 'values': values, + 'date_update': time.strftime('%Y-%m-%d %H:%M:%S'), + }) else: # this record is new, create it in the db: @@ -778,6 +797,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): 'model': table, 'module': module, 'db_id': inherit_db_ids[table], + 'values': str(values), 'inherit': True, }) From a25fa01292ea92d0b7ba8f5bb72503bb103f45f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 4 Dec 2008 15:41:31 +0100 Subject: [PATCH 4/9] Add some todo's --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index 24f95bdd2c..21f3b97e03 100644 --- a/TODO +++ b/TODO @@ -5,3 +5,6 @@ - Improve encoding of default properties - Use real view in get_preferences_fields_view of res.user - Add fields use in states and domain in fields_view_get +- Add on one2many a domain per field of the relation +- Use determined action name in workflow like for default value +- Add check for index and constraint name lenght (limit 31) From 25b4e9d6c071418c5067180392603bc82bc8272d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 4 Dec 2008 18:08:46 +0100 Subject: [PATCH 5/9] Add todo for _constraint --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 21f3b97e03..b318624db8 100644 --- a/TODO +++ b/TODO @@ -8,3 +8,4 @@ - Add on one2many a domain per field of the relation - Use determined action name in workflow like for default value - Add check for index and constraint name lenght (limit 31) +- Change _constraint to pass a BrowseRecordList instead of a list of ids From b129a3d47f9ea675feab2dabea9b6b997739c3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 4 Dec 2008 18:09:58 +0100 Subject: [PATCH 6/9] Add get_groups with cache on res.user for workflow check of groups --- trytond/res/group.py | 2 ++ trytond/res/user.py | 17 +++++++++++++++++ trytond/wkf_service/wkf_expr.py | 3 +-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/trytond/res/group.py b/trytond/res/group.py index 706dd63d7b..31b379b0b3 100644 --- a/trytond/res/group.py +++ b/trytond/res/group.py @@ -27,6 +27,8 @@ class Group(OSV): context=context) # Restart the cache on the domain_get method self.pool.get('ir.rule').domain_get(cursor.dbname) + # Restart the cache for get_groups + self.pool.get('res.user').get_groups(cursor.dbname) return res Group() diff --git a/trytond/res/user.py b/trytond/res/user.py index b499e2d389..06e90fe4db 100644 --- a/trytond/res/user.py +++ b/trytond/res/user.py @@ -5,6 +5,7 @@ import copy from trytond.osv import fields, OSV from trytond.wizard import Wizard, WizardOSV from lxml import etree +from trytond.tools import Cache class User(OSV): @@ -122,6 +123,8 @@ class User(OSV): res = super(User, self).write(cursor, user, ids, vals, context=context) # Restart the cache for domain_get method self.pool.get('ir.rule').domain_get(cursor.dbname) + # Restart the cache for get_groups + self.get_groups(cursor.dbname) return res def delete(self, cursor, user, ids, context=None): @@ -266,6 +269,20 @@ class User(OSV): res = [] return res + def get_groups(self, cursor, user, context=None): + ''' + Return a list of group ids for the user + + :param cursor: the database cursor + :param user: the user id + :param context: the context + :return: a list of group ids + ''' + return self.read(cursor, user, user, ['groups'], + context=context)['groups'] + + get_groups = Cache('res_user.get_groups')(get_groups) + User() diff --git a/trytond/wkf_service/wkf_expr.py b/trytond/wkf_service/wkf_expr.py index 0fba6cc73a..1cc2e83eff 100644 --- a/trytond/wkf_service/wkf_expr.py +++ b/trytond/wkf_service/wkf_expr.py @@ -71,8 +71,7 @@ def check(cursor, ident, transition, signal, context=None): user = ident[0] if transition['group'] and user != 0: user_obj = pooler.get_pool(cursor.dbname).get('res.user') - user_groups = user_obj.read(cursor, user, user, ['groups'], - context=context)['groups'] + user_groups = user_obj.get_groups(cursor, user, context=context) res = res and transition['group'] in user_groups res = res and eval_expr(cursor, ident, transition['condition'], context=context) From 2cda3c591e99be21005fc80158b0734bcd450a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 4 Dec 2008 18:25:58 +0100 Subject: [PATCH 7/9] Improve Cache when function return None or False --- trytond/tools/misc.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/trytond/tools/misc.py b/trytond/tools/misc.py index 56da2906f2..2a3a80e0db 100644 --- a/trytond/tools/misc.py +++ b/trytond/tools/misc.py @@ -251,6 +251,7 @@ class Cache(object): def cached_result(self2, cursor=None, *args, **kwargs): result = None + find = False if isinstance(cursor, basestring): Cache.reset(cursor, self.name) self.lock.acquire() @@ -298,10 +299,11 @@ class Cache(object): mintime = time.time() - self.timeout if self.timeout <= 0 or mintime <= last_time: result = value + find = True finally: self.lock.release() - if not result: + if not find: # Work out new value, cache it and return it # Should copy() this value to avoid futur modf of the cacle ? result = function(self2, cursor, **dict(kwargs)) From 2c2d0003b2c3509cfb1cd09b3c51397921cd819b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 5 Dec 2008 13:22:09 +0100 Subject: [PATCH 8/9] Allow to use a list of id for copy method --- CHANGELOG | 1 + trytond/osv/orm.py | 57 ++++++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5fb3662828..2804bd01bc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Allow to use a list of id for copy method * Use one lock per database * Improve netrpc communication speed * Add contextual domain on inherited views diff --git a/trytond/osv/orm.py b/trytond/osv/orm.py index 77332f4516..791c9fb7dc 100644 --- a/trytond/osv/orm.py +++ b/trytond/osv/orm.py @@ -3001,17 +3001,29 @@ class ORM(object): res = self.name_get(cursor, user, ids, context=context) return res - def copy(self, cursor, user, object_id, default=None, context=None): + def copy(self, cursor, user, ids, default=None, context=None): ''' - Duplicate the object_id record. - default can be a dict with field name as keys, - it will replace the value of the record. + Duplicate the record in ids. + + :param cursor: the database cursor + :param user: the user id + :param ids: a list of ids or an id + :param default: a dictionnary with field name as keys and + new value for the field as value + :param context: the context + :return: a list of new ids or the new id ''' lang_obj = self.pool.get('ir.lang') if default is None: default = {} if context is None: context = {} + + int_id = False + if isinstance(ids, (int, long)): + int_id = True + ids = [ids] + if 'state' not in default: if 'state' in self._defaults: default['state'] = self._defaults['state'](cursor, user, @@ -3042,13 +3054,11 @@ class ORM(object): elif ftype in ('one2many',): res = [] rel = self.pool.get(fields[field_name]['relation']) - for rel_id in data[field_name] or []: - # the lines are first duplicated using the wrong (old) - # parent but then are reassigned to the correct one thanks - # to the ('add', ...) - res.append(('add', rel.copy(cursor, user, rel_id, - context=context))) - data[field_name] = res + if data[field_name]: + data[field_name] = [('add', rel.copy(cursor, user, + data[field_name], context=context))] + else: + data[field_name] = False elif ftype == 'many2many': if data[field_name]: data[field_name] = [('set', data[field_name])] @@ -3058,10 +3068,12 @@ class ORM(object): if self._inherits[i] in data: del data[self._inherits[i]] - data = self.read(cursor, user, object_id, context=context) - fields = self.fields_get(cursor, user) - convert_data(fields, data) - new_id = self.create(cursor, user, data, context=context) + new_ids = [] + datas = self.read(cursor, user, ids, context=context) + fields = self.fields_get(cursor, user, context=context) + for data in datas: + convert_data(fields, data) + new_ids.append(self.create(cursor, user, data, context=context)) fields_translate = {} for field_name, field in fields.iteritems(): @@ -3084,11 +3096,16 @@ class ORM(object): for lang in langs: ctx = context.copy() ctx['language'] = lang.code - data = self.read(cursor, user, object_id, - fields_names=fields_translate.keys(), context=ctx) - convert_data(fields_translate, data) - self.write(cursor, user, new_id, data, context=ctx) - return new_id + datas = self.read(cursor, user, ids, + fields_names=fields_translate.keys() + ['id'], + context=ctx) + for data in datas: + data_id = data['id'] + convert_data(fields_translate, data) + self.write(cursor, user, data_id, data, context=ctx) + if int_id: + return new_ids[0] + return new_ids def search_read(self, cursor, user, args, offset=0, limit=None, order=None, context=None, fields_names=None, load='_classic_read'): From 406eabce43cfb681b56315aa48f48c621ced6d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 5 Dec 2008 18:30:54 +0100 Subject: [PATCH 9/9] Use id to update of strings from view --- trytond/ir/ui/view.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/trytond/ir/ui/view.py b/trytond/ir/ui/view.py index deba184254..a16b9b9b71 100644 --- a/trytond/ir/ui/view.py +++ b/trytond/ir/ui/view.py @@ -120,12 +120,8 @@ class View(OSV): cursor.execute('UPDATE ir_translation ' \ 'SET src = %s, ' \ 'fuzzy = True ' \ - 'WHERE name = %s ' \ - 'AND type = %s ' \ - 'AND src = %s '\ - 'AND module = %s', - (string, view.model, 'view', string_trans, - view.module)) + 'WHERE id = %s ', + (string, trans_views[string_trans]['id'])) del trans_views[string_trans] done = True break