Ejemplo n.º 1
0
 def get_node_information_query(node_name, node_type=None):
     """
     :param node_name: name of the node to get information about.
     :return: the query for showing general information of one node (any entity) with a specific name.
     """
     pypher_object = Pypher()
     if node_type is None:
         pypher_object.Match.node('u').where.u.__name__.CONTAINS(
             Param('per_param', node_name))
     else:
         pypher_object.Match.node(
             'u', labels=node_type).where.u.__name__.CONTAINS(
                 Param('per_param', node_name))
     pypher_object.RETURN('u')
     return GenerateQuery.reformat_query(pypher_object)
Ejemplo n.º 2
0
    def filtering(self, query_variable):
        wheres = []
        fields = self.controller.filter_by

        for i, field in enumerate(fields):
            try:
                if '.' in field:
                    splits = field.split('.')
                    field = splits[-1]
                    query_variable = splits[0]

                value = self.controller.get_argument(field)
            except MissingArgumentError as e:
                # we will swallow these, but let the others proprogate
                continue

            if value:
                exclude = False
                clause = __()

                if value[0] == '!':
                    exclude = True
                    value = value[1:]

                if exclude:
                    clause = clause.NOT

                query_variable = self.get_mapped_query_variable(query_variable)
                name = '{}_{}'.format(field, i).replace('.', '_')
                value = Param(name, value)
                clause = getattr(clause, query_variable).property(field)
                clause = clause.CONTAINS(value)
                wheres.append(clause)

        return wheres
Ejemplo n.º 3
0
    def _entity_by_id_builder(self, entity, id_val, add_labels=False):
        qv = entity.query_variable

        if not qv:
            qv = VM.set_query_var(entity)

        _id = VM.get_next(entity, 'id')
        _id = Param(_id, id_val)
        node_kwargs = {}

        if add_labels:
            node_kwargs['labels'] = entity.labels

        if isinstance(entity, Relationship):
            node = __.node(**node_kwargs).relationship(qv).node()
        else:
            node = __.node(qv, **node_kwargs)

        where = __.ID(qv) == _id

        self.matches.append(node)
        self.wheres.append(where)
        self.returns.append(entity.query_variable)

        return self
Ejemplo n.º 4
0
    def delete_node(self, entity):
        _id = VM.get_next(entity, 'id')
        _id = Param(_id, entity.id)
        match = __.node(entity.query_variable)
        match.WHERE(__.ID(entity.query_variable) == _id)

        self.matches.append(match)
        self.deletes.append(entity.query_variable)

        return self
Ejemplo n.º 5
0
    def _node_by_id(self, entity):
        qv = entity.query_variable

        if not qv:
            qv = VM.set_query_var(entity)

        _id = VM.get_next(entity, 'id')
        _id = Param(_id, entity.id)

        return __.node(qv).WHERE(__.ID(qv) == _id)
Ejemplo n.º 6
0
    def test_can_add_param_to_statement(self):
        p = Pypher()
        n = 'some_param'
        v = 'value {}'.format(random())
        param = Param(n, v)
        p.CONTAINS(param)
        exp = 'CONTAINS ${}'.format(n)
        s = str(p)

        self.assertEqual(exp, s)
        self.assertEqual(1, len(p.bound_params))
Ejemplo n.º 7
0
    def delete_relationship(self, entity):
        _id = VM.get_next(entity, 'id')
        _id = Param(_id, entity.id)
        match = __.node()
        match.rel(entity.query_variable, labels=entity.labels)
        match.node()
        match.WHERE(__.ID(entity.query_variable) == _id)

        self.matches.append(match)
        self.deletes.append(entity.query_variable)

        return self
Ejemplo n.º 8
0
    def test_can_bind_param_object_to_pypher(self):
        n = 'some name'
        v = 'value {}'.format(random())

        v = Param(n, v)
        p = Pypher()
        param = p.bind_param(v)

        str(p)
        params = p.bound_params

        self.assertNotEqual(id(v), id(param))
        self.assertIn(v.value, params.values())
        self.assertIn(n, params)
        self.assertEqual(1, len(params))
Ejemplo n.º 9
0
    def delete_by_entity_id(self, *ids):
        if not ids:
            msg = 'There must be ids passed in to the delete method'
            raise AttributeError(msg)

        def _build_start():
            pypher = Pypher()

            if self.start_entity.id is not None:
                qv = self.start_entity.query_variable
                where = __.ID(qv) == self.start_entity.id

                pypher.NODE(qv)
                self.wheres.append(where)
            else:
                pypher.NODE(self.start_query_variable)

            return pypher

        self.pypher = Pypher()
        self.matches.insert(0, self._build_end())
        self.matches.insert(0, self._build_relationship())
        self.matches.insert(0, _build_start())

        self.pypher.MATCH

        for match in self.matches:
            self.pypher.append(match)

        id_params = []

        for i in ids:
            key = 'end_id_{}'.format(i)
            id_params.append(Param(key, i))

        self.wheres.append(__.ID(self.end_query_variable).IN(*id_params))
        _id = __.ID(self.start_query_variable)

        if self.start_entity.id is not None:
            self.wheres.append(_id == self.start_entity.id)
        # else:
        #     wheres.append(_id)

        self.pypher.WHERE.CAND(*self.wheres)
        self.pypher.DELETE(self.relationship_query_variable)
        self.reset()

        return str(self.pypher), self.pypher.bound_params
