1382 """add several relations to the repository |
1382 """add several relations to the repository |
1383 |
1383 |
1384 relations is a dictionary rtype: [(subj_eid, obj_eid), ...] |
1384 relations is a dictionary rtype: [(subj_eid, obj_eid), ...] |
1385 """ |
1385 """ |
1386 sources = {} |
1386 sources = {} |
|
1387 subjects_by_types = {} |
|
1388 objects_by_types = {} |
|
1389 activintegrity = session.is_hook_category_activated('activeintegrity') |
1387 for rtype, eids_subj_obj in relations.iteritems(): |
1390 for rtype, eids_subj_obj in relations.iteritems(): |
1388 if server.DEBUG & server.DBG_REPO: |
1391 if server.DEBUG & server.DBG_REPO: |
1389 for subject, object in relations: |
1392 for subjeid, objeid in relations: |
1390 print 'ADD relation', subject, rtype, object |
1393 print 'ADD relation', subjeid, rtype, objeid |
1391 for subject, object in eids_subj_obj: |
1394 for subjeid, objeid in eids_subj_obj: |
1392 source = self.locate_relation_source(session, subject, rtype, object) |
1395 source = self.locate_relation_source(session, subjeid, rtype, objeid) |
1393 if source not in sources: |
1396 if source not in sources: |
1394 relations_by_rtype = {} |
1397 relations_by_rtype = {} |
1395 sources[source] = relations_by_rtype |
1398 sources[source] = relations_by_rtype |
1396 else: |
1399 else: |
1397 relations_by_rtype = sources[source] |
1400 relations_by_rtype = sources[source] |
1398 if rtype in relations_by_rtype: |
1401 if rtype in relations_by_rtype: |
1399 relations_by_rtype[rtype].append((subject, object)) |
1402 relations_by_rtype[rtype].append((subjeid, objeid)) |
1400 else: |
1403 else: |
1401 relations_by_rtype[rtype] = [(subject, object)] |
1404 relations_by_rtype[rtype] = [(subjeid, objeid)] |
|
1405 if not activintegrity: |
|
1406 continue |
|
1407 # take care to relation of cardinality '?1', as all eids will |
|
1408 # be inserted later, we've remove duplicated eids since they |
|
1409 # won't be catched by `del_existing_rel_if_needed` |
|
1410 rdef = session.rtype_eids_rdef(rtype, subjeid, objeid) |
|
1411 card = rdef.cardinality |
|
1412 if card[0] in '?1': |
|
1413 with security_enabled(session, read=False): |
|
1414 session.execute('DELETE X %s Y WHERE X eid %%(x)s, ' |
|
1415 'NOT Y eid %%(y)s' % rtype, |
|
1416 {'x': subjeid, 'y': objeid}) |
|
1417 subjects = subjects_by_types.setdefault(rdef, {}) |
|
1418 if subjeid in subjects: |
|
1419 del relations_by_rtype[rtype][subjects[subjeid]] |
|
1420 subjects[subjeid] = len(relations_by_rtype[rtype]) - 1 |
|
1421 continue |
|
1422 subjects[subjeid] = len(relations_by_rtype[rtype]) - 1 |
|
1423 if card[1] in '?1': |
|
1424 with security_enabled(session, read=False): |
|
1425 session.execute('DELETE X %s Y WHERE Y eid %%(y)s, ' |
|
1426 'NOT X eid %%(x)s' % rtype, |
|
1427 {'x': subjeid, 'y': objeid}) |
|
1428 objects = objects_by_types.setdefault(rdef, {}) |
|
1429 if objeid in objects: |
|
1430 del relations_by_rtype[rtype][objects[objeid]] |
|
1431 objects[objeid] = len(relations_by_rtype[rtype]) |
|
1432 continue |
|
1433 objects[objeid] = len(relations_by_rtype[rtype]) |
1402 for source, relations_by_rtype in sources.iteritems(): |
1434 for source, relations_by_rtype in sources.iteritems(): |
1403 if source.should_call_hooks: |
1435 if source.should_call_hooks: |
1404 for rtype, source_relations in relations_by_rtype.iteritems(): |
1436 for rtype, source_relations in relations_by_rtype.iteritems(): |
1405 for subject, object in source_relations: |
|
1406 del_existing_rel_if_needed(session, subject, rtype, object) |
|
1407 self.hm.call_hooks('before_add_relation', session, |
1437 self.hm.call_hooks('before_add_relation', session, |
1408 rtype=rtype, eids_from_to=source_relations) |
1438 rtype=rtype, eids_from_to=source_relations) |
1409 for rtype, source_relations in relations_by_rtype.iteritems(): |
1439 for rtype, source_relations in relations_by_rtype.iteritems(): |
1410 source.add_relations(session, rtype, source_relations) |
1440 source.add_relations(session, rtype, source_relations) |
1411 rschema = self.schema.rschema(rtype) |
1441 rschema = self.schema.rschema(rtype) |
1412 for subject, object in source_relations: |
1442 for subjeid, objeid in source_relations: |
1413 session.update_rel_cache_add(subject, rtype, object, rschema.symmetric) |
1443 session.update_rel_cache_add(subjeid, rtype, objeid, rschema.symmetric) |
1414 if source.should_call_hooks: |
1444 if source.should_call_hooks: |
1415 for rtype, source_relations in relations_by_rtype.iteritems(): |
1445 for rtype, source_relations in relations_by_rtype.iteritems(): |
1416 self.hm.call_hooks('after_add_relation', session, |
1446 self.hm.call_hooks('after_add_relation', session, |
1417 rtype=rtype, eids_from_to=source_relations) |
1447 rtype=rtype, eids_from_to=source_relations) |
1418 |
1448 |