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 |