Merge lp:~therp-nl/openobject-server/ronald@therp.nl_fix_ir_ui_view_arch_lp925840-6.1 into lp:openobject-server

Proposed by Ronald Portier (Therp)
Status: Rejected
Rejected by: Olivier Dony (Odoo)
Proposed branch: lp:~therp-nl/openobject-server/ronald@therp.nl_fix_ir_ui_view_arch_lp925840-6.1
Merge into: lp:openobject-server
Diff against target: 71 lines (+47/-1)
1 file modified
openerp/addons/base/ir/ir_ui_view.py (+47/-1)
To merge this branch: bzr merge lp:~therp-nl/openobject-server/ronald@therp.nl_fix_ir_ui_view_arch_lp925840-6.1
Reviewer Review Type Date Requested Status
Raphael Collet (OpenERP) (community) Disapprove
Review via email: mp+91579@code.launchpad.net

Description of the change

Fix problems caused by excessive whitespace in arch field of ir_ui_view.

As a bonus the arch view will be much more compact. Check in psql with:

# select sum(length(arch)) as sum from ir_ui_view;

Before fix: 199.472

After fix: 118.180

This is bound to have a very positive influence on performance.

To post a comment you must log in.
Revision history for this message
Raphael Collet (OpenERP) (rco-openerp) wrote :

Stripping all whitespaces in views is inadequate. It is common to edit a view with the views form. There, you want to keep the indentation of the XML in the field 'arch'.

Note that the impact of reducing the size of views on performance is negligible. (The number of queries sent to the DBMS has much more impact than the size of the results.)

review: Disapprove
Revision history for this message
Olivier Dony (Odoo) (odo-openerp) wrote :

Hello Ronald,

I agree with Raphael, stripping whitespace from views is very annoying for customizations, and we should rather address the whitespace issue you have found (please report a bug for it if this is a problem in the OpenERP framework), rather than blindly strip whitespace. As Raphael says, the storage and network transfer difference are rather negligible.

I hope you understand our point of view...

The numerous contributions from Therp are of great quality and really appreciated, thanks a lot for your efforts!

Unmerged revisions

4000. By Ronald Portier (Therp)

[FIX] Prevent errors caused by trailing whitespace in arch field. As a bonus, stored field will be much more compact.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/addons/base/ir/ir_ui_view.py'
2--- openerp/addons/base/ir/ir_ui_view.py 2012-01-04 13:30:27 +0000
3+++ openerp/addons/base/ir/ir_ui_view.py 2012-02-05 16:15:22 +0000
4@@ -19,8 +19,10 @@
5 #
6 ##############################################################################
7
8+import sys
9 from osv import fields,osv
10 from lxml import etree
11+from StringIO import StringIO
12 from tools import graph
13 from tools.safe_eval import safe_eval as eval
14 import tools
15@@ -110,11 +112,55 @@
16 (view_id, model))
17 return cr.fetchall()
18
19+ _parser = etree.XMLParser(remove_blank_text=True, encoding='utf-8')
20+
21+ def _strip_tree(self, arch):
22+ if 'encoding' in arch:
23+ return arch # parsing no supported for strings containg encoding
24+ source = etree.parse(StringIO(arch), self._parser)
25+ for element in source.iter('*'):
26+ # Strip white space from element:
27+ if element.text is not None:
28+ strip_text = element.text.strip()
29+ if strip_text:
30+ element.text = strip_text
31+ else:
32+ element.text = None
33+ # Strip whitespace from attributes:
34+ for atr_key, atr_value in element.attrib.items():
35+ if atr_key and atr_value:
36+ element.set(atr_key, atr_value.strip())
37+ return etree.tostring(source.getroot())
38+
39+ '''Override create and write method to make sure that the field arch is
40+ stored in as compact a way as possible. This will not only improve
41+ runtime performance, but also solve bugs due to spurious whitespace.
42+ '''
43+ def _compute_vals(self, cr, uid, view_id, vals):
44+ try:
45+ # We really should have an arch field - otherwise no point in
46+ # having a view, but check regardless...
47+ if 'arch' in vals and vals['arch']:
48+ vals['arch'] = self._strip_tree(vals['arch'])
49+ except:
50+ logging.getLogger('ir_ui_view').debug(
51+ '_compute_vals : Error computing vals: %s' %
52+ str(sys.exc_info()[0]))
53+ logging.getLogger('ir_ui_view').debug(
54+ '_compute_vals : vals: %s' % str(vals))
55+ raise Exception("_compute_vals abnormally ended")
56+
57+ def create(self, cr, uid, vals, context=None):
58+ self._compute_vals(cr, uid, 0, vals)
59+ view_id = super(view, self).create(cr, uid, vals, context)
60+ return view_id
61+
62 def write(self, cr, uid, ids, vals, context=None):
63 if not isinstance(ids, (list, tuple)):
64 ids = [ids]
65+ for view_id in ids:
66+ self._compute_vals(cr, uid, view_id, vals)
67 result = super(view, self).write(cr, uid, ids, vals, context)
68-
69 # drop the corresponding view customizations (used for dashboards for example), otherwise
70 # not all users would see the updated views
71 custom_view_ids = self.pool.get('ir.ui.view.custom').search(cr, uid, [('ref_id','in',ids)])