示例#1
0
    def test_can_add_named_node(self):
        p = Pypher()
        p.node('name')
        exp = '(name)'

        self.assertEqual(str(p), exp)
示例#2
0
    def test_can_create_pypher(self):
        p = Pypher()

        self.assertIsInstance(p, Pypher)
示例#3
0
    def test_can_add_empty_node_with_one_label(self):
        p = Pypher()
        p.node(labels='Test')
        exp = '(:`Test`)'

        self.assertEqual(str(p), exp)
示例#4
0
    def test_can_add_empty_undirected_relationship_with_fixed_length(self):
        p = Pypher()
        p.relationship(min_hops=3, max_hops=3)
        exp = '-[*3]-'

        self.assertEqual(str(p), exp)
示例#5
0
    def test_can_add_empty_node(self):
        p = Pypher()
        p.node()
        exp = '()'

        self.assertEqual(str(p), exp)
示例#6
0
    def test_can_add_empty_out_relationship(self):
        p = Pypher()
        p.relationship(direction='out')
        exp = '-->'

        self.assertEqual(str(p), exp)
示例#7
0
    def test_can_add_named_in_relationship(self):
        p = Pypher()
        p.rel('name', direction='<')
        exp = '<-[name]-'

        self.assertEqual(str(p), exp)
示例#8
0
 def test_can_nest_map(self):
     p = Pypher()
     p.collect(__.map('one', 'two', 'three'))
     q = str(p)
     exp = 'collect({one, two, three})'
     self.assertEqual(exp, q)
示例#9
0
    def save_relationship(self, entity, ensure_unique=False):
        """this method handles creating and saving relationships.
        It will hanle quite a few situations. 
        Given the structure:

        (start)-[rel]->[end]

        We can have:
        * A new start node
        * An existing start node
        * A new rel
        * An existing rel
        * A new end node
        * An existing end node

        Each start, rel, and end could have uniqueness assigned to it
        * start/end could have unique properties
        * rel could have unique relationships

        A Chyper query should be generated that looks something like this,
        depending on the settings for each of the nodes:

        MERGE (n_0:Node {`key`: val})
        ON CREATE SET n_0.key = val, n_0.key2 = val2
        ON MATCH SET n_0.key = val, n_0.key2 = val2
        CREATE (n_0)-[r_0:RelLabel, {`key`: someVal}]->(n_1:Node {`key`: val})
        RETURN n_0, n_1, r_0
        """
        start = entity.start
        start_properties = {}
        end = entity.end
        end_properties = {}
        props = self._properties(entity)

        if start is None or end is None:
            raise Exception('The relationship must have a start and end node')

        if not isinstance(start, Node):
            start = Node(id=start)

        if not isinstance(end, Node):
            end = Node(id=end)

        VM.set_query_var(start)
        VM.set_query_var(end)
        VM.set_query_var(entity)

        rel = Pypher()

        if start not in self.matched_entities:
            if start.id is not None:
                self._update_properties(start)
                self.matches.append(self._node_by_id(start))
            else:
                start_properties = self._properties(start)

            self.matched_entities.append(start)
            self.returns.append(start.query_variable)

        if end not in self.matched_entities:
            if end.id is not None:
                self._update_properties(end)
                self.matches.append(self._node_by_id(end))
            else:
                end_properties = self._properties(end)

            self.matched_entities.append(end)
            self.returns.append(end.query_variable)

        if entity.id is None:
            if start.id is not None:
                rel = rel.node(start.query_variable)
            else:
                start_query = Query(start, self.params)
                start_query.build_save_pypher()

                if len(start_query.creates):
                    rel.append(*start_query.creates)
                elif len(start_query.merges):
                    has_matches = len(self.matches) > 0
                    start_merge = Pypher()
                    start_merge.MERGE(*start_query.merges)

                    if start_query.on_create_sets:
                        start_merge.OnCreateSet(*start_query.on_create_sets)

                    if start_query.on_match_sets:
                        start_merge.OnMatchSet(*start_query.on_match_sets)

                    self.before_matches.append(start_merge)
                    rel.node(start.query_variable)

            rel.rel(entity.query_variable,
                    labels=entity.labels,
                    direction='out',
                    **props)

            if end.id is not None:
                rel.node(end.query_variable)
            else:
                end_query = Query(end, self.params)
                end_query.build_save_pypher()

                if len(end_query.creates):
                    rel.append(*end_query.creates)
                elif len(end_query.merges):
                    end_merge = Pypher().MERGE(*end_query.merges)

                    if end_query.on_create_sets:
                        end_merge.OnCreateSet(*end_query.on_create_sets)

                    if end_query.on_match_sets:
                        end_merge.OnMatchSet(*end_query.on_match_sets)

                    self.before_matches.append(end_merge)
                    rel.node(end.query_variable)

            if ensure_unique:
                self.merges.append(rel)
            else:
                self.creates.append(rel)
        else:
            _id = VM.get_next(entity, 'id')
            _id = Param(_id, entity.id)

            if start.id is not None:
                rel = rel.node(start.query_variable)
            else:
                start_query = Query(start, self.params)
                start_query.build_save_pypher()

                if len(start_query.creates):
                    rel.append(*start_query.creates)
                elif len(start_query.merges):
                    start_merge = Pypher().MERGE(*start_query.merges)

                    if start_query.on_create_sets:
                        start_merge.OnCreateSet(*start_query.on_create_sets)

                    if start_query.on_match_sets:
                        start_merge.OnMatchSet(*start_query.on_match_sets)

                    if len(self.matches):
                        self.matches[-1].append(start_merge)
                    else:
                        self.matches.append(start_merge)

                    rel.node(start.query_variable)

            rel.rel(entity.query_variable,
                    labels=entity.labels,
                    direction='out')

            if end.id is not None:
                rel.node(end.query_variable)
            else:
                end_query = Query(end, self.params)
                end_query.build_save_pypher()

                if len(end_query.creates):
                    rel.append(*end_query.creates)
                elif len(end_query.merges):
                    end_merge = Pypher().MERGE(*end_query.merges)

                    if end_query.on_create_sets:
                        end_merge.OnCreateSet(*end_query.on_create_sets)

                    if end_query.on_match_sets:
                        end_merge.OnMatchSet(*end_query.on_match_sets)

                    if len(self.matches):
                        self.matches[-1].append(end_merge)
                    else:
                        self.matches.append(end_merge)

                    rel.node(end.query_variable)

            rel.WHERE(__.ID(entity.query_variable) == _id)
            self._update_properties(entity)
            self.matches.append(rel)

        self.returns.append(entity.query_variable)

        return self
