~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/archivepublisher/domination.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-12-22 04:05:21 UTC
  • mfrom: (14260.2.7 bug-884649-branch-5)
  • Revision ID: launchpad@pqm.canonical.com-20111222040521-kgndkercui0muy9r
[r=julian-edwards][bug=884649] Use denormalized [BS]PPH.[bs]pn
 columns in dominator.

Show diffs side-by-side

added added

removed removed

Lines of Context:
98
98
apt_pkg.InitSystem()
99
99
 
100
100
 
101
 
def join_spr_spn():
102
 
    """Join condition: SourcePackageRelease/SourcePackageName."""
103
 
    return (
104
 
        SourcePackageName.id == SourcePackageRelease.sourcepackagenameID)
 
101
def join_spph_spn():
 
102
    """Join condition: SourcePackagePublishingHistory/SourcePackageName."""
 
103
    # Avoid circular imports.
 
104
    from lp.soyuz.model.publishing import SourcePackagePublishingHistory
 
105
 
 
106
    SPPH = SourcePackagePublishingHistory
 
107
    SPN = SourcePackageName
 
108
 
 
109
    return SPN.id == SPPH.sourcepackagenameID
105
110
 
106
111
 
107
112
def join_spph_spr():
110
115
    # Avoid circular imports.
111
116
    from lp.soyuz.model.publishing import SourcePackagePublishingHistory
112
117
 
113
 
    return (
114
 
        SourcePackageRelease.id ==
115
 
            SourcePackagePublishingHistory.sourcepackagereleaseID)
 
118
    SPPH = SourcePackagePublishingHistory
 
119
    SPR = SourcePackageRelease
 
120
 
 
121
    return SPR.id == SPPH.sourcepackagereleaseID
116
122
 
117
123
 
118
124
class SourcePublicationTraits:
127
133
    @staticmethod
128
134
    def getPackageName(spph):
129
135
        """Return the name of this publication's source package."""
130
 
        return spph.sourcepackagerelease.sourcepackagename.name
 
136
        return spph.sourcepackagename.name
131
137
 
132
138
    @staticmethod
133
139
    def getPackageRelease(spph):
147
153
    @staticmethod
148
154
    def getPackageName(bpph):
149
155
        """Return the name of this publication's binary package."""
150
 
        return bpph.binarypackagerelease.binarypackagename.name
 
156
        return bpph.binarypackagename.name
151
157
 
152
158
    @staticmethod
153
159
    def getPackageRelease(bpph):
178
184
        """Obtain the version string for a publication record."""
179
185
        return self.traits.getPackageRelease(pub).version
180
186
 
181
 
    def load_releases(self, pubs):
182
 
        """Load the releases associated with a series of publications."""
183
 
        return load_related(
184
 
            self.traits.release_class, pubs,
185
 
            [self.traits.release_reference_name])
186
 
 
187
187
    def compare(self, pub1, pub2):
188
188
        """Compare publications by version.
189
189
 
201
201
 
202
202
    def sortPublications(self, publications):
203
203
        """Sort publications from most to least current versions."""
204
 
        # Listify; we want to iterate this twice, which won't do for a
205
 
        # non-persistent sequence.
206
 
        publications = list(publications)
207
 
        # Batch-load associated package releases; we'll be needing them
208
 
        # to compare versions.
209
 
        self.load_releases(publications)
210
 
        # Now sort.  This is that second iteration.  An in-place sort
211
 
        # won't hurt the original, because we're working on a copy of
212
 
        # the original iterable.
213
 
        publications.sort(cmp=self.compare, reverse=True)
214
 
        return publications
 
204
        return sorted(publications, cmp=self.compare, reverse=True)
215
205
 
216
206
 
217
207
def find_live_source_versions(sorted_pubs):
335
325
        has active arch-specific publications.
336
326
    :return: A list of live versions.
337
327
    """
 
328
    # Avoid circular imports
 
329
    from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
 
330
 
338
331
    sorted_pubs = list(sorted_pubs)
339
332
    latest = sorted_pubs.pop(0)
340
333
    is_arch_specific = attrgetter('architecture_specific')
341
334
    arch_specific_pubs = list(ifilter(is_arch_specific, sorted_pubs))
342
335
    arch_indep_pubs = list(ifilterfalse(is_arch_specific, sorted_pubs))
