110
115
# Avoid circular imports.
111
116
from lp.soyuz.model.publishing import SourcePackagePublishingHistory
114
SourcePackageRelease.id ==
115
SourcePackagePublishingHistory.sourcepackagereleaseID)
118
SPPH = SourcePackagePublishingHistory
119
SPR = SourcePackageRelease
121
return SPR.id == SPPH.sourcepackagereleaseID
118
124
class SourcePublicationTraits:
178
184
"""Obtain the version string for a publication record."""
179
185
return self.traits.getPackageRelease(pub).version
181
def load_releases(self, pubs):
182
"""Load the releases associated with a series of publications."""
184
self.traits.release_class, pubs,
185
[self.traits.release_reference_name])
187
187
def compare(self, pub1, pub2):
188
188
"""Compare publications by version.
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)
204
return sorted(publications, cmp=self.compare, reverse=True)
217
207
def find_live_source_versions(sorted_pubs):
335
325
has active arch-specific publications.
336
326
:return: A list of live versions.
328
# Avoid circular imports
329
from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
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))
339
[pub.binarypackagerelease for pub in arch_indep_pubs], ['buildID'])
340
load_related(SourcePackageRelease, bpbs, ['source_package_release_id'])
344
342
reprieved_pubs = [
346
344
for pub in arch_indep_pubs
577
575
# Avoid circular imports.
578
576
from lp.soyuz.model.publishing import BinaryPackagePublishingHistory
578
BPPH = BinaryPackagePublishingHistory
579
BPR = BinaryPackageRelease
580
581
bpph_location_clauses = [
581
BinaryPackagePublishingHistory.status ==
582
PackagePublishingStatus.PUBLISHED,
583
BinaryPackagePublishingHistory.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,
588
587
candidate_binary_names = Select(
589
BinaryPackageName.id,
591
BinaryPackageRelease.binarypackagenameID ==
592
BinaryPackageName.id,
593
BinaryPackagePublishingHistory.binarypackagereleaseID ==
594
BinaryPackageRelease.id,
595
bpph_location_clauses,
597
group_by=BinaryPackageName.id,
598
having=Count(BinaryPackagePublishingHistory.id) > 1)
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,
607
main_clauses.extend(bpph_location_clauses)
609
store = IStore(BinaryPackagePublishingHistory)
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.
617
(BinaryPackagePublishingHistory, BinaryPackageRelease),
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'])
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
672
SPPH = SourcePackagePublishingHistory
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,
695
681
def findSourcesForDomination(self, distroseries, pocket):
706
692
# Avoid circular imports.
707
693
from lp.soyuz.model.publishing import SourcePackagePublishingHistory
695
SPPH = SourcePackagePublishingHistory
696
SPR = SourcePackageRelease
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))
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(
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'])
733
721
def dominateSources(self, distroseries, pocket):
734
722
"""Perform domination on source package publications.
780
768
# Avoid circular imports.
781
769
from lp.soyuz.model.publishing import SourcePackagePublishingHistory
771
SPPH = SourcePackagePublishingHistory
772
SPR = SourcePackageRelease
783
774
query = IStore(SourcePackagePublishingHistory).find(
784
SourcePackagePublishingHistory,
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))
796
785
def dominateSourceVersions(self, distroseries, pocket, package_name,