def test_fix_old_neighbors(self): """Check if _fix_old_neighbors. - Deletes old children. - Adds connection to old parents. """ c = city.City(name="Freiburg") with CoreSession() as session: wrapper = city.CityWrapper(session=session) cw = wrapper.add(c) n = city.Neighborhood(name="Zähringen") nw = cw.add(n) c = clone_cuds_object(c) c._session = session old_neighbor_diff = get_neighbor_diff(cw, c) old_neighbors = session.load(*[x[0] for x in old_neighbor_diff]) Cuds._fix_old_neighbors( new_cuds_object=c, old_cuds_object=cw, old_neighbors=old_neighbors, old_neighbor_diff=old_neighbor_diff, ) self.assertEqual(c.get(rel=city.isPartOf), [wrapper]) self.assertEqual(c.get(rel=city.hasPart), []) self.assertEqual(nw.get(rel=city.isPartOf), []) self.assertEqual(wrapper.get(rel=city.hasPart), [c])
def __call__(self, uid=None, session=None, _force=False, **kwargs): """Create a Cuds object from this ontology class. Args: uid (UUID, optional): The uid of the Cuds object. Should be set to None in most cases. Then a new UUID is generated, defaults to None. Defaults to None. session (Session, optional): The session to create the cuds object in, defaults to None. Defaults to None. _force (bool, optional): Skip validity checks. Defaults to False. Raises: TypeError: Error occurred during instantiation. Returns: Cuds: The created cuds object """ from osp.core.cuds import Cuds from osp.core.namespaces import cuba if self.is_subclass_of(cuba.Wrapper) and session is None: raise TypeError("Missing keyword argument 'session' for wrapper.") if self.is_subclass_of(cuba.Nothing): raise TypeError("Cannot instantiate cuds object for ontology class" " cuba.Nothing.") # build attributes dictionary by combining # kwargs and defaults return Cuds(attributes=self._get_attributes_values(kwargs, _force=_force), oclass=self, session=session, uid=uid)
def test_fix_new_parents(self): """Check _fix_new_parent. Make sure the method: - Deletes connection to new parents not available in new session - Adds connection to new parents available in new session """ n = city.Neighborhood(name="Zähringen") # parent in both sessions c1 = city.City(name="Berlin") # only parent in default session (available in both) c2 = city.City(name="Paris") n.add(c1, c2, rel=city.isPartOf) c3 = city.City(name="London") with CoreSession() as session: wrapper = city.CityWrapper(session=session) c1w, c2w = wrapper.add(c1, c2) nw = c2w.get(n.uid) nw.remove(c2.uid, rel=cuba.relationship) # only parent + available in default session n.add(c3, rel=city.isPartOf) n = clone_cuds_object(n) n._session = session new_parent_diff = get_neighbor_diff(n, nw, mode="non-active") new_parents = session.load(*[x[0] for x in new_parent_diff]) missing = dict() Cuds._fix_new_parents( new_cuds_object=n, new_parents=new_parents, new_parent_diff=new_parent_diff, missing=missing, ) self.assertEqual( set(n.get(rel=city.isPartOf)), {c1w, c2w, None}, # missing parent, should be in missing dict ) self.assertEqual(missing, {c3.uid: [(n, city.isPartOf)]}) self.assertEqual(c2w.get(rel=city.hasPart), [n])
def create_from_triples(triples, neighbor_triples, session, fix_neighbors=True): """Create a CUDS object from triples. Args: triples (List[Tuple]): The list of triples of the CUDS object to create. neighbor_triples (List[Tuple]): A list of important triples of neighbors, most importantly their types. session (Session): The session to create the CUDS object in. fix_neighbors (bool): Whether to remove the link from the old neighbors to this cuds object, defaults to True. """ from osp.core.cuds import Cuds from osp.core.session.wrapper_session import WrapperSession from osp.core.utils.general import uid_from_iri triples = list(triples) if not triples: return None uid = uid_from_iri(triples[0][0]) if isinstance(session, WrapperSession) and uid in session._expired: session._expired.remove(uid) # recycle old object if uid in session._registry: cuds_object = session._registry.get(uid) cuds_object.session._notify_read(cuds_object) if fix_neighbors: rels = set(cuds_object._neighbors.keys()) for rel in rels: cuds_object.remove(rel=rel) session.graph.remove((cuds_object.iri, None, None)) for triple in set(triples): session.graph.add(triple) else: # create new cuds_object = Cuds( attributes={}, oclass=None, session=session, uid=uid, extra_triples=set(triples), ) # add the triples for triple in set(neighbor_triples): session.graph.add(triple) if isinstance(session, WrapperSession): session._store_checks(cuds_object) cuds_object.session._notify_update(cuds_object) return cuds_object
def __call__(self, session=None, iri=None, uid=None, _force=False, **kwargs): """Create a Cuds object from this ontology class. Args: uid (Union[UUID, int], optional): The identifier of the Cuds object. Should be set to None in most cases. Then a new identifier is generated, defaults to None. Defaults to None. iri (Union[URIRef, str], optional): The same as the uid, but exclusively for IRI identifiers. session (Session, optional): The session to create the cuds object in, defaults to None. Defaults to None. _force (bool, optional): Skip validity checks. Defaults to False. Raises: TypeError: Error occurred during instantiation. Returns: Cuds: The created cuds object """ # Accept strings as IRI identifiers and integers as UUID identifiers. types_map = { int: lambda x: uuid.UUID(int=x), str: lambda x: rdflib.URIRef(x), rdflib.URIRef: lambda x: x, uuid.UUID: lambda x: x, type(None): lambda x: x, } iri, uid = (types_map[type(x)](x) for x in (iri, uid)) from osp.core.cuds import Cuds from osp.core.namespaces import cuba if self.is_subclass_of(cuba.Wrapper) and session is None: raise TypeError("Missing keyword argument 'session' for wrapper.") if self.is_subclass_of(cuba.Nothing): raise TypeError("Cannot instantiate cuds object for ontology class" " cuba.Nothing.") # build attributes dictionary by combining # kwargs and defaults return Cuds( attributes=self._get_attributes_values(kwargs, _force=_force), oclass=self, session=session, iri=iri, uid=uid, )
def create_recycle(oclass, kwargs, session, uid, fix_neighbors=True, _force=False): """Instantiate a cuds_object with a given session. If cuds_object with same uid is already in the session, this object will be reused. Args: oclass (Cuds): The OntologyClass of cuds_object to instantiate kwargs (Dict[str, Any]): The kwargs of the cuds_object session (Session): The session of the new Cuds object uid (Union[UUID, URIRef): The uid of the new Cuds object fix_neighbors (bool): Whether to remove the link from the old neighbors to this cuds object, defaults to True _force (bool): Skip sanity checks. Returns: Cuds: The created cuds object. """ from osp.core.cuds import Cuds from osp.core.session.wrapper_session import WrapperSession uid = convert_to(uid, "UID") if isinstance(session, WrapperSession) and uid in session._expired: session._expired.remove(uid) # recycle old object if uid in session._registry: cuds_object = session._registry.get(uid) for rel in set(cuds_object._neighbors.keys()): if not fix_neighbors: del cuds_object._neighbors[rel] else: cuds_object.remove(rel=rel) change_oclass(cuds_object, oclass, kwargs, _force=_force) else: # create new if oclass is not None: cuds_object = oclass(uid=uid, session=session, **kwargs, _force=_force) else: cuds_object = Cuds(uid=uid, session=session, **kwargs) return cuds_object
def test_fix_neighbors(self): """Test fixing the neighbors after replacing CUDS objects.""" w1 = city.CityWrapper(session=CoreSession()) w2 = city.CityWrapper(session=CoreSession()) c1w1 = city.City(name="city1") # parent in both wrappers c2w1 = city.City(name="city2") # parent in w1, not present in w2 c3w1 = city.City(name="city3") # parent only in w1, present in w2 c4w1 = city.City(name="city4") # parent only in w2 p1w1 = city.Citizen(name="citizen") p2w1 = city.Citizen(name="child") w2.add(c1w1, c3w1, c4w1) c1w2, c3w2, c4w2 = w2.get(c1w1.uid, c3w1.uid, c4w1.uid) c1w2.add(p1w1, rel=city.hasInhabitant) c4w2.add(p1w1, rel=city.hasInhabitant) p1w2 = c1w2.get(p1w1.uid) p1w2.add(p2w1, rel=city.hasChild) p2w2 = p1w2.get(p2w1.uid) w1.add(c1w1, c2w1, c3w1, c4w1) c1w1.add(p1w1, rel=city.hasInhabitant) c2w1.add(p1w1, rel=city.hasInhabitant) c3w1.add(p1w1, rel=city.hasInhabitant) self.assertEqual( set(p1w1._neighbors[city.INVERSE_OF_hasInhabitant].keys()), set([c1w1.uid, c2w1.uid, c3w1.uid]), ) self.assertEqual(set(p2w2._neighbors[city.isChildOf].keys()), set([p1w2.uid])) missing = dict() Cuds._fix_neighbors( new_cuds_object=p1w1, old_cuds_object=p1w2, session=p1w2.session, missing=missing, ) # check if connections cuds_objects that are no # longer parents are in the missing dict self.assertIn(c2w1.uid, missing) self.assertEqual( set(p1w1._neighbors[city.INVERSE_OF_hasInhabitant].keys()), set([c1w1.uid, c2w1.uid, c3w1.uid, c4w1.uid]), ) self.assertNotIn(city.isPartOf, p2w2._neighbors) # check if there are no unexpected other changes self.assertEqual(set(c1w1._neighbors[city.hasInhabitant].keys()), set([p1w1.uid])) self.assertEqual(set(c2w1._neighbors[city.hasInhabitant].keys()), set([p1w1.uid])) self.assertEqual(set(c3w1._neighbors[city.hasInhabitant].keys()), set([p1w1.uid])) self.assertNotIn(city.hasInhabitant, c4w1._neighbors) # check if the parents in w2 have been updated self.assertEqual(set(c1w2._neighbors[city.hasInhabitant].keys()), set([p1w1.uid])) self.assertEqual(set(c3w2._neighbors[city.hasInhabitant].keys()), set([p1w1.uid])) self.assertEqual(set(c4w2._neighbors[city.hasInhabitant].keys()), set([p1w1.uid]))