示例#10
0
    def test_can_assign_variable(self):
        p = Pypher()
        p.MATCH.p.assign(__.node('n').rel_out().node('m'))
        exp = 'MATCH p = (n)-->(m)'

        self.assertEqual(str(p), exp)
示例#11
0
    def test_can_reuse_params_object_across_pypher_isntances(self):
        params = Params('xxx')
        p = Pypher(params=params)
        p2 = Pypher(params=params)

        self.assertEqual(id(p.params), id(p2.params))
示例#12
0
    def test_can_add_multiple_labels(self):
        p = Pypher()
        p.n.label(['one', 'two', 'three', 'four'])
        exp = 'n:`one`:`two`:`three`:`four`'

        self.assertEqual(str(p), exp)
示例#13
0
    def test_can_add_named_undirected_relationship_with_labels(self):
        p = Pypher()
        p.relationship(variable='test', labels=['one', 'two', 'three'])
        exp = '-[test:`one`|`two`|`three`]-'

        self.assertEqual(str(p), exp)
示例#14
0
 def test_using_hops_and_max_hops_raises_error(self):
     p = Pypher()
     with self.assertRaises(ValueError):
         p.relationship(hops=2, max_hops=3)
示例#15
0
    def test_can_add_named_node_with_multiple_labels(self):
        p = Pypher()
        p.node('name', labels=['Test', 'one', 'two'])
        exp = '(name:`Test`:`one`:`two`)'

        self.assertEqual(str(p), exp)
示例#16
0
    def test_can_add_alias_using_alias(self):
        p = Pypher()
        p.mark.alias('MARK')
        exp = 'mark AS MARK'

        self.assertEqual(exp, str(p))
示例#17
0
    def test_can_add_empty_undirected_relationship(self):
        p = Pypher()
        p.relationship()
        exp = '--'

        self.assertEqual(str(p), exp)
示例#18
0
    def test_will_get_param_object_from_binding_param(self):
        v = 'v'
        p = Pypher()
        param = p.bind_param(v)

        self.assertIsInstance(param, Param)
示例#19
0
    def test_can_add_empty_in_relationship(self):
        p = Pypher()
        p.relationship(direction='in')
        exp = '<--'

        self.assertEqual(str(p), exp)
示例#20
0
    def test_can_add_statement_and_property(self):
        p = Pypher()
        p.RETURN.property('money')
        exp = 'RETURN.`money`'

        self.assertEqual(str(p), exp)
示例#21
0
    def test_can_add_empty_undirected_relationship_with_types(self):
        p = Pypher()
        p.relationship(types=['one', 'two', 'three'])
        exp = '-[:`one`|`two`|`three`]-'

        self.assertEqual(str(p), exp)
示例#22
0
    def test_can_add_empty_undirected_relationship_with_min_max_hop(self):
        p = Pypher()
        p.relationship(min_hops=1, max_hops=3)
        exp = '-[*1..3]-'

        self.assertEqual(str(p), exp)