~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/registry/model/distribution.py

[rs=buildbot-poller] automatic merge from stable. Revisions: 13503,
        13504 included.

Show diffs side-by-side

added added

removed removed

Lines of Context:
656
656
        """See `IBugTarget`."""
657
657
        return get_bug_tags("BugTask.distribution = %s" % sqlvalues(self))
658
658
 
659
 
    def getBranchTips(self, since=None):
 
659
    def getBranchTips(self, user=None, since=None):
660
660
        """See `IDistribution`."""
661
 
        query = """
662
 
            SELECT unique_name, last_scanned_id, SPBDS.name FROM Branch
663
 
            JOIN DistroSeries
664
 
                ON Branch.distroseries = DistroSeries.id
665
 
            LEFT OUTER JOIN SeriesSourcePackageBranch
666
 
                ON Branch.id = SeriesSourcePackageBranch.branch
667
 
            LEFT OUTER JOIN DistroSeries SPBDS
668
 
                -- (SPDBS stands for Source Package Branch Distro Series)
669
 
                ON SeriesSourcePackageBranch.distroseries = SPBDS.id
670
 
            WHERE DistroSeries.distribution = %s""" % sqlvalues(self.id)
671
 
 
 
661
        # This, ignoring privacy issues, is what we want.
 
662
        base_query = """
 
663
        SELECT Branch.unique_name,
 
664
               Branch.last_scanned_id,
 
665
               SPBDS.name AS distro_series_name,
 
666
               Branch.id,
 
667
               Branch.private,
 
668
               Branch.owner
 
669
        FROM Branch
 
670
        JOIN DistroSeries
 
671
            ON Branch.distroseries = DistroSeries.id
 
672
        LEFT OUTER JOIN SeriesSourcePackageBranch
 
673
            ON Branch.id = SeriesSourcePackageBranch.branch
 
674
        LEFT OUTER JOIN DistroSeries SPBDS
 
675
            -- (SPDBS stands for Source Package Branch Distro Series)
 
676
            ON SeriesSourcePackageBranch.distroseries = SPBDS.id
 
677
        WHERE DistroSeries.distribution = %s
 
678
        """ % sqlvalues(self.id)
672
679
        if since is not None:
673
 
            query += (
674
 
                ' AND branch.last_scanned > %s' % sqlvalues(since))
675
 
 
676
 
        query += ' ORDER BY unique_name, last_scanned_id;'
677
 
 
678
 
        data = Store.of(self).execute(query)
 
680
            # If "since" was provided, take into account.
 
681
            base_query += (
 
682
                '      AND branch.last_scanned > %s\n' % sqlvalues(since))
 
683
        if user is None:
 
684
            # Now we see just a touch of privacy concerns.
 
685
            # If the current user is anonymous, they cannot see any private
 
686
            # branches.
 
687
            base_query += ('      AND NOT Branch.private\n')
 
688
        # We want to order the results, in part for easier grouping at the
 
689
        # end.
 
690
        base_query += 'ORDER BY unique_name, last_scanned_id'
 
691
        if (user is None or
 
692
            user.inTeam(getUtility(ILaunchpadCelebrities).admin)):
 
693
            # Anonymous is already handled above; admins can see everything.
 
694
            # In both cases, we can just use the query as it already stands.
 
695
            query = base_query
 
696
        else:
 
697
            # Otherwise (an authenticated, non-admin user), we need to do some
 
698
            # more sophisticated privacy dances.  Note that the one thing we
 
699
            # are ignoring here is stacking.  See the discussion in comment 1
 
700
            # of https://bugs.launchpad.net/launchpad/+bug/812335 . Often, we
 
701
            # use unions for this kind of work.  The WITH statement can give
 
702
            # us a similar approach with more flexibility. In both cases,
 
703
            # we're essentially declaring that we have a better idea of a good
 
704
            # high-level query plan than Postgres will.
 
705
            query = """
 
706
            WITH principals AS (
 
707
                    SELECT team AS id
 
708
                        FROM TeamParticipation
 
709
                        WHERE TeamParticipation.person = %(user)s
 
710
                    UNION
 
711
                    SELECT %(user)s
 
712
                ), all_branches AS (
 
713
            %(base_query)s
 
714
                ), private_branches AS (
 
715
                    SELECT unique_name,
 
716
                           last_scanned_id,
 
717
                           distro_series_name,
 
718
                           id,
 
719
                           owner
 
720
                    FROM all_branches
 
721
                    WHERE private
 
722
                ), owned_branch_ids AS (
 
723
                    SELECT private_branches.id
 
724
                    FROM private_branches
 
725
                    JOIN principals ON private_branches.owner = principals.id
 
726
                ), subscribed_branch_ids AS (
 
727
                    SELECT private_branches.id
 
728
                    FROM private_branches
 
729
                    JOIN BranchSubscription
 
730
                        ON BranchSubscription.branch = private_branches.id
 
731
                    JOIN principals
 
732
                        ON BranchSubscription.person = principals.id
 
733
                )
 
734
            SELECT unique_name, last_scanned_id, distro_series_name
 
735
            FROM all_branches
 
736
            WHERE NOT private OR
 
737
                  id IN (SELECT id FROM owned_branch_ids) OR
 
738
                  id IN (SELECT id FROM subscribed_branch_ids)
 
739
            """ % dict(base_query=base_query, user=quote(user.id))
 
740
 
 
741
        data = Store.of(self).execute(query + ';')
679
742
 
680
743
        result = []
681
744
        # Group on location (unique_name) and revision (last_scanned_id).
683
746
            result.append(list(key))
684
747
            # Pull out all the official series names and append them as a list
685
748
            # to the end of the current record, removing Nones from the list.
686
 
            result[-1].append(filter(None, map(itemgetter(-1), group)))
 
749
            result[-1].append(filter(None, map(itemgetter(2), group)))
687
750
        return result
688
751
 
689
752
    def getMirrorByName(self, name):