Пример #1
0
    def save(self, subj, node=None):
        """ Save an object to a database node.

        :param subj: the object to save
        :param node: the database node to save to (if omitted, will re-save to
            same node as previous save)
        """
        if node is not None:
            subj.__node__ = node
        # naively copy properties from object to node
        props = {}
        for key, value in subj.__dict__.items():
            if not key.startswith("_"):
                props[key] = value
        if hasattr(subj, "__node__"):
            subj.__node__.set_properties(props)
            query = CypherQuery(self.graph, "START a=node({A}) "
                                                     "MATCH (a)-[r]->(b) "
                                                     "DELETE r")
            query.execute(A=subj.__node__._id)
        else:
            subj.__node__, = self.graph.create(props)
        # write rels
        if hasattr(subj, "__rel__"):
            batch = WriteBatch(self.graph)
            for rel_type, rels in subj.__rel__.items():
                for rel_props, endpoint in rels:
                    end_node = self._get_node(endpoint)
                    if end_node not in self.graph:
                        raise ValueError(end_node)
                    batch.create((subj.__node__, rel_type, end_node, rel_props))
            batch.run()
        return subj
Пример #2
0
class TestIndexedRelationshipAddition(object):
    @pytest.fixture(autouse=True)
    def setup(self, graph):
        try:
            graph.legacy.delete_index(Relationship, "Friendships")
        except LookupError:
            pass
        self.friendships = graph.legacy.get_or_create_index(
            Relationship, "Friendships")
        self.batch = LegacyWriteBatch(graph)
        self.graph = graph

    def test_can_add_single_relationship(self, graph):
        alice, bob, ab = self.graph.create({"name": "Alice"}, {"name": "Bob"},
                                           (0, "KNOWS", 1))
        self.batch.add_to_index(Relationship, self.friendships, "friends",
                                "alice_&_bob", ab)
        self.batch.run()
        # check entries
        rels = self.friendships.get("friends", "alice_&_bob")
        assert len(rels) == 1
        assert ab in rels
        # done
        self.recycling = [ab, alice, bob]

    def test_can_add_two_similar_relationships(self, graph):
        alice, bob, ab1, ab2 = self.graph.create({"name": "Alice"},
                                                 {"name": "Bob"},
                                                 (0, "KNOWS", 1),
                                                 (0, "KNOWS", 1))
        self.batch.add_to_index(Relationship, self.friendships, "friends",
                                "alice_&_bob", ab1)
        self.batch.add_to_index(Relationship, self.friendships, "friends",
                                "alice_&_bob", ab2)
        self.batch.run()
        # check entries
        entries = self.friendships.get("friends", "alice_&_bob")
        assert len(entries) == 2
        assert ab1 in entries
        assert ab2 in entries
        # done
        self.recycling = [ab1, ab2, alice, bob]

    def test_can_add_relationships_only_if_none_exist(self):
        alice, bob, ab1, ab2 = self.graph.create({"name": "Alice"},
                                                 {"name": "Bob"},
                                                 (0, "KNOWS", 1),
                                                 (0, "KNOWS", 1))
        self.batch.get_or_add_to_index(Relationship, self.friendships,
                                       "friends", "alice_&_bob", ab1)
        self.batch.get_or_add_to_index(Relationship, self.friendships,
                                       "friends", "alice_&_bob", ab2)
        results = self.batch.submit()
        assert results[0] == results[1]
        # check entries
        entries = self.friendships.get("friends", "alice_&_bob")
        assert len(entries) == 1
        assert ab1 in entries
        # done
        self.recycling = [ab1, ab2, alice, bob]
