server/repository.py
changeset 10203 1443fe643a38
parent 10110 f601d2fdeff7
child 10235 684215aca046
equal deleted inserted replaced
10202:aaabcb64f77f 10203:1443fe643a38
  1072         """
  1072         """
  1073         # begin by inserting eid/type/source/extid into the entities table
  1073         # begin by inserting eid/type/source/extid into the entities table
  1074         hook.CleanupNewEidsCacheOp.get_instance(session).add_data(entity.eid)
  1074         hook.CleanupNewEidsCacheOp.get_instance(session).add_data(entity.eid)
  1075         self.system_source.add_info(session, entity, source, extid)
  1075         self.system_source.add_info(session, entity, source, extid)
  1076 
  1076 
  1077     def delete_info(self, session, entity, sourceuri):
  1077     def _delete_cascade_multi(self, session, entities):
  1078         """called by external source when some entity known by the system source
  1078         """same as _delete_cascade but accepts a list of entities with
  1079         has been deleted in the external source
  1079         the same etype and belonging to the same source.
  1080         """
       
  1081         # mark eid as being deleted in session info and setup cache update
       
  1082         # operation
       
  1083         hook.CleanupDeletedEidsCacheOp.get_instance(session).add_data(entity.eid)
       
  1084         self._delete_info(session, entity, sourceuri)
       
  1085 
       
  1086     def _delete_info(self, session, entity, sourceuri):
       
  1087         """delete system information on deletion of an entity:
       
  1088 
       
  1089         * delete all remaining relations from/to this entity
       
  1090         * call delete info on the system source
       
  1091         """
       
  1092         pendingrtypes = session.transaction_data.get('pendingrtypes', ())
       
  1093         # delete remaining relations: if user can delete the entity, he can
       
  1094         # delete all its relations without security checking
       
  1095         with session.security_enabled(read=False, write=False):
       
  1096             eid = entity.eid
       
  1097             for rschema, _, role in entity.e_schema.relation_definitions():
       
  1098                 rtype = rschema.type
       
  1099                 if rtype in schema.VIRTUAL_RTYPES or rtype in pendingrtypes:
       
  1100                     continue
       
  1101                 if role == 'subject':
       
  1102                     # don't skip inlined relation so they are regularly
       
  1103                     # deleted and so hooks are correctly called
       
  1104                     rql = 'DELETE X %s Y WHERE X eid %%(x)s' % rtype
       
  1105                 else:
       
  1106                     rql = 'DELETE Y %s X WHERE X eid %%(x)s' % rtype
       
  1107                 try:
       
  1108                     session.execute(rql, {'x': eid}, build_descr=False)
       
  1109                 except Exception:
       
  1110                     if self.config.mode == 'test':
       
  1111                         raise
       
  1112                     self.exception('error while cascading delete for entity %s '
       
  1113                                    'from %s. RQL: %s', entity, sourceuri, rql)
       
  1114         self.system_source.delete_info_multi(session, [entity])
       
  1115 
       
  1116     def _delete_info_multi(self, session, entities):
       
  1117         """same as _delete_info but accepts a list of entities with
       
  1118         the same etype and belinging to the same source.
       
  1119         """
  1080         """
  1120         pendingrtypes = session.transaction_data.get('pendingrtypes', ())
  1081         pendingrtypes = session.transaction_data.get('pendingrtypes', ())
  1121         # delete remaining relations: if user can delete the entity, he can
  1082         # delete remaining relations: if user can delete the entity, he can
  1122         # delete all its relations without security checking
  1083         # delete all its relations without security checking
  1123         with session.security_enabled(read=False, write=False):
  1084         with session.security_enabled(read=False, write=False):
  1144                 except Exception:
  1105                 except Exception:
  1145                     if self.config.mode == 'test':
  1106                     if self.config.mode == 'test':
  1146                         raise
  1107                         raise
  1147                     self.exception('error while cascading delete for entity %s. RQL: %s',
  1108                     self.exception('error while cascading delete for entity %s. RQL: %s',
  1148                                    entities, rql)
  1109                                    entities, rql)
  1149         self.system_source.delete_info_multi(session, entities)
       
  1150 
  1110 
  1151     def init_entity_caches(self, cnx, entity, source):
  1111     def init_entity_caches(self, cnx, entity, source):
  1152         """add entity to connection entities cache and repo's extid cache.
  1112         """add entity to connection entities cache and repo's extid cache.
  1153         Return entity's ext id if the source isn't the system source.
  1113         Return entity's ext id if the source isn't the system source.
  1154         """
  1114         """
  1182         self.hm.call_hooks('before_add_entity', cnx, entity=entity)
  1142         self.hm.call_hooks('before_add_entity', cnx, entity=entity)
  1183         relations = preprocess_inlined_relations(cnx, entity)
  1143         relations = preprocess_inlined_relations(cnx, entity)
  1184         edited.set_defaults()
  1144         edited.set_defaults()
  1185         if cnx.is_hook_category_activated('integrity'):
  1145         if cnx.is_hook_category_activated('integrity'):
  1186             edited.check(creation=True)
  1146             edited.check(creation=True)
       
  1147         self.add_info(cnx, entity, source, extid)
  1187         try:
  1148         try:
  1188             source.add_entity(cnx, entity)
  1149             source.add_entity(cnx, entity)
  1189         except UniqueTogetherError as exc:
  1150         except UniqueTogetherError as exc:
  1190             userhdlr = cnx.vreg['adapters'].select(
  1151             userhdlr = cnx.vreg['adapters'].select(
  1191                 'IUserFriendlyError', cnx, entity=entity, exc=exc)
  1152                 'IUserFriendlyError', cnx, entity=entity, exc=exc)
  1192             userhdlr.raise_user_exception()
  1153             userhdlr.raise_user_exception()
  1193         self.add_info(cnx, entity, source, extid)
       
  1194         edited.saved = entity._cw_is_saved = True
  1154         edited.saved = entity._cw_is_saved = True
  1195         # trigger after_add_entity after after_add_relation
  1155         # trigger after_add_entity after after_add_relation
  1196         self.hm.call_hooks('after_add_entity', cnx, entity=entity)
  1156         self.hm.call_hooks('after_add_entity', cnx, entity=entity)
  1197         # call hooks for inlined relations
  1157         # call hooks for inlined relations
  1198         for attr, value in relations:
  1158         for attr, value in relations:
  1303         source = self.system_source
  1263         source = self.system_source
  1304         for etype, entities in data_by_etype.iteritems():
  1264         for etype, entities in data_by_etype.iteritems():
  1305             if server.DEBUG & server.DBG_REPO:
  1265             if server.DEBUG & server.DBG_REPO:
  1306                 print 'DELETE entities', etype, [entity.eid for entity in entities]
  1266                 print 'DELETE entities', etype, [entity.eid for entity in entities]
  1307             self.hm.call_hooks('before_delete_entity', cnx, entities=entities)
  1267             self.hm.call_hooks('before_delete_entity', cnx, entities=entities)
  1308             self._delete_info_multi(cnx, entities)
  1268             self._delete_cascade_multi(cnx, entities)
  1309             source.delete_entities(cnx, entities)
  1269             source.delete_entities(cnx, entities)
       
  1270             source.delete_info_multi(cnx, entities)
  1310             self.hm.call_hooks('after_delete_entity', cnx, entities=entities)
  1271             self.hm.call_hooks('after_delete_entity', cnx, entities=entities)
  1311         # don't clear cache here, it is done in a hook on commit
  1272         # don't clear cache here, it is done in a hook on commit
  1312 
  1273 
  1313     def glob_add_relation(self, cnx, subject, rtype, object):
  1274     def glob_add_relation(self, cnx, subject, rtype, object):
  1314         """add a relation to the repository"""
  1275         """add a relation to the repository"""