Ejemplo n.º 10
0
    def _properties(self, entity, unique_only=False):
        props = {}
        mapper = get_mapper(entity)
        properties = mapper.entity_data(entity.data,
                                        unique_only=unique_only,
                                        data_type='graph')

        for field, value in properties.items():
            name = VM.get_next(entity, field)
            param = Param(name=name, value=value)

            self.pypher.bind_param(param)

            props[field] = param

        return props
Ejemplo n.º 11
0
    def test_can_bind_nonunique_mixed_primitive_and_param_object_to_pypher(self):
        n = 'some name'
        v = 'value {}'.format(random())
        v2 = v
        v = Param(n, v)
        p = Pypher()
        param = p.bind_param(v)
        param2 = p.bind_param(v2)

        str(p)
        params = p.bound_params

        self.assertNotEqual(id(v), id(param))
        self.assertIn(v.value, params.values())
        self.assertIn(n, params)
        self.assertEqual(1, len(params))
        self.assertEqual(param.name, param2.name)
Ejemplo n.º 12
0
    def test_will_allow_binding_of_pypher_instances_as_values(self):
        p = Pypher()
        p.bind_param(__.ID('x'), 'SOME_ID')

        str(p)
        params = p.bound_params

        self.assertIn('SOME_ID', params)
        self.assertEqual('id(x)', params['SOME_ID'])
        self.assertEqual(1, len(params))

        # do it in a Pypher string
        p = Pypher()
        val = 'some value {}'.format(random())
        name = 'name'
        p.MATCH.node('p', 'person', lastname=__.coalesce(name, val))

        cy = str(p)
        params = p.bound_params
        name = get_dict_key(params, 'name')
        val = get_dict_key(params, val)
        exp = 'MATCH (p:`person` {{`lastname`: coalesce(${name}, ${val})}})'.format(
            name=name, val=val)

        self.assertEqual(3, len(params))
        self.assertEqual(exp, cy)

        # manually use Param and pass it in
        p = Pypher()
        val = 'some value {}'.format(random())
        name = 'name'
        ln = Param(name, __.coalesce(name, val))
        p.MATCH.node('p', 'person', lastname=ln)

        cy = str(p)
        params = p.bound_params
        name = get_dict_key(params, 'name')
        val = get_dict_key(params, val)
        exp = 'MATCH (p:`person` {{`lastname`: coalesce(${name}, ${val})}})'.format(
            name=name, val=val)

        self.assertEqual(3, len(params))
        self.assertEqual(exp, cy)
Ejemplo n.º 13
0
    def get_by_ids(self, entity, ids):
        p = Pypher()
        p.MATCH

        if isinstance(entity, Relationship):
            var = 'rel'
            p.node().rel(var, labels=entity.labels).node()
        else:
            var = 'node'
            p.node(var, labels=entity.labels)

        id_params = []

        for i in ids:
            key = 'entity_id_{}'.format(i)
            id_params.append(Param(key, i))

        p.WHERE.COR(__.ID(var).IN(*id_params))
        p.RETURN(var)

        return str(p), p.bound_params
Ejemplo n.º 14
0
    def get_detailed_bundle_info_query(bundle_name, aspect=None):
        """
        :param bundle_name: retrieve specific information for this bundle.
        :param aspect: should be 'bundles', 'imports', 'Exports', 'packages','components','compilationUnit','Methods'.
        :return: the query for (general or specific) information about one bundle.
        """
        if aspect is None:
            return GenerateQuery.get_node_information_query(
                bundle_name, 'bundles')

        pypher_object = Pypher()
        if aspect == 'compilationUnit':
            pypher_object.Match.node('u', labels='bundles').relationship('f', labels="Pkg_fragment").node('n')\
                .relationship('c', labels="compiled_By").node("m")

        elif aspect == 'methods':
            pypher_object.Match.node('u', labels='bundles').relationship('pkg', labels="Pkg_fragment").node('k')\
                .relationship('kl', labels='compiled_By').node('n')\
                .relationship('r', labels='compiledUnits_topLevelType').node('nl')\
                .relationship('rl', labels='Methods_Contains').node('m')

        else:
            if aspect == 'packages':
                labels = 'uses_pkgs'
            elif aspect == 'components':
                labels = 'uses_components'
            else:
                labels = aspect

            pypher_object.Match.node('u', labels='bundles').relationship(
                'r', labels=labels).node('m')

        pypher_object.Match.node('u').where.u.__name__.CONTAINS(
            Param('per_param', bundle_name))

        # this can be changed according to req. if we need all info or just names of packages
        # query = str(self.pypherObject.RETURN('u.name', 'm.name'))
        pypher_object.RETURN('u.name', 'm.name')
        return GenerateQuery.reformat_query(pypher_object)
