From 108decbd99451a771428baa336e981aff5f8a797 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Mon, 19 Oct 2015 18:07:53 +0200 Subject: [PATCH] [FIX] ir_qweb: call clean_attachment at the end of save_attachment .. instead of at the start. The reason is: if any rollback have to occur during the call to `save_attachments`, we want to avoid rollbacking an unlink on the ir.attachment table (because we cannot rollback the removal of a file in the filestore). This issue is especially annoying when we generate a bundle whose ir.attachment record has the same hash than the invalidated one (for instance when one of the source files in the bundle has been touched but not modified) and of of these rollback occurs: the bundle has been deleted on the filestore and cannot be served. --- openerp/addons/base/ir/ir_qweb.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py index 015316dd7e8..5fbfa673177 100644 --- a/openerp/addons/base/ir/ir_qweb.py +++ b/openerp/addons/base/ir/ir_qweb.py @@ -1223,6 +1223,12 @@ class AssetsBundle(object): When `type` is css we need to check that we are deleting a different version (and not *any* version) because css may be paginated and, therefore, may produce multiple attachments for the same bundle's version. + + When `type` is js we need to check that we are deleting a different version (and not *any* + version) because, as one of the creates in `save_attachment` can trigger a rollback, the + call to `clean_attachments ` is made at the end of the method in order to avoid the rollback + of an ir.attachment unlink (because we cannot rollback a removal on the filestore), thus we + must exclude the current bundle. """ ira = self.registry['ir.attachment'] domain = [ @@ -1240,7 +1246,6 @@ class AssetsBundle(object): def save_attachment(self, type, content, inc=None): ira = self.registry['ir.attachment'] - self.clean_attachments(type) values = {} values["name"] = "/web/content/%s" % type @@ -1259,6 +1264,8 @@ class AssetsBundle(object): if self.context.get('commit_assetsbundle') is True: self.cr.commit() + self.clean_attachments(type) + return ira.browse(self.cr, openerp.SUPERUSER_ID, attachment_id, context=self.context) def js(self):