From 7b8afc298a9dc9f35b4dd1594892ea4ea6e0605b Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Thu, 20 Aug 2009 17:29:21 +0200 Subject: [PATCH] [IMP] Speed impprovement: 2x faster for flow: sale -> invoice -> payment bzr revid: fp@tinyerp.com-20090820152921-ntnzn2tqo1bhiss1 --- bin/osv/fields.py | 11 ++++++++++- bin/osv/orm.py | 28 +++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/bin/osv/fields.py b/bin/osv/fields.py index 51b5dd1c51e..ee235e95eca 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -53,6 +53,7 @@ def _symbol_set(symb): class _column(object): _classic_read = True _classic_write = True + _prefetch = True _properties = False _type = 'unknown' _obj = None @@ -196,6 +197,7 @@ class binary(_column): _symbol_get = lambda self, x: x and str(x) _classic_read = False + _prefetch = False def __init__(self, string='unknown', filters=None, **args): _column.__init__(self, string=string, **args) @@ -350,6 +352,7 @@ class many2one(_column): class one2many(_column): _classic_read = False _classic_write = False + _prefetch = False _type = 'one2many' def __init__(self, obj, fields_id, string='unknown', limit=None, **args): @@ -426,11 +429,13 @@ class one2many(_column): return res def set(self, cr, obj, id, field, values, user=None, context=None): + result = [] if not context: context = {} if self._context: context = context.copy() context.update(self._context) + context['no_store_function'] = True if not values: return _table = obj.pool.get(self._obj)._table @@ -438,7 +443,8 @@ class one2many(_column): for act in values: if act[0] == 0: act[2][self._fields_id] = id - obj.create(cr, user, act[2], context=context) + id_new = obj.create(cr, user, act[2], context=context) + result += obj._store_get_values(cr, user, [id_new], act[2].keys(), context) elif act[0] == 1: obj.write(cr, user, [act[1]], act[2], context=context) elif act[0] == 2: @@ -455,6 +461,7 @@ class one2many(_column): cr.execute('select id from '+_table+' where '+self._fields_id+'=%s and id not in ('+','.join(map(str, ids2))+')', (id,)) ids3 = map(lambda x:x[0], cr.fetchall()) obj.write(cr, user, ids3, {self._fields_id:False}, context=context or {}) + return result def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like'): return obj.pool.get(self._obj).name_search(cr, uid, value, self._domain, offset, limit) @@ -472,6 +479,7 @@ class one2many(_column): class many2many(_column): _classic_read = False _classic_write = False + _prefetch = False _type = 'many2many' def __init__(self, obj, rel, id1, id2, string='unknown', limit=None, **args): @@ -582,6 +590,7 @@ class many2many(_column): class function(_column): _classic_read = False _classic_write = False + _prefetch = False _type = 'function' _properties = True diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 4899ab48f4b..9ed0087415f 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -174,7 +174,7 @@ class browse_record(object): return False # if the field is a classic one or a many2one, we'll fetch all classic and many2one fields - if col._classic_write: + if col._prefetch: # gen the list of "local" (ie not inherited) fields which are classic or many2one ffields = filter(lambda x: x[1]._classic_write, self._table._columns.items()) # gen the list of inherited fields @@ -2345,6 +2345,7 @@ class orm(orm_template): if not edit: vals.pop(field) + if not context: context = {} if not ids: @@ -2356,6 +2357,7 @@ class orm(orm_template): self.pool.get('ir.model.access').check(cr, user, self._name, 'write', context=context) + upd0 = [] upd1 = [] upd_todo = [] @@ -2432,6 +2434,7 @@ class orm(orm_template): src_trans = self.pool.get(self._name).read(cr,user,ids,[f]) self.pool.get('ir.translation')._set_ids(cr, user, self._name+','+f, 'model', context['lang'], ids, vals[f], src_trans[0][f]) + # call the 'set' method of fields which are not classic_write upd_todo.sort(lambda x, y: self._columns[x].priority-self._columns[y].priority) @@ -2649,13 +2652,19 @@ class orm(orm_template): if c[0].startswith('default_'): del rel_context[c[0]] + result = [] for field in upd_todo: - self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context) + result += self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context) or [] self._validate(cr, user, [id_new], context) - result = self._store_get_values(cr, user, [id_new], vals.keys(), context) - for order, object, ids, fields2 in result: - self.pool.get(object)._store_set_values(cr, user, ids, fields2, context) + if not context.get('no_store_function', False): + result += self._store_get_values(cr, user, [id_new], vals.keys(), context) + result.sort() + done = [] + for order, object, ids, fields2 in result: + if not (object, ids, fields2) in done: + self.pool.get(object)._store_set_values(cr, user, ids, fields2, context) + done.append((object, ids, fields2)) wf_service = netsvc.LocalService("workflow") wf_service.trg_create(user, self._name, id_new, cr) @@ -2665,6 +2674,15 @@ class orm(orm_template): result = {} fncts = self.pool._store_function.get(self._name, []) for fnct in range(len(fncts)): + if fncts[fnct][3]: + ok = False + for f in (fields or []): + if f in fncts[fnct][3]: + ok = True + break + if not ok: + continue + result.setdefault(fncts[fnct][0], {}) ids2 = fncts[fnct][2](self,cr, uid, ids, context) for id in filter(None, ids2):