Ejemplo n.º 15
0
    def get_simple_query(self):
        extracted_intent = self.tracker.latest_message['intent']['name']

        if len(self.tracker.latest_message['entities']) > 0:
            extracted_value = self.tracker.latest_message['entities'][0][
                'value']
            extracted_entities = {
                self.tracker.latest_message['entities'][index]['entity']:
                self.tracker.latest_message['entities'][index]['value']
                for index in range(len(
                    self.tracker.latest_message['entities']))
            }
        else:
            extracted_entities = self.tracker.slots
        if len(extracted_entities) <= 0:
            return []

        if extracted_intent == 'showNodeInformation':
            if extracted_entities['node'] is None:
                return []
            self.pypher_object.Match.node('u').where.u.__name__.CONTAINS(
                Param('per_param', extracted_entities['node']))
            self.pypher_object.RETURN('u')

        elif extracted_intent == 'showAllNodes':
            self.pypher_object.Match.node(
                'u',
                labels=self.get_key_with_none_empty_value(extracted_entities))
            self.pypher_object.RETURN('u')

        elif extracted_intent == 'countAllNodes':
            self.pypher_object.Match.node(
                'u',
                labels=self.get_key_with_none_empty_value(extracted_entities))
            self.pypher_object.RETURN(__.count('u'))

        elif extracted_intent == 'showLargestCompilationUnit':

            if self.tracker.get_slot('Methods') is not None:

                self.pypher_object.Match.node('bundle', labels='bundles').relationship \
                    ('pkg', labels="Pkg_fragment").node('k').relationship \
                    ('kl', labels='compiled_By').node().relationship \
                    ('cp', labels="compiledUnits_topLevelType").node('n').relationship \
                    ('rl', 'Methods_Contains').node('mthd')

                self.pypher_object.RETURN('bundle.name', 'n.name',
                                          __.count('mthd'))
                self.pypher_object.OrderBy(__.count('mthd'))

            else:
                self.pypher_object.Match.node('bundle', labels='bundles').relationship \
                    ('pkg', labels="Pkg_fragment").node('k').relationship \
                    ('kl', labels='compiled_By').node('cmp')

                if self.tracker.get_slot('bundles') is not None:
                    self.pypher_object.WHERE(
                        __.bundle.__name__ == self.tracker.get_slot('bundles'))

                self.pypher_object.RETURN('bundle.name', 'cmp.name', 'cmp.Loc')
                self.pypher_object.OrderBy(__.cmp.__Loc__)

            self.pypher_object.Desc()
            self.pypher_object.Limit(1)

        elif extracted_intent == 'showDetailInfoBundles':

            bundle_name = None
            key_value = None
            # iterate through all entities
            for key, value in self.tracker.slots.items():

                # key_value is assigned according to relation names
                if key == 'bundles':
                    bundle_name = value
                elif key == 'imports' or key == 'Exports':
                    key_value = value
                elif key == 'packages':
                    key_value = 'uses_pkgs'
                elif key == 'components':
                    key_value = 'uses_components'
                elif key == 'compilationUnit':
                    key_value = 'compiled_By'
                elif key == 'Methods':
                    key_value = 'Methods_Contains'

            # this is relation name
            if key_value == 'compiled_By':

                self.pypher_object.Match.node('u', labels='bundles').relationship \
                    ('f', labels="Pkg_fragment").node('n').relationship \
                    ('c', labels="compiled_By").node("m")

            elif key_value == 'Methods_Contains':
                self.pypher_object.Match.node('u', labels='bundles').relationship \
                    ('pkg', labels="Pkg_fragment").node('k').relationship \
                    ('kl', labels='compiled_By').node('n').relationship \
                    ('r', labels='compiledUnits_topLevelType').node('nl').relationship \
                    ('rl', labels='Methods_Contains').node('m')

            else:
                self.pypher_object.Match.node('u', labels='bundles').relationship \
                    ('r', labels=key_value).node('m')

            self.pypher_object.WHERE(__.u.__name__ == bundle_name)

            # this can be changed according to req. if we need all info or just names of packages
            # query = str(self.pypherObject.RETURN('u.name', 'm.name'))
            self.pypher_object.RETURN('u.name', 'm.name')

        elif self.extracted_intents == 'showProjectInformation':
            self.pypher_object.Match.node('u')
            self.pypher_object.WHERE(
                __.u.__name__ == self.tracker.get_slot('bundles'))
            self.pypher_object.RETURN('u')

        else:
            if extracted_value is not None:
                self.pypher_object.Match.node(
                    'u', labels=extracted_entities).WHERE.u.property(
                        'name') == extracted_value
                self.pypher_object.RETURN('u')

        query = str(self.pypher_object)
        params = self.pypher_object.bound_params
        return [query, params, extracted_intent]
Ejemplo n.º 16
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
Ejemplo n.º 17
0
    def bind_param(self, value, name=None):
        if not isinstance(value, Param):
            name = VM.get_next(self.entity, name)
            param = Param(name, value)

        return super(Builder, self).bind_param(value=Param, name=name)