Merge lp:~therp-nl/openobject-addons/7.0-lp1078689-audittrail_bad_performance_and_infinit_recursion into lp:openobject-addons

Proposed by Stefan Rijnhart (Opener)
Status: Needs review
Proposed branch: lp:~therp-nl/openobject-addons/7.0-lp1078689-audittrail_bad_performance_and_infinit_recursion
Merge into: lp:openobject-addons
Diff against target: 80 lines (+12/-6)
1 file modified
audittrail/audittrail.py (+12/-6)
To merge this branch: bzr merge lp:~therp-nl/openobject-addons/7.0-lp1078689-audittrail_bad_performance_and_infinit_recursion
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+134290@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

8034. By Stefan Rijnhart (Opener)

[FIX] Audittrail: bad performance and infinite recursion

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'audittrail/audittrail.py'
--- audittrail/audittrail.py 2012-11-12 08:40:18 +0000
+++ audittrail/audittrail.py 2012-11-14 12:20:30 +0000
@@ -174,6 +174,8 @@
174class audittrail_objects_proxy(object_proxy):174class audittrail_objects_proxy(object_proxy):
175 """ Uses Object proxy for auditing changes on object of subscribed Rules"""175 """ Uses Object proxy for auditing changes on object of subscribed Rules"""
176176
177 _default_recursive_level = 1
178
177 def get_value_text(self, cr, uid, pool, resource_pool, method, field, value):179 def get_value_text(self, cr, uid, pool, resource_pool, method, field, value):
178 """180 """
179 Gets textual values for the fields.181 Gets textual values for the fields.
@@ -303,7 +305,7 @@
303 self.process_data(cr, uid_orig, pool, res_ids, model, method, old_values, new_values, field_list)305 self.process_data(cr, uid_orig, pool, res_ids, model, method, old_values, new_values, field_list)
304 return res306 return res
305307
306 def get_data(self, cr, uid, pool, res_ids, model, method):308 def get_data(self, cr, uid, pool, res_ids, model, method, recursive_level=None):
307 """309 """
308 This function simply read all the fields of the given res_ids, and also recurisvely on310 This function simply read all the fields of the given res_ids, and also recurisvely on
309 all records of a x2m fields read that need to be logged. Then it returns the result in311 all records of a x2m fields read that need to be logged. Then it returns the result in
@@ -322,6 +324,8 @@
322 },324 },
323 }325 }
324 """326 """
327 if recursive_level is None:
328 recursive_level = self._default_recursive_level
325 data = {}329 data = {}
326 resource_pool = pool.get(model.model)330 resource_pool = pool.get(model.model)
327 # read all the fields of the given resources in super admin mode331 # read all the fields of the given resources in super admin mode
@@ -338,7 +342,7 @@
338 values_text[field] = self.get_value_text(cr, SUPERUSER_ID, pool, resource_pool, method, field, resource[field])342 values_text[field] = self.get_value_text(cr, SUPERUSER_ID, pool, resource_pool, method, field, resource[field])
339343
340 field_obj = resource_pool._all_columns.get(field).column344 field_obj = resource_pool._all_columns.get(field).column
341 if field_obj._type in ('one2many','many2many'):345 if field_obj._type in ('one2many','many2many') and recursive_level:
342 # check if an audittrail rule apply in super admin mode346 # check if an audittrail rule apply in super admin mode
343 if self.check_rules(cr, SUPERUSER_ID, field_obj._obj, method):347 if self.check_rules(cr, SUPERUSER_ID, field_obj._obj, method):
344 # check if the model associated to a *2m field exists, in super admin mode348 # check if the model associated to a *2m field exists, in super admin mode
@@ -347,11 +351,11 @@
347 assert x2m_model_id, _("'%s' Model does not exist..." %(field_obj._obj))351 assert x2m_model_id, _("'%s' Model does not exist..." %(field_obj._obj))
348 x2m_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, x2m_model_id)352 x2m_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, x2m_model_id)
349 #recursive call on x2m fields that need to be checked too353 #recursive call on x2m fields that need to be checked too
350 data.update(self.get_data(cr, SUPERUSER_ID, pool, resource[field], x2m_model, method))354 data.update(self.get_data(cr, SUPERUSER_ID, pool, resource[field], x2m_model, method, recursive_level - 1))
351 data[(model.id, resource_id)] = {'text':values_text, 'value': values}355 data[(model.id, resource_id)] = {'text':values_text, 'value': values}
352 return data356 return data
353357
354 def prepare_audittrail_log_line(self, cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=None):358 def prepare_audittrail_log_line(self, cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=None, recursive_level=None):
355 """359 """
356 This function compares the old data (i.e before the method was executed) and the new data360 This function compares the old data (i.e before the method was executed) and the new data
357 (after the method was executed) and returns a structure with all the needed information to361 (after the method was executed) and returns a structure with all the needed information to
@@ -380,6 +384,8 @@
380 The reason why the structure returned is build as above is because when modifying an existing384 The reason why the structure returned is build as above is because when modifying an existing
381 record, we may have to log a change done in a x2many field of that object385 record, we may have to log a change done in a x2many field of that object
382 """386 """
387 if recursive_level is None:
388 recursive_level = self._default_recursive_level
383 if field_list is None:389 if field_list is None:
384 field_list = []390 field_list = []
385 key = (model.id, resource_id)391 key = (model.id, resource_id)
@@ -394,7 +400,7 @@
394 if field_list and field_name not in field_list:400 if field_list and field_name not in field_list:
395 continue401 continue
396 field_obj = field_definition.column402 field_obj = field_definition.column
397 if field_obj._type in ('one2many','many2many'):403 if field_obj._type in ('one2many','many2many') and recursive_level:
398 # checking if an audittrail rule apply in super admin mode404 # checking if an audittrail rule apply in super admin mode
399 if self.check_rules(cr, SUPERUSER_ID, field_obj._obj, method):405 if self.check_rules(cr, SUPERUSER_ID, field_obj._obj, method):
400 # checking if the model associated to a *2m field exists, in super admin mode406 # checking if the model associated to a *2m field exists, in super admin mode
@@ -409,7 +415,7 @@
409 # We use list(set(...)) to remove duplicates.415 # We use list(set(...)) to remove duplicates.
410 res_ids = list(set(x2m_old_values_ids + x2m_new_values_ids))416 res_ids = list(set(x2m_old_values_ids + x2m_new_values_ids))
411 for res_id in res_ids:417 for res_id in res_ids:
412 lines.update(self.prepare_audittrail_log_line(cr, SUPERUSER_ID, pool, x2m_model, res_id, method, old_values, new_values, field_list))418 lines.update(self.prepare_audittrail_log_line(cr, SUPERUSER_ID, pool, x2m_model, res_id, method, old_values, new_values, field_list, recursive_level=recursive_level - 1))
413 # if the value value is different than the old value: record the change419 # if the value value is different than the old value: record the change
414 if key not in old_values or key not in new_values or old_values[key]['value'][field_name] != new_values[key]['value'][field_name]:420 if key not in old_values or key not in new_values or old_values[key]['value'][field_name] != new_values[key]['value'][field_name]:
415 data = {421 data = {

Subscribers

People subscribed via source and target branches

to all changes: