From 3b4e3bdac63578d0c7a85cb90b3eb165351e1432 Mon Sep 17 00:00:00 2001 From: "odo@tinyerp.com" <> Date: Thu, 12 May 2011 12:00:38 +0200 Subject: [PATCH 1/5] [FIX] solve cache problem when unlink ir.model.data bzr revid: tfr@openerp.com-20110512100038-hng80ug44afq8fr7 --- openerp/addons/base/ir/ir_model.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index 0c3cd46356f..93ce7219c07 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -629,6 +629,13 @@ class ir_model_data(osv.osv): except: id = False return id + + def unlink(self, cr, uid, ids, context=None): + ref_ids = self.browse(cr, uid, ids, context=context) + for ref_id in ref_ids: + self._get_id.clear_cache(cr.dbname, uid, ref_id.module, ref_id.name) + self.get_object_reference.clear_cache(cr.dbname, uid, ref_id.module, ref_id.name) + super(ir_model_data,self).unlink(cr, uid, ids, context=context) def _update(self,cr, uid, model, module, values, xml_id=False, store=True, noupdate=False, mode='init', res_id=False, context=None): model_obj = self.pool.get(model) From 82b215c5831596b4de133f6d000094e08ae29e0c Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Fri, 20 May 2011 10:48:28 +0200 Subject: [PATCH 2/5] [FIX] ir.model.data: add missing return statement, would cause marshalling errors in XMLRPC bzr revid: odo@openerp.com-20110520084828-fre96mfaocmynmtb --- openerp/addons/base/ir/ir_model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index 93ce7219c07..45e5a138c73 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -629,13 +629,13 @@ class ir_model_data(osv.osv): except: id = False return id - + def unlink(self, cr, uid, ids, context=None): ref_ids = self.browse(cr, uid, ids, context=context) for ref_id in ref_ids: self._get_id.clear_cache(cr.dbname, uid, ref_id.module, ref_id.name) self.get_object_reference.clear_cache(cr.dbname, uid, ref_id.module, ref_id.name) - super(ir_model_data,self).unlink(cr, uid, ids, context=context) + return super(ir_model_data,self).unlink(cr, uid, ids, context=context) def _update(self,cr, uid, model, module, values, xml_id=False, store=True, noupdate=False, mode='init', res_id=False, context=None): model_obj = self.pool.get(model) From 107bd89aea98c29c17292ad120458e8f3f03b083 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 31 May 2011 11:21:33 +0200 Subject: [PATCH 3/5] [IMP] convert: remove now useless call to ir.model.data._unlink for unlinked records. bzr revid: odo@openerp.com-20110531092133-rbobo5g4rmk1o8j7 --- openerp/tools/convert.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index 5536f311eb8..dd3a3d4a285 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -301,13 +301,11 @@ form: module.record_id""" % (xml_id,) pass if ids: self.pool.get(d_model).unlink(cr, self.uid, ids) - self.pool.get('ir.model.data')._unlink(cr, self.uid, d_model, ids) def _remove_ir_values(self, cr, name, value, model): ir_value_ids = self.pool.get('ir.values').search(cr, self.uid, [('name','=',name),('value','=',value),('model','=',model)]) if ir_value_ids: self.pool.get('ir.values').unlink(cr, self.uid, ir_value_ids) - self.pool.get('ir.model.data')._unlink(cr, self.uid, 'ir.values', ir_value_ids) return True From f6f4618fb069d4b35d48bc79ef556ea4ebedf46a Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 31 May 2011 11:22:32 +0200 Subject: [PATCH 4/5] [IMP] orm: minor typo and improvement in handling of ir.model.data during unlink() bzr revid: odo@openerp.com-20110531092232-pyt85iw2q7bf6qp1 --- openerp/osv/orm.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 2edb0f8c824..1d9cbe36ee8 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -3237,9 +3237,10 @@ class orm(orm_template): # Removing the ir_model_data reference if the record being deleted is a record created by xml/csv file, # as these are not connected with real database foreign keys, and would be dangling references. # Step 1. Calling unlink of ir_model_data only for the affected IDS. - referenced_ids = pool_model_data.search(cr, uid, [('res_id','in',list(sub_ids)),('model','=',self._name)], context=context) + reference_ids = pool_model_data.search(cr, uid, [('res_id','in',list(sub_ids)),('model','=',self._name)], context=context) # Step 2. Marching towards the real deletion of referenced records - pool_model_data.unlink(cr, uid, referenced_ids, context=context) + if reference_ids: + pool_model_data.unlink(cr, uid, reference_ids, context=context) # For the same reason, removing the record relevant to ir_values ir_value_ids = pool_ir_values.search(cr, uid, From b96c79147f21c7eea5f593b67fceb60e0e970d40 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 31 May 2011 11:24:26 +0200 Subject: [PATCH 5/5] [IMP] ir.model.data: remove obsolete _unlink() and unlink_mark, and their references Now all deletions in ir.model.data are automatically handled by ORM during the regular call to orm.unlink(). No need for any manual care. bzr revid: odo@openerp.com-20110531092426-ehvzf3dw6urqsdov --- openerp/addons/base/ir/ir_model.py | 42 +++++++++--------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index 45e5a138c73..772163b9717 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -581,7 +581,6 @@ class ir_model_data(osv.osv): def __init__(self, pool, cr): osv.osv.__init__(self, pool, cr) self.doinit = True - self.unlink_mark = {} # also stored in pool to avoid being discarded along with this osv instance if getattr(pool, 'model_data_reference_ids', None) is None: @@ -727,11 +726,12 @@ class ir_model_data(osv.osv): table.replace('.', '_'))] = (table, inherit_id) return res_id - def _unlink(self, cr, uid, model, res_ids): - for res_id in res_ids: - self.unlink_mark[(model, res_id)] = False - cr.execute('delete from ir_model_data where res_id=%s and model=%s', (res_id, model)) - return True + def unlink(self, cr, uid, ids, context=None): + ref_ids = self.browse(cr, uid, ids, context=context) + for ref_id in ref_ids: + self._get_id.clear_cache(cr.dbname, uid, ref_id.module, ref_id.name) + self.get_object_reference.clear_cache(cr.dbname, uid, ref_id.module, ref_id.name) + super(ir_model_data,self).unlink(cr, uid, ids, context=context) def ir_set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, meta=None, xml_id=False): if type(models[0])==type([]) or type(models[0])==type(()): @@ -765,9 +765,10 @@ class ir_model_data(osv.osv): module_in = ",".join(["%s"] * len(modules)) cr.execute('select id,name,model,res_id,module from ir_model_data where module IN (' + module_in + ') and noupdate=%s', modules + [False]) wkf_todo = [] + to_unlink = [] for (id, name, model, res_id,module) in cr.fetchall(): if (module,name) not in self.loads: - self.unlink_mark[(model,res_id)] = id + to_unlink.append((model,res_id)) if model=='workflow.activity': cr.execute('select res_type,res_id from wkf_instance where id IN (select inst_id from wkf_workitem where act_id=%s)', (res_id,)) wkf_todo.extend(cr.fetchall()) @@ -780,36 +781,19 @@ class ir_model_data(osv.osv): cr.commit() if not config.get('import_partial'): - for (model, res_id) in self.unlink_mark.keys(): + for (model, res_id) in to_unlink: if self.pool.get(model): self.__logger.info('Deleting %s@%s', res_id, model) try: self.pool.get(model).unlink(cr, uid, [res_id]) - if id: - ids = self.search(cr, uid, [('res_id','=',res_id), - ('model','=',model)]) - self.__logger.debug('=> Deleting %s: %s', - self._name, ids) - if len(ids) > 1 and \ - self.__logger.isEnabledFor(logging.WARNING): - self.__logger.warn( - 'Got %d %s for (%s, %d): %s', - len(ids), self._name, model, res_id, - map(itemgetter('module','name'), - self.read(cr, uid, ids, - ['name', 'module']))) - self.unlink(cr, uid, ids) - cr.execute( - 'DELETE FROM ir_values WHERE value=%s', - ('%s,%s'%(model, res_id),)) cr.commit() except Exception: cr.rollback() self.__logger.warn( - 'Could not delete id: %d of model %s\nThere ' - 'should be some relation that points to this ' - 'resource\nYou should manually fix this and ' - 'restart with --update=module', res_id, model) + 'Could not delete obsolete record with id: %d of model %s\n' + 'There should be some relation that points to this resource\n' + 'You should manually fix this and restart with --update=module', + res_id, model) return True ir_model_data()