Пример #3
0
class TestIndexedRelationshipAddition(object):

    @pytest.fixture(autouse=True)
    def setup(self, legacy_graph):
        try:
            legacy_graph.delete_index(Relationship, "Friendships")
        except LookupError:
            pass
        self.friendships = legacy_graph.get_or_create_index(Relationship, "Friendships")
        self.batch = LegacyWriteBatch(legacy_graph)
        self.graph = legacy_graph

    def test_can_add_single_relationship(self, legacy_graph):
        alice, bob, ab = self.graph.create({"name": "Alice"}, {"name": "Bob"}, (0, "KNOWS", 1))
        self.batch.add_to_index(Relationship, self.friendships, "friends", "alice_&_bob", ab)
        self.batch.run()
        # check entries
        rels = self.friendships.get("friends", "alice_&_bob")
        assert len(rels) == 1
        assert ab in rels
        # done
        self.recycling = [ab, alice, bob]

    def test_can_add_two_similar_relationships(self, legacy_graph):
        alice, bob, ab1, ab2 = self.graph.create(
            {"name": "Alice"}, {"name": "Bob"},
            (0, "KNOWS", 1), (0, "KNOWS", 1))
        self.batch.add_to_index(Relationship, self.friendships, "friends", "alice_&_bob", ab1)
        self.batch.add_to_index(Relationship, self.friendships, "friends", "alice_&_bob", ab2)
        self.batch.run()
        # check entries
        entries = self.friendships.get("friends", "alice_&_bob")
        assert len(entries) == 2
        assert ab1 in entries
        assert ab2 in entries
        # done
        self.recycling = [ab1, ab2, alice, bob]

    def test_can_add_relationships_only_if_none_exist(self):
        alice, bob, ab1, ab2 = self.graph.create(
            {"name": "Alice"}, {"name": "Bob"},
            (0, "KNOWS", 1), (0, "KNOWS", 1))
        self.batch.get_or_add_to_index(Relationship, self.friendships,
                                       "friends", "alice_&_bob", ab1)
        self.batch.get_or_add_to_index(Relationship, self.friendships,
                                       "friends", "alice_&_bob", ab2)
        results = self.batch.submit()
        assert results[0] == results[1]
        # check entries
        entries = self.friendships.get("friends", "alice_&_bob")
        assert len(entries) == 1
        assert ab1 in entries
        # done
        self.recycling = [ab1, ab2, alice, bob]
Пример #4
0
class TestIndexedNodeAddition(object):
    @pytest.fixture(autouse=True)
    def setup(self, graph):
        try:
            graph.legacy.delete_index(Node, "People")
        except LookupError:
            pass
        self.people = graph.legacy.get_or_create_index(Node, "People")
        self.batch = LegacyWriteBatch(graph)
        self.graph = graph

    def test_can_add_single_node(self):
        alice, = self.graph.create({"name": "Alice Smith"})
        self.batch.add_to_index(Node, self.people, "surname", "Smith", alice)
        self.batch.run()
        # check entries
        smiths = self.people.get("surname", "Smith")
        assert len(smiths) == 1
        assert alice in smiths
        # done
        self.graph.delete(alice)

    def test_can_add_two_similar_nodes(self):
        alice, bob = self.graph.create({"name": "Alice Smith"},
                                       {"name": "Bob Smith"})
        self.batch.add_to_index(Node, self.people, "surname", "Smith", alice)
        self.batch.add_to_index(Node, self.people, "surname", "Smith", bob)
        nodes = self.batch.submit()
        assert nodes[0] != nodes[1]
        # check entries
        smiths = self.people.get("surname", "Smith")
        assert len(smiths) == 2
        assert alice in smiths
        assert bob in smiths
        # done
        self.graph.delete(alice, bob)

    def test_can_add_nodes_only_if_none_exist(self):
        alice, bob = self.graph.create({"name": "Alice Smith"},
                                       {"name": "Bob Smith"})
        self.batch.get_or_add_to_index(Node, self.people, "surname", "Smith",
                                       alice)
        self.batch.get_or_add_to_index(Node, self.people, "surname", "Smith",
                                       bob)
        nodes = self.batch.submit()
        assert nodes[0] == nodes[1]
        # check entries
        smiths = self.people.get("surname", "Smith")
        assert len(smiths) == 1
        assert alice in smiths
        # done
        self.graph.delete(alice, bob)
Пример #5
0
class TestIndexedNodeAddition(object):

    @pytest.fixture(autouse=True)
    def setup(self, legacy_graph):
        try:
            legacy_graph.delete_index(Node, "People")
        except LookupError:
            pass
        self.people = legacy_graph.get_or_create_index(Node, "People")
        self.batch = LegacyWriteBatch(legacy_graph)
        self.graph = legacy_graph

    def test_can_add_single_node(self):
        alice, = self.graph.create({"name": "Alice Smith"})
        self.batch.add_to_index(Node, self.people, "surname", "Smith", alice)
        self.batch.run()
        # check entries
        smiths = self.people.get("surname", "Smith")
        assert len(smiths) == 1
        assert alice in smiths
        # done
        self.graph.delete(alice)

    def test_can_add_two_similar_nodes(self):
        alice, bob = self.graph.create(
            {"name": "Alice Smith"}, {"name": "Bob Smith"})
        self.batch.add_to_index(Node, self.people, "surname", "Smith", alice)
        self.batch.add_to_index(Node, self.people, "surname", "Smith", bob)
        nodes = self.batch.submit()
        assert nodes[0] != nodes[1]
        # check entries
        smiths = self.people.get("surname", "Smith")
        assert len(smiths) == 2
        assert alice in smiths
        assert bob in smiths
        # done
        self.graph.delete(alice, bob)

    def test_can_add_nodes_only_if_none_exist(self):
        alice, bob = self.graph.create(
            {"name": "Alice Smith"}, {"name": "Bob Smith"})
        self.batch.get_or_add_to_index(Node, self.people, "surname", "Smith", alice)
        self.batch.get_or_add_to_index(Node, self.people, "surname", "Smith", bob)
        nodes = self.batch.submit()
        assert nodes[0] == nodes[1]
        # check entries
        smiths = self.people.get("surname", "Smith")
        assert len(smiths) == 1
        assert alice in smiths
        # done
        self.graph.delete(alice, bob)
