# HG changeset patch # User Sylvain Thénault # Date 1347549975 -7200 # Node ID f23ac525ddd19b6d6f273b2521b6a4df3e4e712a # Parent 3d2038d6f20dea3b6f3cfa5211db2ed93fb26104 [datafeed] properly call hooks for inlined relations on entity creation. Closes #2481156 diff -r 3d2038d6f20d -r f23ac525ddd1 server/repository.py --- a/server/repository.py Mon Sep 10 15:17:10 2012 +0200 +++ b/server/repository.py Thu Sep 13 17:26:15 2012 +0200 @@ -120,6 +120,26 @@ {'x': eidfrom, 'y': eidto}) +def preprocess_inlined_relations(session, entity): + """when an entity is added, check if it has some inlined relation which + requires to be extrated for proper call hooks + """ + relations = [] + activeintegrity = session.is_hook_category_activated('activeintegrity') + eschema = entity.e_schema + for attr in entity.cw_edited.iterkeys(): + rschema = eschema.subjrels[attr] + if not rschema.final: # inlined relation + value = entity.cw_edited[attr] + relations.append((attr, value)) + session.update_rel_cache_add(entity.eid, attr, value) + rdef = session.rtype_eids_rdef(attr, entity.eid, value) + if rdef.cardinality[1] in '1?' and activeintegrity: + with security_enabled(session, read=False): + session.execute('DELETE X %s Y WHERE Y eid %%(y)s' % attr, + {'x': entity.eid, 'y': value}) + return relations + class NullEventBus(object): def publish(self, msg): @@ -1353,7 +1373,6 @@ entity._cw_is_saved = False # entity has an eid but is not yet saved # init edited_attributes before calling before_add_entity hooks entity.cw_edited = edited - eschema = entity.e_schema source = self.locate_etype_source(entity.__regid__) # allocate an eid to the entity before calling hooks entity.eid = self.system_source.create_eid(session) @@ -1364,19 +1383,7 @@ prefill_entity_caches(entity) if source.should_call_hooks: self.hm.call_hooks('before_add_entity', session, entity=entity) - relations = [] - activeintegrity = session.is_hook_category_activated('activeintegrity') - for attr in edited.iterkeys(): - rschema = eschema.subjrels[attr] - if not rschema.final: # inlined relation - value = edited[attr] - relations.append((attr, value)) - session.update_rel_cache_add(entity.eid, attr, value) - rdef = session.rtype_eids_rdef(attr, entity.eid, value) - if rdef.cardinality[1] in '1?' and activeintegrity: - with security_enabled(session, read=False): - session.execute('DELETE X %s Y WHERE Y eid %%(y)s' % attr, - {'x': entity.eid, 'y': value}) + relations = preprocess_inlined_relations(session, entity) edited.set_defaults() if session.is_hook_category_activated('integrity'): edited.check(creation=True) diff -r 3d2038d6f20d -r f23ac525ddd1 server/sources/datafeed.py --- a/server/sources/datafeed.py Mon Sep 10 15:17:10 2012 +0200 +++ b/server/sources/datafeed.py Thu Sep 13 17:26:15 2012 +0200 @@ -30,6 +30,7 @@ from lxml import etree from cubicweb import RegistryNotFound, ObjectNotFound, ValidationError, UnknownEid +from cubicweb.server.repository import preprocess_inlined_relations from cubicweb.server.sources import AbstractSource from cubicweb.appobject import AppObject @@ -254,11 +255,20 @@ """called by the repository after an entity stored here has been inserted in the system table. """ + relations = preprocess_inlined_relations(session, entity) if session.is_hook_category_activated('integrity'): entity.cw_edited.check(creation=True) self.repo.system_source.add_entity(session, entity) entity.cw_edited.saved = entity._cw_is_saved = True sourceparams['parser'].after_entity_copy(entity, sourceparams) + # call hooks for inlined relations + call_hooks = self.repo.hm.call_hooks + if self.should_call_hooks: + for attr, value in relations: + call_hooks('before_add_relation', session, + eidfrom=entity.eid, rtype=attr, eidto=value) + call_hooks('after_add_relation', session, + eidfrom=entity.eid, rtype=attr, eidto=value) def source_cwuris(self, session): sql = ('SELECT extid, eid, type FROM entities, cw_source_relation ' @@ -399,6 +409,7 @@ entity.set_attributes(**attrs) self.notify_updated(entity) + class DataFeedXMLParser(DataFeedParser): def process(self, url, raise_on_error=False):