Exemple #1
0
    def get_annotation(self, cte):
        ancestor_condition = self.build_ancestor_condition(cte)

        return ArrayAgg(Case(When(condition=WhenQ(*ancestor_condition),
                                  then=cte.col.pk),
                             default=Value(None)),
                        output_field=CharField())
Exemple #2
0
    def get_annotation(self, cte):
        resource_condition = self.build_topic_condition(F('kind_id'), '!=')
        topic_condition = self.build_child_condition(cte)

        return Coalesce(
            Max(
                Case(
                    # when selected node is not a topic, use its sort_order
                    When(condition=WhenQ(*resource_condition),
                         then=F('sort_order')),
                    # when selected node is a topic, then find max of children
                    When(condition=WhenQ(*topic_condition),
                         then=cte.col.sort_order),
                    default=Value(None))),
            Value(1),
            output_field=IntegerField())
Exemple #3
0
    def get_annotation(self, cte):
        resource_condition = self.build_topic_condition(F('kind_id'), '!=')

        topic_condition = self.build_topic_condition(cte.col.kind_id, '!=')
        topic_condition += self.build_descendant_condition(cte)

        return Count(
            Case(
                # when selected node is not a topic, then count = 1
                When(condition=WhenQ(*resource_condition),
                     then=F('content_id')),
                # when it is a topic, then count descendants
                When(condition=WhenQ(*topic_condition),
                     then=cte.col.content_id),
                default=Value(None)),
            distinct=True)
Exemple #4
0
    def get_annotation(self, cte):
        topic_condition = self.build_topic_condition(F('kind_id'))
        topic_condition += self.build_descendant_condition(cte)
        topic_condition += self.build_coach_condition(cte.col.role_visibility)

        resource_condition = self.build_topic_condition(F('kind_id'), '!=')
        resource_condition += self.build_coach_condition(F('role_visibility'))

        return Count(
            Case(
                # when selected node is a coach topic, then count descendent content_id's
                When(condition=WhenQ(*topic_condition),
                     then=cte.col.content_id),
                # when selected node is not a topic, count its content_id
                When(condition=WhenQ(*resource_condition),
                     then=F('content_id')),
                default=Value(None)),
            distinct=True)
Exemple #5
0
    def get_annotation(self, cte):
        resource_condition = self.build_topic_condition(F('kind_id'), '!=')

        whens = [
            # when selected node is not a topic, just use its changed status
            When(condition=WhenQ(*resource_condition), then=F('changed')),
        ]

        if self.include_self:
            # when selected node is a topic and it's changed and including self, then return that
            whens.append(
                When(condition=WhenQ(*[F('changed')]), then=F('changed')))

        return Coalesce(
            Case(
                *whens,
                # fallback to aggregating descendant changed status when a unchanged topic
                default=BoolOr(cte.col.changed)),
            Value(False),
            output_field=BooleanField())
Exemple #6
0
 def get_annotation(self, cte=None):
     """
     @see MPTTModel.get_descendant_count()
     """
     return Max(
         Case(
             # when selected node is topic, use algorithm to get descendant count
             When(
                 condition=WhenQ(*self.build_topic_condition(F('kind_id'))),
                 then=(F('rght') - F('lft') - Value(1)) / Value(2)),
             # integer division floors the result in postgres
             default=Value(1)))
Exemple #7
0
    def build(self):
        """
        Creates special nested CTE since all other metadata works of nodes, and joining on multiple
        file records would produce incorrect result for resource sizes due to summing.
        """
        files_cte = FileMetadataCTE(self.query)
        files_cte.add_columns(('file_size', 'checksum'))

        resource_condition = BooleanComparison(F('kind_id'), '!=',
                                               Value(content_kinds.TOPIC))

        q = files_cte.join(self.query).annotate(resource_size=Sum(
            Case(
                # aggregate file_size when selected node is not a topic
                When(
                    condition=WhenQ(resource_condition),
                    then=Coalesce(files_cte.col.file_size, Value(0)),
                ),
                default=Value(0)),
            output_field=IntegerField()))

        return With(q.values(*set(self.columns)), name='resource_size_cte')