server/repository.py
branchstable
changeset 7503 bc30c2faaadc
parent 7502 e7190f7e850e
child 7507 4c043afb104a
equal deleted inserted replaced
7502:e7190f7e850e 7503:bc30c2faaadc
    80     for rschema in entity.e_schema.object_relations():
    80     for rschema in entity.e_schema.object_relations():
    81         rtype = str(rschema)
    81         rtype = str(rschema)
    82         if rtype in schema.VIRTUAL_RTYPES or (rtype, 'object') in NO_CACHE_RELATIONS:
    82         if rtype in schema.VIRTUAL_RTYPES or (rtype, 'object') in NO_CACHE_RELATIONS:
    83             continue
    83             continue
    84         entity.cw_set_relation_cache(rtype, 'object', session.empty_rset())
    84         entity.cw_set_relation_cache(rtype, 'object', session.empty_rset())
    85     # set inlined relation cache before call to after_add_entity
       
    86     for attr, value in relations:
       
    87         session.update_rel_cache_add(entity.eid, attr, value)
       
    88         del_existing_rel_if_needed(session, entity.eid, attr, value)
       
    89 
    85 
    90 def del_existing_rel_if_needed(session, eidfrom, rtype, eidto):
    86 def del_existing_rel_if_needed(session, eidfrom, rtype, eidto):
    91     """delete existing relation when adding a new one if card is 1 or ?
    87     """delete existing relation when adding a new one if card is 1 or ?
    92 
    88 
    93     have to be done once the new relation has been inserted to avoid having
    89     have to be done once the new relation has been inserted to avoid having
    94     an entity without a relation for some time
    90     an entity without a relation for some time
    95 
    91 
    96     this kind of behaviour has to be done in the repository so we don't have
    92     this kind of behaviour has to be done in the repository so we don't have
    97     hooks order hazardness
    93     hooks order hazardness
    98     """
    94     """
    99     # skip that for internal session or if integrity explicitly disabled
    95     # skip that if integrity explicitly disabled
   100     #
    96     if not session.is_hook_category_activated('activeintegrity'):
   101     # XXX we should imo rely on the orm to first fetch existing entity if any
       
   102     # then delete it.
       
   103     if session.is_internal_session \
       
   104            or not session.is_hook_category_activated('activeintegrity'):
       
   105         return
    97         return
   106     rdef = session.rtype_eids_rdef(rtype, eidfrom, eidto)
    98     rdef = session.rtype_eids_rdef(rtype, eidfrom, eidto)
   107     card = rdef.cardinality
    99     card = rdef.cardinality
   108     # one may be tented to check for neweids but this may cause more than one
   100     # one may be tented to check for neweids but this may cause more than one
   109     # relation even with '1?'  cardinality if thoses relations are added in the
   101     # relation even with '1?'  cardinality if thoses relations are added in the
   114     #
   106     #
   115     # notes:
   107     # notes:
   116     # * inlined relations will be implicitly deleted for the subject entity
   108     # * inlined relations will be implicitly deleted for the subject entity
   117     # * we don't want read permissions to be applied but we want delete
   109     # * we don't want read permissions to be applied but we want delete
   118     #   permission to be checked
   110     #   permission to be checked
   119     if card[0] in '1?' and not rdef.rtype.inlined:
   111     if card[0] in '1?':
   120         with security_enabled(session, read=False):
   112         with security_enabled(session, read=False):
   121             session.execute('DELETE X %s Y WHERE X eid %%(x)s, '
   113             session.execute('DELETE X %s Y WHERE X eid %%(x)s, '
   122                             'NOT Y eid %%(y)s' % rtype,
   114                             'NOT Y eid %%(y)s' % rtype,
   123                                 {'x': eidfrom, 'y': eidto})
   115                                 {'x': eidfrom, 'y': eidto})
   124     if card[1] in '1?':
   116     if card[1] in '1?':
  1221         # set caches asap
  1213         # set caches asap
  1222         extid = self.init_entity_caches(session, entity, source)
  1214         extid = self.init_entity_caches(session, entity, source)
  1223         if server.DEBUG & server.DBG_REPO:
  1215         if server.DEBUG & server.DBG_REPO:
  1224             print 'ADD entity', self, entity.__regid__, entity.eid, edited
  1216             print 'ADD entity', self, entity.__regid__, entity.eid, edited
  1225         relations = []
  1217         relations = []
       
  1218         prefill_entity_caches(entity, relations)
  1226         if source.should_call_hooks:
  1219         if source.should_call_hooks:
  1227             self.hm.call_hooks('before_add_entity', session, entity=entity)
  1220             self.hm.call_hooks('before_add_entity', session, entity=entity)
       
  1221         activintegrity = session.is_hook_category_activated('activeintegrity')
  1228         for attr in edited.iterkeys():
  1222         for attr in edited.iterkeys():
  1229             rschema = eschema.subjrels[attr]
  1223             rschema = eschema.subjrels[attr]
  1230             if not rschema.final: # inlined relation
  1224             if not rschema.final: # inlined relation
  1231                 relations.append((attr, edited[attr]))
  1225                 value = edited[attr]
       
  1226                 relations.append((attr, value))
       
  1227                 session.update_rel_cache_add(entity.eid, attr, value)
       
  1228                 rdef = session.rtype_eids_rdef(attr, entity.eid, value)
       
  1229                 if rdef.cardinality[1] in '1?' and activintegrity:
       
  1230                     with security_enabled(session, read=False):
       
  1231                         session.execute('DELETE X %s Y WHERE Y eid %(y)s',
       
  1232                                         {'x': entity.eid, 'y': value})
  1232         edited.set_defaults()
  1233         edited.set_defaults()
  1233         if session.is_hook_category_activated('integrity'):
  1234         if session.is_hook_category_activated('integrity'):
  1234             edited.check(creation=True)
  1235             edited.check(creation=True)
  1235         prefill_entity_caches(entity, relations)
       
  1236         try:
  1236         try:
  1237             source.add_entity(session, entity)
  1237             source.add_entity(session, entity)
  1238         except UniqueTogetherError, exc:
  1238         except UniqueTogetherError, exc:
  1239             userhdlr = session.vreg['adapters'].select(
  1239             userhdlr = session.vreg['adapters'].select(
  1240                 'IUserFriendlyError', session, entity=entity, exc=exc)
  1240                 'IUserFriendlyError', session, entity=entity, exc=exc)