Esempio n. 1
0
    def resolve__related_cases(self, info, args):
        if not case_cache_enabled():
            return []
        # Don't resolve related cases for cases
        if cls.label == "case":
            return []

        q = with_path_to(
            get_authorized_query(md.Case),
            {
                "type": cls.label,
                "id": self.id
            },
            info,
            name="related_cases",
        )
        qcls = __gql_object_classes["case"]
        try:
            return [
                qcls(**load_node(n, info, Node.fields_depend_on_columns))
                for n in q.all()
            ]
        except Exception as e:
            capp.logger.exception(e)
            raise
Esempio n. 2
0
 def resolve_related_cases(self, info, **args):
     if case_cache_enabled():
         return [
             instantiate_safely(TransactionResponseEntityRelatedCases, case)
             for case in self.related_cases
         ]
     else:
         return []
Esempio n. 3
0
    def resolve_related_cases(self, info, **args):
        if not case_cache_enabled():
            return []
        related_cases = {}
        for document in self.documents:
            entities = document.response_json.get("entities", [])
            for entity in entities:
                for related_case in entity.get("related_cases", []):
                    related_cases["id"] = {
                        "id": related_case.get("id", None),
                        "submitter_id": related_case.get("submitter_id", None),
                    }

        return [
            instantiate_safely(TransactionResponseEntityRelatedCases, case)
            for case in related_cases.values()
        ]
Esempio n. 4
0
def with_path_to(q, value, info, union=False, name='with_path_to'):
    """This will traverse any (any meaning any paths specified in the path
    generation heuristic which prunes some redundant/wandering paths)
    from the source entity to the given target type where it will
    apply a given query.

    This filter is a logical conjunction (*AND*) over subfilters.

    """

    if not isinstance(value, list):
        value = [value]

    union_qs = []

    for entry in value:
        entry = dict(entry)

        # Check target type
        dst_type = entry.pop('type', None)
        if not dst_type:
            raise RuntimeError(
                'Please specify a {{type: <type>}} in the {} filter.'.format(
                    name))

        # Prevent traversal to Node interface
        if q.entity() is Node:
            raise RuntimeError(
                '{} filter cannot be used with "node" interface'.format(name))

        # Define end of traversal filter
        def end_of_traversal_filter(q, entry=entry):
            if not entry:
                return q
            for key, val in entry.iteritems():
                if key == 'id':
                    q = q.ids(val)
                else:
                    q = q.filter(q.entity()._props.contains({key: val}))
            return q

        # Special case for traversing TO case
        if case_cache_enabled() and dst_type == 'case':
            # Rely on shortcut link to case, if it doesn't exist, then
            # this entity does not relate to any cases
            if hasattr(q.entity(), '_related_cases'):
                subq = q.subq_path('_related_cases', end_of_traversal_filter)
            else:
                subq = q.filter(sa.sql.false())

        # Special case for traversing FROM case
        elif case_cache_enabled() and q.entity().label == 'case':
            link = '_related_{}'.format(dst_type)
            q = q.limit(None)
            if hasattr(q.entity(), link):
                subq = q.subq_path(link, end_of_traversal_filter)
            else:
                subq = q.filter(sa.sql.false())

        # Otherwise do a full traversal
        else:
            subq = subq_paths(q, dst_type, end_of_traversal_filter)

        # Add the subq for this dst_type (multiplex on :param:`union`)
        if union:
            union_qs += [subq]
        else:
            q = subq

    # Construct final query (multiplex on :param:`union`)
    if union and union_qs:
        # If we are taking a union of the paths (i.e. OR) compile the union
        q = union_qs.pop(0)
        for union_q in union_qs:
            q = q.union(union_q)
    elif union and not union_qs:
        q = q.filter(sa.sql.false())

    return q
Esempio n. 5
0
def get_node_class_link_attrs(cls):
    attrs = {
        name: graphene.List(
            __name__ + '.' + link['type'].label,
            args=get_node_class_args(link['type']),
        )
        for name, link in cls._pg_edges.iteritems()
    }

    def resolve__related_cases(self, info, args):
        if not case_cache_enabled():
            return []
        # Don't resolve related cases for cases
        if cls.label == 'case':
            return []

        q = with_path_to(get_authorized_query(md.Case), {
            'type': cls.label,
            'id': self.id,
        },
                         info,
                         name='related_cases')
        qcls = __gql_object_classes['case']
        try:
            return [
                qcls(**load_node(n, info, Node.fields_depend_on_columns))
                for n in q.all()
            ]
        except Exception as e:
            capp.logger.exception(e)
            raise

    if case_cache_enabled():
        attrs['resolve__related_cases'] = resolve__related_cases
        attrs['_related_cases'] = graphene.List(
            'peregrine.resources.submission.graphql.node.case',
            args=get_node_class_args(md.Case))

    for link in cls._pg_edges:
        name = COUNT_NAME.format(link)
        attrs[name] = graphene.Field(graphene.Int,
                                     args=get_node_class_args(cls))

    # transaction logs that affected this node
    def resolve_transaction_logs_count(self, info, **args):
        args = dict(args, **{'entities': [self.id]})
        return transaction.resolve_transaction_log_count(self, info, **args)

    attrs['resolve__transaction_logs_count'] = resolve_transaction_logs_count
    attrs['_transaction_logs_count'] = graphene.Field(
        graphene.Int,
        args=transaction.get_transaction_log_args(),
    )

    def resolve_transaction_logs(self, info, **args):
        args = dict(args, **{'entities': [self.id]})
        return transaction.resolve_transaction_log(self, info, **args)

    attrs['resolve__transaction_logs'] = resolve_transaction_logs
    attrs['_transaction_logs'] = graphene.List(
        transaction.TransactionLog,
        args=transaction.get_transaction_log_args(),
    )

    _links_args = get_node_interface_args()
    _links_args.pop('of_type', None)
    attrs['_links'] = graphene.List(Node, args=_links_args)

    return attrs