server/repository.py
branchstable
changeset 6889 37668bf302f5
parent 6801 33952695295b
child 6931 0af44a38fe41
child 7064 b8ce2266d026
equal deleted inserted replaced
6888:c02e5ba43366 6889:37668bf302f5
  1095         # mark eid as being deleted in session info and setup cache update
  1095         # mark eid as being deleted in session info and setup cache update
  1096         # operation
  1096         # operation
  1097         hook.CleanupDeletedEidsCacheOp.get_instance(session).add_data(entity.eid)
  1097         hook.CleanupDeletedEidsCacheOp.get_instance(session).add_data(entity.eid)
  1098         self._delete_info(session, entity, sourceuri, extid, scleanup)
  1098         self._delete_info(session, entity, sourceuri, extid, scleanup)
  1099 
  1099 
       
  1100     def delete_info_multi(self, session, entities, sourceuri, extids, scleanup=False):
       
  1101         """same as delete_info but accepts a list of entities and
       
  1102         extids with the same etype and belonging to the same source
       
  1103         """
       
  1104         # mark eid as being deleted in session info and setup cache update
       
  1105         # operation
       
  1106         op = hook.CleanupDeletedEidsCacheOp.get_instance(session)
       
  1107         for entity in entities:
       
  1108             op.add_data(entity.eid)
       
  1109         self._delete_info_multi(session, entities, sourceuri, extids, scleanup)
       
  1110 
  1100     def _delete_info(self, session, entity, sourceuri, extid, scleanup=False):
  1111     def _delete_info(self, session, entity, sourceuri, extid, scleanup=False):
  1101         """delete system information on deletion of an entity:
  1112         """delete system information on deletion of an entity:
  1102         * delete all remaining relations from/to this entity
  1113         * delete all remaining relations from/to this entity
  1103         * call delete info on the system source which will transfer record from
  1114         * call delete info on the system source which will transfer record from
  1104           the entities table to the deleted_entities table
  1115           the entities table to the deleted_entities table
  1126                                     build_descr=False)
  1137                                     build_descr=False)
  1127                 except:
  1138                 except:
  1128                     self.exception('error while cascading delete for entity %s '
  1139                     self.exception('error while cascading delete for entity %s '
  1129                                    'from %s. RQL: %s', entity, sourceuri, rql)
  1140                                    'from %s. RQL: %s', entity, sourceuri, rql)
  1130         self.system_source.delete_info(session, entity, sourceuri, extid)
  1141         self.system_source.delete_info(session, entity, sourceuri, extid)
       
  1142 
       
  1143     def _delete_info_multi(self, session, entities, sourceuri, extids, scleanup=False):
       
  1144         """same as _delete_info but accepts a list of entities with
       
  1145         the same etype and belinging to the same source.
       
  1146         """
       
  1147         pendingrtypes = session.transaction_data.get('pendingrtypes', ())
       
  1148         # delete remaining relations: if user can delete the entity, he can
       
  1149         # delete all its relations without security checking
       
  1150         assert entities and len(entities) == len(extids)
       
  1151         with security_enabled(session, read=False, write=False):
       
  1152             eids = [_e.eid for _e in entities]
       
  1153             in_eids = ','.join((str(eid) for eid in eids))
       
  1154             for rschema, _, role in entities[0].e_schema.relation_definitions():
       
  1155                 rtype = rschema.type
       
  1156                 if rtype in schema.VIRTUAL_RTYPES or rtype in pendingrtypes:
       
  1157                     continue
       
  1158                 if role == 'subject':
       
  1159                     # don't skip inlined relation so they are regularly
       
  1160                     # deleted and so hooks are correctly called
       
  1161                     rql = 'DELETE X %s Y WHERE X eid IN (%s)' % (rtype, in_eids)
       
  1162                 else:
       
  1163                     rql = 'DELETE Y %s X WHERE X eid IN (%s)' % (rtype, in_eids)
       
  1164                 if scleanup:
       
  1165                     # source cleaning: only delete relations stored locally
       
  1166                     rql += ', NOT (Y cw_source S, S name %(source)s)'
       
  1167                 try:
       
  1168                     session.execute(rql, {'source': sourceuri},
       
  1169                                     build_descr=False)
       
  1170                 except:
       
  1171                     self.exception('error while cascading delete for entity %s '
       
  1172                                    'from %s. RQL: %s', entities, sourceuri, rql)
       
  1173         self.system_source.delete_info_multi(session, entities, sourceuri, extids)
  1131 
  1174 
  1132     def locate_relation_source(self, session, subject, rtype, object):
  1175     def locate_relation_source(self, session, subject, rtype, object):
  1133         subjsource = self.source_from_eid(subject, session)
  1176         subjsource = self.source_from_eid(subject, session)
  1134         objsource = self.source_from_eid(object, session)
  1177         objsource = self.source_from_eid(object, session)
  1135         if not subjsource is objsource:
  1178         if not subjsource is objsource:
  1295                                   eidfrom=entity.eid, rtype=attr, eidto=value)
  1338                                   eidfrom=entity.eid, rtype=attr, eidto=value)
  1296         finally:
  1339         finally:
  1297             if orig_edited is not None:
  1340             if orig_edited is not None:
  1298                 entity.cw_edited = orig_edited
  1341                 entity.cw_edited = orig_edited
  1299 
  1342 
  1300     def glob_delete_entity(self, session, eid):
  1343 
  1301         """delete an entity and all related entities from the repository"""
  1344     def glob_delete_entities(self, session, eids):
  1302         entity = session.entity_from_eid(eid)
  1345         """delete a list of  entities and all related entities from the repository"""
  1303         etype, sourceuri, extid = self.type_and_source_from_eid(eid, session)
  1346         data_by_etype_source = {} # values are ([list of eids],
  1304         if server.DEBUG & server.DBG_REPO:
  1347                                   #             [list of extid],
  1305             print 'DELETE entity', etype, eid
  1348                                   #             [list of entities])
  1306         source = self.sources_by_uri[sourceuri]
  1349         #
  1307         if source.should_call_hooks:
  1350         # WARNING: the way this dictionary is populated is heavily optimized
  1308             self.hm.call_hooks('before_delete_entity', session, entity=entity)
  1351         # and does not use setdefault on purpose. Unless a new release
  1309         self._delete_info(session, entity, sourceuri, extid)
  1352         # of the Python interpreter advertises large perf improvements
  1310         source.delete_entity(session, entity)
  1353         # in setdefault, this should not be changed without profiling.
  1311         if source.should_call_hooks:
  1354 
  1312             self.hm.call_hooks('after_delete_entity', session, entity=entity)
  1355         for eid in eids:
       
  1356             etype, sourceuri, extid = self.type_and_source_from_eid(eid, session)
       
  1357             entity = session.entity_from_eid(eid, etype)
       
  1358             _key = (etype, sourceuri)
       
  1359             if _key not in data_by_etype_source:
       
  1360                 data_by_etype_source[_key] = ([eid], [extid], [entity])
       
  1361             else:
       
  1362                 _data = data_by_etype_source[_key]
       
  1363                 _data[0].append(eid)
       
  1364                 _data[1].append(extid)
       
  1365                 _data[2].append(entity)
       
  1366         for (etype, sourceuri), (eids, extids, entities) in data_by_etype_source.iteritems():
       
  1367             if server.DEBUG & server.DBG_REPO:
       
  1368                 print 'DELETE entities', etype, eids
       
  1369             #print 'DELETE entities', etype, len(eids)
       
  1370             source = self.sources_by_uri[sourceuri]
       
  1371             if source.should_call_hooks:
       
  1372                 self.hm.call_hooks('before_delete_entity', session, entities=entities)
       
  1373             self._delete_info_multi(session, entities, sourceuri, extids) # xxx
       
  1374             source.delete_entities(session, entities)
       
  1375             if source.should_call_hooks:
       
  1376                 self.hm.call_hooks('after_delete_entity', session, entities=entities)
  1313         # don't clear cache here this is done in a hook on commit
  1377         # don't clear cache here this is done in a hook on commit
  1314 
  1378 
  1315     def glob_add_relation(self, session, subject, rtype, object):
  1379     def glob_add_relation(self, session, subject, rtype, object):
  1316         """add a relation to the repository"""
  1380         """add a relation to the repository"""
  1317         if server.DEBUG & server.DBG_REPO:
  1381         if server.DEBUG & server.DBG_REPO: