From afdfdbfa5b36b1fcda8da759cf3fb5a027d9673a Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Mon, 23 Sep 2019 12:40:25 +0000 Subject: [PATCH] [IMP] base: inverse `datas` of `ir.attachment` during `create` Before this commit, the inverse of `datas` would be computed after the `create`, which would lead to unnecessary queries, not only for writing the new values, but also because of the re-computation of fields that depend on these values. --- odoo/addons/base/models/ir_attachment.py | 34 +++++++++++++----------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/odoo/addons/base/models/ir_attachment.py b/odoo/addons/base/models/ir_attachment.py index 27b52033ab5..d98a52b8ef1 100644 --- a/odoo/addons/base/models/ir_attachment.py +++ b/odoo/addons/base/models/ir_attachment.py @@ -195,23 +195,8 @@ class IrAttachment(models.Model): attach.datas = attach.db_datas def _inverse_datas(self): - location = self._storage() for attach in self: - # compute the fields that depend on datas - value = attach.datas - bin_data = base64.b64decode(value) if value else b'' - vals = { - 'file_size': len(bin_data), - 'checksum': self._compute_checksum(bin_data), - 'index_content': self._index(bin_data, attach.mimetype), - 'store_fname': False, - 'db_datas': value, - } - if value and location != 'db': - # save it to the filestore - vals['store_fname'] = self._file_write(value, vals['checksum']) - vals['db_datas'] = False - + vals = self._get_datas_related_values(attach.datas, attach.mimetype) # take current location in filestore to possibly garbage-collect it fname = attach.store_fname # write as superuser, as user probably does not have write access @@ -219,6 +204,21 @@ class IrAttachment(models.Model): if fname: self._file_delete(fname) + def _get_datas_related_values(self, data, mimetype): + # compute the fields that depend on datas + bin_data = base64.b64decode(data) if data else b'' + values = { + 'file_size': len(bin_data), + 'checksum': self._compute_checksum(bin_data), + 'index_content': self._index(bin_data, mimetype), + 'store_fname': False, + 'db_datas': data, + } + if data and self._storage() != 'db': + values['store_fname'] = self._file_write(data, values['checksum']) + values['db_datas'] = False + return values + def _compute_checksum(self, bin_data): """ compute the checksum for the given datas :param bin_data : datas in its binary form @@ -506,6 +506,8 @@ class IrAttachment(models.Model): for field in ('file_size', 'checksum'): values.pop(field, False) values = self._check_contents(values) + if 'datas' in values: + values.update(self._get_datas_related_values(values.pop('datas'), values['mimetype'])) # 'check()' only uses res_model and res_id from values, and make an exists. # We can group the values by model, res_id to make only one query when # creating multiple attachments on a single record.