Пример #6
0
class TestIndexedNodeRemoval(object):
    @pytest.fixture(autouse=True)
    def setup(self, graph):
        self.graph = graph
        try:
            graph.legacy.delete_index(Node, "node_removal_test_index")
        except LookupError:
            pass
        self.index = graph.legacy.get_or_create_index(
            Node, "node_removal_test_index")
        self.fred, self.wilma, = graph.create(
            {"name": "Fred Flintstone"},
            {"name": "Wilma Flintstone"},
        )
        self.index.add("name", "Fred", self.fred)
        self.index.add("name", "Wilma", self.wilma)
        self.index.add("name", "Flintstone", self.fred)
        self.index.add("name", "Flintstone", self.wilma)
        self.index.add("flintstones", "%", self.fred)
        self.index.add("flintstones", "%", self.wilma)
        self.batch = LegacyWriteBatch(graph)

    def check(self, key, value, *entities):
        e = self.index.get(key, value)
        assert len(entities) == len(e)
        for entity in entities:
            assert entity in e

    def test_remove_key_value_entity(self):
        self.batch.remove_from_index(Node,
                                     self.index,
                                     key="name",
                                     value="Flintstone",
                                     entity=self.fred)
        self.batch.run()
        self.check("name", "Fred", self.fred)
        self.check("name", "Wilma", self.wilma)
        self.check("name", "Flintstone", self.wilma)
        self.check("flintstones", "%", self.fred, self.wilma)

    def test_remove_key_entity(self):
        self.batch.remove_from_index(Node,
                                     self.index,
                                     key="name",
                                     entity=self.fred)
        self.batch.run()
        self.check("name", "Fred")
        self.check("name", "Wilma", self.wilma)
        self.check("name", "Flintstone", self.wilma)
        self.check("flintstones", "%", self.fred, self.wilma)

    def test_remove_entity(self):
        self.batch.remove_from_index(Node, self.index, entity=self.fred)
        self.batch.run()
        self.check("name", "Fred")
        self.check("name", "Wilma", self.wilma)
        self.check("name", "Flintstone", self.wilma)
        self.check("flintstones", "%", self.wilma)
Пример #7
0
class TestIndexedNodeRemoval(object):

    @pytest.fixture(autouse=True)
    def setup(self, legacy_graph):
        self.graph = legacy_graph
        try:
            legacy_graph.delete_index(Node, "node_removal_test_index")
        except LookupError:
            pass
        self.index = legacy_graph.get_or_create_index(Node, "node_removal_test_index")
        self.fred, self.wilma, = legacy_graph.create(
            {"name": "Fred Flintstone"}, {"name": "Wilma Flintstone"},
        )
        self.index.add("name", "Fred", self.fred)
        self.index.add("name", "Wilma", self.wilma)
        self.index.add("name", "Flintstone", self.fred)
        self.index.add("name", "Flintstone", self.wilma)
        self.index.add("flintstones", "%", self.fred)
        self.index.add("flintstones", "%", self.wilma)
        self.batch = LegacyWriteBatch(legacy_graph)

    def check(self, key, value, *entities):
        e = self.index.get(key, value)
        assert len(entities) == len(e)
        for entity in entities:
            assert entity in e

    def test_remove_key_value_entity(self):
        self.batch.remove_from_index(Node, self.index, key="name",
                                     value="Flintstone", entity=self.fred)
        self.batch.run()
        self.check("name", "Fred", self.fred)
        self.check("name", "Wilma", self.wilma)
        self.check("name", "Flintstone", self.wilma)
        self.check("flintstones", "%", self.fred, self.wilma)

    def test_remove_key_entity(self):
        self.batch.remove_from_index(Node, self.index, key="name", entity=self.fred)
        self.batch.run()
        self.check("name", "Fred")
        self.check("name", "Wilma", self.wilma)
        self.check("name", "Flintstone", self.wilma)
        self.check("flintstones", "%", self.fred, self.wilma)

    def test_remove_entity(self):
        self.batch.remove_from_index(Node, self.index, entity=self.fred)
        self.batch.run()
        self.check("name", "Fred")
        self.check("name", "Wilma", self.wilma)
        self.check("name", "Flintstone", self.wilma)
        self.check("flintstones", "%", self.wilma)