Merge lp:~openerp-dev/openobject-server/6.1-opw-577963-odo into lp:openobject-server/6.1

Proposed by Xavier ALT
Status: Merged
Approved by: Xavier ALT
Approved revision: 4261
Merged at revision: 4260
Proposed branch: lp:~openerp-dev/openobject-server/6.1-opw-577963-odo
Merge into: lp:openobject-server/6.1
Diff against target: 37 lines (+13/-4)
1 file modified
openerp/addons/base/ir/ir_attachment.py (+13/-4)
To merge this branch: bzr merge lp:~openerp-dev/openobject-server/6.1-opw-577963-odo
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+120586@code.launchpad.net

Description of the change

Hi,

This improve the speed of ir.attachment search() method - making this usable for database with 100k+ attachments.
(coutesy of Mr. Olivier Dony)

Regards,
Xavier

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openerp/addons/base/ir/ir_attachment.py'
--- openerp/addons/base/ir/ir_attachment.py 2012-06-27 08:57:09 +0000
+++ openerp/addons/base/ir/ir_attachment.py 2012-08-21 14:46:23 +0000
@@ -64,10 +64,18 @@
64 return 064 return 0
65 return []65 return []
6666
67 # Work with a set, as list.remove() is prohibitive for large lists of documents
68 # (takes 20+ seconds on a db with 100k docs during search_count()!)
69 orig_ids = ids
70 ids = set(ids)
71
67 # For attachments, the permissions of the document they are attached to72 # For attachments, the permissions of the document they are attached to
68 # apply, so we must remove attachments for which the user cannot access73 # apply, so we must remove attachments for which the user cannot access
69 # the linked document.74 # the linked document.
70 targets = super(ir_attachment,self).read(cr, uid, ids, ['id', 'res_model', 'res_id'])75 # Use pure SQL rather than read() as it is about 50% faster for large dbs (100k+ docs),
76 # and the permissions are checked in super() and below anyway.
77 cr.execute("""SELECT id, res_model, res_id FROM ir_attachment WHERE id = ANY(%s)""", (list(ids),))
78 targets = cr.dictfetchall()
71 model_attachments = {}79 model_attachments = {}
72 for target_dict in targets:80 for target_dict in targets:
73 if not (target_dict['res_id'] and target_dict['res_model']):81 if not (target_dict['res_id'] and target_dict['res_model']):
@@ -92,9 +100,10 @@
92 for res_id in disallowed_ids:100 for res_id in disallowed_ids:
93 for attach_id in targets[res_id]:101 for attach_id in targets[res_id]:
94 ids.remove(attach_id)102 ids.remove(attach_id)
95 if count:103
96 return len(ids)104 # sort result according to the original sort ordering
97 return ids105 result = [id for id in orig_ids if id in ids]
106 return len(result) if count else list(result)
98107
99 def read(self, cr, uid, ids, fields_to_read=None, context=None, load='_classic_read'):108 def read(self, cr, uid, ids, fields_to_read=None, context=None, load='_classic_read'):
100 self.check(cr, uid, ids, 'read', context=context)109 self.check(cr, uid, ids, 'read', context=context)