[MERGE] ir_model_data unlinking does not use _unlink anymore, clears caches.

bzr revid: vmt@openerp.com-20110622135344-i4u23z22binbq8h1
This commit is contained in:
Vo Minh Thu 2011-06-22 15:53:44 +02:00
commit 0e6668a391
4 changed files with 27 additions and 35 deletions

View File

@ -580,7 +580,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:
@ -629,6 +628,14 @@ class ir_model_data(osv.osv):
id = False
return id
def unlink(self, cr, uid, ids, context=None):
""" Regular unlink method, but make sure to clear the caches. """
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)
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)
if not context:
@ -719,12 +726,6 @@ 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 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(()):
model,res_id = models[0]
@ -752,15 +753,25 @@ class ir_model_data(osv.osv):
return True
def _process_end(self, cr, uid, modules):
""" Clear records removed from updated module data.
This method is called at the end of the module loading process.
It is meant to removed records that are no longer present in the
updated data. Such records are recognised as the one with an xml id
and a module in ir_model_data and noupdate set to false, but not
present in self.loads.
"""
if not modules:
return True
modules = list(modules)
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())
@ -773,36 +784,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()

View File

@ -3511,9 +3511,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 = ir_values_obj.search(cr, uid,

View File

@ -301,14 +301,12 @@ 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_values_obj = self.pool.get('ir.values')
ir_value_ids = ir_values_obj.search(cr, self.uid, [('name','=',name),('value','=',value),('model','=',model)])
if ir_value_ids:
ir_values_obj.unlink(cr, self.uid, ir_value_ids)
self.pool.get('ir.model.data')._unlink(cr, self.uid, 'ir.values', ir_value_ids)
return True

View File

@ -643,7 +643,6 @@ class YamlInterpreter(object):
ids = [self.get_id(node.id)]
if len(ids):
self.pool.get(node.model).unlink(self.cr, self.uid, ids)
self.pool.get('ir.model.data')._unlink(self.cr, 1, node.model, ids)
else:
self.logger.log(logging.TEST, "Record not deleted.")