343
336
 
 
337
    bpbs = load_related(
 
338
        BinaryPackageBuild,
 
339
        [pub.binarypackagerelease for pub in arch_indep_pubs], ['buildID'])
 
340
    load_related(SourcePackageRelease, bpbs, ['source_package_release_id'])
 
341
 
344
342
    reprieved_pubs = [
345
343
        pub
346
344
        for pub in arch_indep_pubs
577
575
        # Avoid circular imports.
578
576
        from lp.soyuz.model.publishing import BinaryPackagePublishingHistory
579
577
 
 
578
        BPPH = BinaryPackagePublishingHistory
 
579
        BPR = BinaryPackageRelease
 
580
 
580
581
        bpph_location_clauses = [
581
 
            BinaryPackagePublishingHistory.status ==
582
 
                PackagePublishingStatus.PUBLISHED,
583
 
            BinaryPackagePublishingHistory.distroarchseries ==
584
 
                distroarchseries,
585
 
            BinaryPackagePublishingHistory.archive == self.archive,
586
 
            BinaryPackagePublishingHistory.pocket == pocket,
 
582
            BPPH.status == PackagePublishingStatus.PUBLISHED,
 
583
            BPPH.distroarchseries == distroarchseries,
 
584
            BPPH.archive == self.archive,
 
585
            BPPH.pocket == pocket,
587
586
            ]
588
587
        candidate_binary_names = Select(
589
 
            BinaryPackageName.id,
590
 
            And(
591
 
                BinaryPackageRelease.binarypackagenameID ==
592
 
                    BinaryPackageName.id,
593
 
                BinaryPackagePublishingHistory.binarypackagereleaseID ==
594
 
                    BinaryPackageRelease.id,
595
 
                bpph_location_clauses,
596
 
            ),
597
 
            group_by=BinaryPackageName.id,
598
 
            having=Count(BinaryPackagePublishingHistory.id) > 1)
599
 
        main_clauses = [
600
 
            BinaryPackageRelease.id ==
601
 
                BinaryPackagePublishingHistory.binarypackagereleaseID,
602
 
            BinaryPackageRelease.binarypackagenameID.is_in(
603
 
                candidate_binary_names),
604
 
            BinaryPackageRelease.binpackageformat !=
605
 
                BinaryPackageFormat.DDEB,
 
588
            BPPH.binarypackagenameID, And(*bpph_location_clauses),
 
589
            group_by=BPPH.binarypackagenameID, having=(Count() > 1))
 
590
        main_clauses = bpph_location_clauses + [
 
591
            BPR.id == BPPH.binarypackagereleaseID,
 
592
            BPR.binarypackagenameID.is_in(candidate_binary_names),
 
593
            BPR.binpackageformat != BinaryPackageFormat.DDEB,
606
594
            ]
607
 
        main_clauses.extend(bpph_location_clauses)
608
 
 
609
 
        store = IStore(BinaryPackagePublishingHistory)
610
595
 
611
596
        # We're going to access the BPRs as well.  Since we make the
612
597
        # database look them up anyway, and since there won't be many
613
598
        # duplications among them, load them alongside the publications.
614
599
        # We'll also want their BinaryPackageNames, but adding those to
615
600
        # the join would complicate the query.
616
 
        query = store.find(
617
 
            (BinaryPackagePublishingHistory, BinaryPackageRelease),
618
 
            *main_clauses)
619
 
        return DecoratedResultSet(query, itemgetter(0))
 
601
        query = IStore(BPPH).find((BPPH, BPR), *main_clauses)
 
602
        bpphs = list(DecoratedResultSet(query, itemgetter(0)))
 
603
        load_related(BinaryPackageName, bpphs, ['binarypackagenameID'])
 
604
        return bpphs
620
605
 
621
606
    def dominateBinaries(self, distroseries, pocket):
622
607
        """Perform domination on binary package publications.
684
669
        # Avoid circular imports.
685
670
        from lp.soyuz.model.publishing import SourcePackagePublishingHistory
686
671
 
 
672
        SPPH = SourcePackagePublishingHistory
 
673
 
687
674
        return And(
688
 
            SourcePackagePublishingHistory.status ==
689
 
                PackagePublishingStatus.PUBLISHED,
690
 
            SourcePackagePublishingHistory.distroseries == distroseries,
691
 
            SourcePackagePublishingHistory.archive == self.archive,
692
 
            SourcePackagePublishingHistory.pocket == pocket,
 
675
            SPPH.status == PackagePublishingStatus.PUBLISHED,
 
676
            SPPH.distroseries == distroseries,
 
677
            SPPH.archive == self.archive,
 
678
            SPPH.pocket == pocket,
693
679
            )
694
680
 
695
681
    def findSourcesForDomination(self, distroseries, pocket):
706
692
        # Avoid circular imports.
707
693
        from lp.soyuz.model.publishing import SourcePackagePublishingHistory
708
694
 
 
695
        SPPH = SourcePackagePublishingHistory
 
696
        SPR = SourcePackageRelease
 
697
 
709
698
        spph_location_clauses = self._composeActiveSourcePubsCondition(
710
699
            distroseries, pocket)
711
 
        having_multiple_active_publications = (
712
 
            Count(SourcePackagePublishingHistory.id) > 1)
713
700
        candidate_source_names = Select(
714
 
            SourcePackageName.id,
715
 
            And(join_spph_spr(), join_spr_spn(), spph_location_clauses),
716
 
            group_by=SourcePackageName.id,
717
 
            having=having_multiple_active_publications)
 
701
            SPPH.sourcepackagenameID,
 
702
            And(join_spph_spr(), spph_location_clauses),
 
703
            group_by=SPPH.sourcepackagenameID,
 
704
            having=(Count() > 1))
718
705
 
719
706
        # We'll also access the SourcePackageReleases associated with
720
707
        # the publications we find.  Since they're in the join anyway,
722
709
        # Actually we'll also want the SourcePackageNames, but adding
723
710
        # those to the (outer) query would complicate it, and
724
711
        # potentially slow it down.
725
 
        query = IStore(SourcePackagePublishingHistory).find(
726
 
            (SourcePackagePublishingHistory, SourcePackageRelease),
 
712
        query = IStore(SPPH).find(
 
713
            (SPPH, SPR),
727
714
            join_spph_spr(),
728
 
            SourcePackageRelease.sourcepackagenameID.is_in(
729
 
                candidate_source_names),
 
715
            SPPH.sourcepackagenameID.is_in(candidate_source_names),
730
716
            spph_location_clauses)
731
 
        return DecoratedResultSet(query, itemgetter(0))
 
717
        spphs = DecoratedResultSet(query, itemgetter(0))
 
718
        load_related(SourcePackageName, spphs, ['sourcepackagenameID'])
 
719
        return spphs
732
720
 
733
721
    def dominateSources(self, distroseries, pocket):
734
722
        """Perform domination on source package publications.
771
759
        result = IStore(SourcePackageName).find(
772
760
            looking_for,
773
761
            join_spph_spr(),
774
 
            join_spr_spn(),
 
762
            join_spph_spn(),
775
763
            self._composeActiveSourcePubsCondition(distroseries, pocket))
776
764
        return result.group_by(SourcePackageName.name)
777
765
 
780
768
        # Avoid circular imports.
781
769
        from lp.soyuz.model.publishing import SourcePackagePublishingHistory
782
770
 
 
771
        SPPH = SourcePackagePublishingHistory
 
772
        SPR = SourcePackageRelease
 
773
 
783
774
        query = IStore(SourcePackagePublishingHistory).find(
784
 
            SourcePackagePublishingHistory,
 
775
            SPPH,
785
776
            join_spph_spr(),
786
 
            join_spr_spn(),
 
777
            join_spph_spn(),
787
778
            SourcePackageName.name == package_name,
788
779
            self._composeActiveSourcePubsCondition(distroseries, pocket))
789
780
        # Sort by descending version (SPR.version has type debversion in
790
781
        # the database, so this should be a real proper comparison) so
791
782
        # that _sortPackage will have slightly less work to do later.
792
 
        return query.order_by(
793
 
            Desc(SourcePackageRelease.version),
794
 
            Desc(SourcePackagePublishingHistory.datecreated))
 
783
        return query.order_by(Desc(SPR.version), Desc(SPPH.datecreated))
795
784
 
796
785
    def dominateSourceVersions(self, distroseries, pocket, package_name,
797
786
                               live_versions):