Speed Improvement ORM

Better Store={...}

bzr revid: fp@tinyerp.com-20081207021654-wfgrjy7tj3ukgopv
This commit is contained in:
Fabien Pinckaers 2008-12-07 03:16:54 +01:00
parent bcca622a6e
commit dfbcd29e8e
2 changed files with 63 additions and 91 deletions

View File

@ -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)

View File

@ -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
#