server/repository.py
branchstable
changeset 7501 2983dd24494a
parent 7373 e5e6ef56cfb5
child 7502 e7190f7e850e
equal deleted inserted replaced
7500:cb0f4da64e86 7501:2983dd24494a
  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=None):
       
  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 
       
  1111     def _delete_info(self, session, entity, sourceuri, extid, scleanup=None):
  1100     def _delete_info(self, session, entity, sourceuri, extid, scleanup=None):
  1112         """delete system information on deletion of an entity:
  1101         """delete system information on deletion of an entity:
  1113         * delete all remaining relations from/to this entity
  1102         * delete all remaining relations from/to this entity
  1114         * call delete info on the system source which will transfer record from
  1103         * call delete info on the system source which will transfer record from
  1115           the entities table to the deleted_entities table
  1104           the entities table to the deleted_entities table
  1137                     session.execute(rql, {'x': eid, 'seid': scleanup},
  1126                     session.execute(rql, {'x': eid, 'seid': scleanup},
  1138                                     build_descr=False)
  1127                                     build_descr=False)
  1139                 except:
  1128                 except:
  1140                     self.exception('error while cascading delete for entity %s '
  1129                     self.exception('error while cascading delete for entity %s '
  1141                                    'from %s. RQL: %s', entity, sourceuri, rql)
  1130                                    'from %s. RQL: %s', entity, sourceuri, rql)
  1142         self.system_source.delete_info(session, entity, sourceuri, extid)
  1131         self.system_source.delete_info_multi(session, [entity], sourceuri)
  1143 
  1132 
  1144     def _delete_info_multi(self, session, entities, sourceuri, extids, scleanup=None):
  1133     def _delete_info_multi(self, session, entities, sourceuri, scleanup=None):
  1145         """same as _delete_info but accepts a list of entities with
  1134         """same as _delete_info but accepts a list of entities with
  1146         the same etype and belinging to the same source.
  1135         the same etype and belinging to the same source.
  1147         """
  1136         """
  1148         pendingrtypes = session.transaction_data.get('pendingrtypes', ())
  1137         pendingrtypes = session.transaction_data.get('pendingrtypes', ())
  1149         # delete remaining relations: if user can delete the entity, he can
  1138         # delete remaining relations: if user can delete the entity, he can
  1150         # delete all its relations without security checking
  1139         # delete all its relations without security checking
  1151         assert entities and len(entities) == len(extids)
       
  1152         with security_enabled(session, read=False, write=False):
  1140         with security_enabled(session, read=False, write=False):
  1153             eids = [_e.eid for _e in entities]
  1141             eids = [_e.eid for _e in entities]
  1154             in_eids = ','.join((str(eid) for eid in eids))
  1142             in_eids = ','.join((str(eid) for eid in eids))
  1155             for rschema, _, role in entities[0].e_schema.relation_definitions():
  1143             for rschema, _, role in entities[0].e_schema.relation_definitions():
  1156                 rtype = rschema.type
  1144                 rtype = rschema.type
  1168                 try:
  1156                 try:
  1169                     session.execute(rql, {'seid': scleanup}, build_descr=False)
  1157                     session.execute(rql, {'seid': scleanup}, build_descr=False)
  1170                 except:
  1158                 except:
  1171                     self.exception('error while cascading delete for entity %s '
  1159                     self.exception('error while cascading delete for entity %s '
  1172                                    'from %s. RQL: %s', entities, sourceuri, rql)
  1160                                    'from %s. RQL: %s', entities, sourceuri, rql)
  1173         self.system_source.delete_info_multi(session, entities, sourceuri, extids)
  1161         self.system_source.delete_info_multi(session, entities, sourceuri)
  1174 
  1162 
  1175     def locate_relation_source(self, session, subject, rtype, object):
  1163     def locate_relation_source(self, session, subject, rtype, object):
  1176         subjsource = self.source_from_eid(subject, session)
  1164         subjsource = self.source_from_eid(subject, session)
  1177         objsource = self.source_from_eid(object, session)
  1165         objsource = self.source_from_eid(object, session)
  1178         if not subjsource is objsource:
  1166         if not subjsource is objsource:
  1343                 entity.cw_edited = orig_edited
  1331                 entity.cw_edited = orig_edited
  1344 
  1332 
  1345 
  1333 
  1346     def glob_delete_entities(self, session, eids):
  1334     def glob_delete_entities(self, session, eids):
  1347         """delete a list of  entities and all related entities from the repository"""
  1335         """delete a list of  entities and all related entities from the repository"""
       
  1336         # mark eids as being deleted in session info and setup cache update
       
  1337         # operation (register pending eids before actual deletion to avoid
       
  1338         # multiple call to glob_delete_entities)
       
  1339         op = hook.CleanupDeletedEidsCacheOp.get_instance(session)
       
  1340         eids = eids - op._container
       
  1341         op._container |= eids
  1348         data_by_etype_source = {} # values are ([list of eids],
  1342         data_by_etype_source = {} # values are ([list of eids],
  1349                                   #             [list of extid],
  1343                                   #             [list of extid],
  1350                                   #             [list of entities])
  1344                                   #             [list of entities])
  1351         #
  1345         #
  1352         # WARNING: the way this dictionary is populated is heavily optimized
  1346         # WARNING: the way this dictionary is populated is heavily optimized
  1354         # of the Python interpreter advertises large perf improvements
  1348         # of the Python interpreter advertises large perf improvements
  1355         # in setdefault, this should not be changed without profiling.
  1349         # in setdefault, this should not be changed without profiling.
  1356 
  1350 
  1357         for eid in eids:
  1351         for eid in eids:
  1358             etype, sourceuri, extid = self.type_and_source_from_eid(eid, session)
  1352             etype, sourceuri, extid = self.type_and_source_from_eid(eid, session)
       
  1353             # XXX should cache entity's cw_metainformation
  1359             entity = session.entity_from_eid(eid, etype)
  1354             entity = session.entity_from_eid(eid, etype)
  1360             _key = (etype, sourceuri)
  1355             try:
  1361             if _key not in data_by_etype_source:
  1356                 data_by_etype_source[(etype, sourceuri)].append(entity)
  1362                 data_by_etype_source[_key] = ([eid], [extid], [entity])
  1357             except KeyError:
  1363             else:
  1358                 data_by_etype_source[(etype, sourceuri)] = [entity]
  1364                 _data = data_by_etype_source[_key]
  1359         for (etype, sourceuri), entities in data_by_etype_source.iteritems():
  1365                 _data[0].append(eid)
       
  1366                 _data[1].append(extid)
       
  1367                 _data[2].append(entity)
       
  1368         for (etype, sourceuri), (eids, extids, entities) in data_by_etype_source.iteritems():
       
  1369             if server.DEBUG & server.DBG_REPO:
  1360             if server.DEBUG & server.DBG_REPO:
  1370                 print 'DELETE entities', etype, eids
  1361                 print 'DELETE entities', etype, [entity.eid for entity in entities]
  1371             #print 'DELETE entities', etype, len(eids)
       
  1372             source = self.sources_by_uri[sourceuri]
  1362             source = self.sources_by_uri[sourceuri]
  1373             if source.should_call_hooks:
  1363             if source.should_call_hooks:
  1374                 self.hm.call_hooks('before_delete_entity', session, entities=entities)
  1364                 self.hm.call_hooks('before_delete_entity', session, entities=entities)
  1375             self._delete_info_multi(session, entities, sourceuri, extids) # xxx
  1365             self._delete_info_multi(session, entities, sourceuri)
  1376             source.delete_entities(session, entities)
  1366             source.delete_entities(session, entities)
  1377             if source.should_call_hooks:
  1367             if source.should_call_hooks:
  1378                 self.hm.call_hooks('after_delete_entity', session, entities=entities)
  1368                 self.hm.call_hooks('after_delete_entity', session, entities=entities)
  1379         # don't clear cache here this is done in a hook on commit
  1369         # don't clear cache here, it is done in a hook on commit
  1380 
  1370 
  1381     def glob_add_relation(self, session, subject, rtype, object):
  1371     def glob_add_relation(self, session, subject, rtype, object):
  1382         """add a relation to the repository"""
  1372         """add a relation to the repository"""
  1383         self.glob_add_relations(session, {rtype: [(subject, object)]})
  1373         self.glob_add_relations(session, {rtype: [(subject, object)]})
  1384 
  1374