Beispiel #1
0
    def query(
        self,
        projects,
        environments=None,
        sort_by="date",
        limit=100,
        cursor=None,
        count_hits=False,
        paginator_options=None,
        search_filters=None,
        date_from=None,
        date_to=None,
    ):
        from sentry.models import Group, GroupStatus, GroupSubscription

        search_filters = search_filters if search_filters is not None else []

        # ensure projects are from same org
        if len({p.organization_id for p in projects}) != 1:
            raise RuntimeError("Cross organization search not supported")

        if paginator_options is None:
            paginator_options = {}

        group_queryset = Group.objects.filter(project__in=projects).exclude(
            status__in=[
                GroupStatus.PENDING_DELETION,
                GroupStatus.DELETION_IN_PROGRESS,
                GroupStatus.PENDING_MERGE,
            ])

        qs_builder_conditions = {
            "status":
            QCallbackCondition(lambda status: Q(status=status)),
            "bookmarked_by":
            QCallbackCondition(lambda user: Q(
                bookmark_set__project__in=projects, bookmark_set__user=user)),
            "assigned_to":
            QCallbackCondition(
                functools.partial(assigned_to_filter, projects=projects)),
            "unassigned":
            QCallbackCondition(
                functools.partial(unassigned_filter, projects=projects)),
            "subscribed_by":
            QCallbackCondition(
                lambda user: Q(id__in=GroupSubscription.objects.filter(
                    project__in=projects, user=user, is_active=True).
                               values_list("group"))),
            "active_at":
            ScalarCondition("active_at"),
        }

        group_queryset = QuerySetBuilder(qs_builder_conditions).build(
            group_queryset, search_filters)
        # filter out groups which are beyond the retention period
        retention = quotas.get_event_retention(
            organization=projects[0].organization)
        if retention:
            retention_window_start = timezone.now() - timedelta(days=retention)
        else:
            retention_window_start = None
        # TODO: This could be optimized when building querysets to identify
        # criteria that are logically impossible (e.g. if the upper bound
        # for last seen is before the retention window starts, no results
        # exist.)
        if retention_window_start:
            group_queryset = group_queryset.filter(
                last_seen__gte=retention_window_start)

        # TODO: It's possible `first_release` could be handled by Snuba.
        if environments is not None:
            environment_ids = [environment.id for environment in environments]
            group_queryset = group_queryset.filter(
                groupenvironment__environment_id__in=environment_ids)
            group_queryset = QuerySetBuilder({
                "first_release":
                QCallbackCondition(lambda version: Q(
                    # if environment(s) are selected, we just filter on the group
                    # environment's first_release attribute.
                    groupenvironment__first_release__organization_id=projects[
                        0].organization_id,
                    groupenvironment__first_release__version=version,
                    groupenvironment__environment_id__in=environment_ids,
                )),
                "first_seen":
                ScalarCondition(
                    "groupenvironment__first_seen",
                    {"groupenvironment__environment_id__in": environment_ids},
                ),
            }).build(group_queryset, search_filters)
        else:
            group_queryset = QuerySetBuilder({
                "first_release":
                QCallbackCondition(lambda release_version: Q(
                    # if no specific environments are supplied, we either choose any
                    # groups/issues whose first release matches the given release_version,
                    Q(first_release_id__in=Release.objects.filter(
                        version=release_version,
                        organization_id=projects[0].organization_id,
                    ))
                    |
                    # or we choose any groups whose first occurrence in any environment and the latest release at
                    # the time of the groups' first occurrence matches the given
                    # release_version
                    Q(id__in=GroupEnvironment.objects.filter(
                        first_release__version=release_version,
                        first_release__organization_id=projects[0].
                        organization_id,
                        environment__organization_id=projects[
                            0].organization_id,
                    ).values_list("group_id")))),
                "first_seen":
                ScalarCondition("first_seen"),
            }).build(group_queryset, search_filters)

        query_executor = PostgresSnubaQueryExecutor()

        return query_executor.query(
            projects,
            retention_window_start,
            group_queryset,
            environments,
            sort_by,
            limit,
            cursor,
            count_hits,
            paginator_options,
            search_filters,
            date_from,
            date_to,
        )
Beispiel #2
0
 def _get_query_executor(self, *args, **kwargs):
     return PostgresSnubaQueryExecutor()
Beispiel #3
0
 def _get_query_executor(self, *args: Any,
                         **kwargs: Any) -> AbstractQueryExecutor:
     return PostgresSnubaQueryExecutor()