diff --git a/bin/osv/fields.py b/bin/osv/fields.py index 51112a10048..e8c0c3b1ede 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -597,6 +597,9 @@ class function(_column): self._type = type self._fnct_search = fnct_search self.store = store + if store: + self._classic_read = True + self._classic_write = True if type == 'float': self._symbol_c = '%f' self._symbol_f = lambda x: __builtin__.float(x or 0.0) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 0803a7ace38..a4417552669 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1627,29 +1627,33 @@ class orm(orm_template): def __init__(self, cr): super(orm, self).__init__(cr) self._columns = self._columns.copy() - f = filter(lambda a: isinstance(self._columns[a], fields.function) and self._columns[a].store, self._columns) - if f: - list_store = [] - tuple_store = () - tuple_fn = () - for store_field in f: - if not self._columns[store_field].store == True: - dict_store = self._columns[store_field].store - key = dict_store.keys() - list_data = [] - for i in key: - tuple_store = self._name, store_field, self._columns[store_field]._fnct.__name__, tuple(dict_store[i][0]), dict_store[i][1], i - list_data.append(tuple_store) - #tuple_store=self._name,store_field,self._columns[store_field]._fnct.__name__,tuple(dict_store[key[0]][0]),dict_store[key[0]][1] - for l in list_data: - list_store = [] - if l[5] in self.pool._store_function.keys(): - self.pool._store_function[l[5]].append(l) - temp_list = list(set(self.pool._store_function[l[5]])) - self.pool._store_function[l[5]] = temp_list - else: - list_store.append(l) - self.pool._store_function[l[5]] = list_store + for store_field in self._columns: + f = self._columns[store_field] + if not isinstance(f, fields.function): + continue + if not f.store: + continue + if self._columns[store_field].store is True: + sm = {self._name:(lambda self,cr, uid, ids, c={}: ids, None)} + else: + sm = self._columns[store_field].store + for object, aa in sm.items(): + if len(aa)==2: + (fnct,fields2)=aa + order = 1 + elif len(aa)==3: + (fnct,fields2,order)=aa + else: + raise except_orm(_('Error'), + _('Invalid function definition %s in object %s !' % (store_field, self._name))) + self.pool._store_function.setdefault(object, []) + ok = True + for x,y,z,e,f in self.pool._store_function[object]: + if (x==self._name) and (y==store_field) and (e==fields2): + ok = False + if ok: + self.pool._store_function[object].append( (self._name, store_field, fnct, fields2, order)) + self.pool._store_function[object].sort(lambda x,y: cmp(x[4],y[4])) for (key, _, msg) in self._sql_constraints: self.pool._sql_error[self._table+'_'+key] = msg @@ -1978,15 +1982,8 @@ class orm(orm_template): ids = [ids] fn_list = [] - if self._name in self.pool._store_function.keys(): - list_store = self.pool._store_function[self._name] - fn_data = () - id_change = [] - for tuple_fn in list_store: - for id in ids: - id_change.append(self._store_get_ids(cr, uid, id, tuple_fn, context)[0]) - fn_data = id_change, tuple_fn - fn_list.append(fn_data) + for fnct in self.pool._store_function.get(self._name, []): + fn_list.append( (fnct[0], fnct[1], fnct[2](self,cr, uid, ids, context)) ) delta = context.get('read_delta', False) if delta and self._log_access: @@ -2033,10 +2030,9 @@ class orm(orm_template): else: cr.execute('delete from "'+self._table+'" ' \ 'where id in ('+str_d+')', sub_ids) - if fn_list: - for ids, tuple_fn in fn_list: - self._store_set_values(cr, uid, ids, tuple_fn, id_change, context) + for object,field,ids in fn_list: + self.pool.get(object)._store_set_values(cr, uid, ids, field, context) return True # @@ -2247,22 +2243,15 @@ class orm(orm_template): wf_service = netsvc.LocalService("workflow") for id in ids: wf_service.trg_write(user, self._name, id, cr) - self._update_function_stored(cr, user, ids, context=context) - - if self._name in self.pool._store_function.keys(): - list_store = self.pool._store_function[self._name] - for tuple_fn in list_store: - flag = False - if not tuple_fn[3]: - flag = True - for field in tuple_fn[3]: - if field in vals.keys(): - flag = True - break - if flag: - id_change = self._store_get_ids(cr, user, ids[0], tuple_fn, context) - self._store_set_values(cr, user, ids[0], tuple_fn, id_change, context) + for fnct in self.pool._store_function.get(self._name, []): + ok = False + for key in vals.keys(): + if (not fnct[3]) or (key in fnct[3]): + ok = True + if ok: + ids2 = fnct[2](self,cr, user, ids, context) + self.pool.get(fnct[0])._store_set_values(cr, user, ids2, fnct[1], context) return True # @@ -2369,54 +2358,34 @@ class orm(orm_template): wf_service = netsvc.LocalService("workflow") wf_service.trg_create(user, self._name, id_new, cr) - self._update_function_stored(cr, user, [id_new], context=context) - if self._name in self.pool._store_function.keys(): - list_store = self.pool._store_function[self._name] - for tuple_fn in list_store: - id_change = self._store_get_ids(cr, user, id_new, tuple_fn, context) - self._store_set_values(cr, user, id_new, tuple_fn, id_change, context) + for fnct in self.pool._store_function.get(self._name, []): + ids2 = fnct[2](self,cr, user, [id_new], context) + self.pool.get(fnct[0])._store_set_values(cr, user, ids2, fnct[1], context) return id_new def _store_get_ids(self, cr, uid, ids, tuple_fn, context): - parent_id = getattr(self.pool.get(tuple_fn[0]), tuple_fn[4].func_name)(cr, uid, [ids]) + parent_id = getattr(self.pool.get(tuple_fn[0]), tuple_fn[4].func_name)(cr, uid, ids, context) return parent_id - def _store_set_values(self, cr, uid, ids, tuple_fn, parent_id, context): - name = tuple_fn[1] - table = tuple_fn[0] + def _store_set_values(self, cr, uid, ids, field, context): args = {} - vals_tot = getattr(self.pool.get(table), tuple_fn[2])(cr, uid, parent_id, name, args, context) - write_dict = {} - for id in vals_tot.keys(): - write_dict[name] = vals_tot[id] - self.pool.get(table).write(cr, uid, [id], write_dict) - return True - - def _update_function_stored(self, cr, user, ids, context=None): - if not context: - context = {} - f = filter(lambda a: isinstance(self._columns[a], fields.function) \ - and self._columns[a].store, self._columns) - if f: - result = self.read(cr, user, ids, fields=f, context=context) - for res in result: - upd0 = [] - upd1 = [] - for field in res: - if field not in f: - continue - value = res[field] - if self._columns[field]._type in ('many2one', 'one2one'): - try: - value = res[field][0] - except: - value = res[field] - upd0.append('"'+field+'"='+self._columns[field]._symbol_set[0]) - upd1.append(self._columns[field]._symbol_set[1](value)) - upd1.append(res['id']) - cr.execute('update "' + self._table + '" set ' + \ - string.join(upd0, ',') + ' where id = %d', upd1) + result = self._columns[field].get(cr, self, ids, field, uid, context=context) + for id,value in result.items(): + upd0 = [] + upd1 = [] + if self._columns[field]._multi: + value = value[field] + if self._columns[field]._type in ('many2one', 'one2one'): + try: + value = value[0] + except: + pass + upd0.append('"'+field+'"='+self._columns[field]._symbol_set[0]) + upd1.append(self._columns[field]._symbol_set[1](value)) + upd1.append(id) + cr.execute('update "' + self._table + '" set ' + \ + string.join(upd0, ',') + ' where id = %d', upd1) return True #