Merge lp:~wgrant/launchpad/flatten-bfj-3.5-more-query into lp:launchpad

Proposed by William Grant
Status: Merged
Approved by: William Grant
Approved revision: no longer in the source branch.
Merged at revision: 16473
Proposed branch: lp:~wgrant/launchpad/flatten-bfj-3.5-more-query
Merge into: lp:launchpad
Prerequisite: lp:~wgrant/launchpad/flatten-bfj-3-query
Diff against target: 817 lines (+126/-256)
18 files modified
lib/lp/buildmaster/configure.zcml (+0/-6)
lib/lp/buildmaster/interfaces/buildfarmjob.py (+9/-0)
lib/lp/buildmaster/interfaces/packagebuild.py (+0/-17)
lib/lp/buildmaster/model/buildfarmjob.py (+35/-18)
lib/lp/buildmaster/model/packagebuild.py (+0/-43)
lib/lp/buildmaster/tests/test_buildfarmjob.py (+27/-2)
lib/lp/buildmaster/tests/test_packagebuild.py (+0/-42)
lib/lp/code/model/sourcepackagerecipebuild.py (+9/-21)
lib/lp/soyuz/browser/tests/test_queue.py (+1/-1)
lib/lp/soyuz/interfaces/publishing.py (+2/-5)
lib/lp/soyuz/model/archive.py (+4/-4)
lib/lp/soyuz/model/binarypackagebuild.py (+17/-44)
lib/lp/soyuz/model/publishing.py (+4/-11)
lib/lp/soyuz/model/queue.py (+0/-1)
lib/lp/soyuz/scripts/retrydepwait.py (+9/-15)
lib/lp/soyuz/tests/test_hasbuildrecords.py (+3/-14)
lib/lp/soyuz/tests/test_packageupload.py (+1/-1)
lib/lp/translations/model/translationtemplatesbuild.py (+5/-11)
To merge this branch: bzr merge lp:~wgrant/launchpad/flatten-bfj-3.5-more-query
Reviewer Review Type Date Requested Status
Steve Kowalik (community) code Approve
Review via email: mp+145819@code.launchpad.net

Commit message

Switch the remaining IBuildFarmJob queries to use the new denormalised columns.

Description of the change

The build farm job schema is being reworked to improve performance. Columns from PackageBuild and BuildFarmJob are being merged into tables that previously delegated to them. The PackageBuild table will end up dying entirely, but BuildFarmJob will remain, a shadow of its former self, to answer questions about Archive:+builds and Builder:+history. Additionally, BinaryPackageBuild is growing new distribution, distroseries, sourcepackagename and is_distro_archive columns to make searches even faster.

This branch adjusts the rest of the BFJ/PB queries to to use just BPB/SPRB/TTB where possible, otherwise BFJ (for getBuildsByArchive and getBuildsByBuilder).

To post a comment you must log in.
Revision history for this message
Steve Kowalik (stevenk) wrote :

115 + store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)

I know this code is copied, but IStore? Please?

129 + if status is None or status in unfinished_states:
130 + result_set.order_by(
131 + Desc(BuildFarmJob.date_created), BuildFarmJob.id)
132 + else:
133 + result_set.order_by(
134 + Desc(BuildFarmJob.date_finished), BuildFarmJob.id)

Personally, I'd prefer setting an order array, and then returning store.find().order_by(*order), but eh.

703 # Until we have different IBuildFarmJob types implemented, we
704 # can only test this by creating a lone PackageBuild of a
705 # different type.

Now hysterical raisins, so delete it.

716 # different type.

A copy of the same comment from above?

749 - buildfarmjob_ids = [buildfarmjob.id for buildfarmjob in buildfarmjobs]

Haha, even above the docstring. Good work killing it.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/buildmaster/configure.zcml'
2--- lib/lp/buildmaster/configure.zcml 2013-01-07 05:25:16 +0000
3+++ lib/lp/buildmaster/configure.zcml 2013-02-04 04:13:30 +0000
4@@ -76,12 +76,6 @@
5 <allow
6 interface="lp.buildmaster.interfaces.packagebuild.IPackageBuildSource" />
7 </securedutility>
8- <securedutility
9- class="lp.buildmaster.model.packagebuild.PackageBuildSet"
10- provides="lp.buildmaster.interfaces.packagebuild.IPackageBuildSet">
11- <allow
12- interface="lp.buildmaster.interfaces.packagebuild.IPackageBuildSet" />
13- </securedutility>
14
15 <!-- BuildQueue -->
16 <class
17
18=== modified file 'lib/lp/buildmaster/interfaces/buildfarmjob.py'
19--- lib/lp/buildmaster/interfaces/buildfarmjob.py 2013-02-04 04:13:30 +0000
20+++ lib/lp/buildmaster/interfaces/buildfarmjob.py 2013-02-04 04:13:30 +0000
21@@ -374,3 +374,12 @@
22 that should be included.
23 :return: a `ResultSet` representing the requested builds.
24 """
25+
26+ def getBuildsForArchive(archive, status=None):
27+ """Return `IBuildFarmJob` records targeted to a given `IArchive`.
28+
29+ :param archive: The archive for which builds will be returned.
30+ :param status: If status is provided, only builders with that
31+ status will be returned.
32+ :return: a `ResultSet` representing the requested `IBuildFarmJobs`.
33+ """
34
35=== modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
36--- lib/lp/buildmaster/interfaces/packagebuild.py 2013-02-04 04:13:30 +0000
37+++ lib/lp/buildmaster/interfaces/packagebuild.py 2013-02-04 04:13:30 +0000
38@@ -6,7 +6,6 @@
39 __all__ = [
40 'IPackageBuild',
41 'IPackageBuildSource',
42- 'IPackageBuildSet',
43 ]
44
45
46@@ -23,7 +22,6 @@
47 )
48
49 from lp import _
50-from lp.buildmaster.enums import BuildStatus
51 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob
52 from lp.registry.interfaces.distribution import IDistribution
53 from lp.registry.interfaces.distroseries import IDistroSeries
54@@ -136,18 +134,3 @@
55 :param archive: An `IArchive`.
56 :param pocket: An item of `PackagePublishingPocket`.
57 """
58-
59-
60-class IPackageBuildSet(Interface):
61- """A utility representing a set of package builds."""
62-
63- def getBuildsForArchive(archive, status=None, pocket=None):
64- """Return package build records targeted to a given IArchive.
65-
66- :param archive: The archive for which builds will be returned.
67- :param status: If status is provided, only builders with that
68- status will be returned.
69- :param pocket: If pocket is provided only builds for that pocket
70- will be returned.
71- :return: a `ResultSet` representing the requested package builds.
72- """
73
74=== modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
75--- lib/lp/buildmaster/model/buildfarmjob.py 2013-02-04 04:13:30 +0000
76+++ lib/lp/buildmaster/model/buildfarmjob.py 2013-02-04 04:13:30 +0000
77@@ -44,11 +44,6 @@
78 )
79 from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
80 from lp.services.database.enumcol import DBEnum
81-from lp.services.database.interfaces import (
82- DEFAULT_FLAVOR,
83- IStoreSelector,
84- MAIN_STORE,
85- )
86 from lp.services.database.lpstorm import (
87 IMasterStore,
88 IStore,
89@@ -73,17 +68,13 @@
90 @classmethod
91 def getByJob(cls, job):
92 """See `IBuildFarmJobOld`."""
93- store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
94- return store.find(cls, cls.job == job).one()
95+ return IStore(cls).find(cls, cls.job == job).one()
96
97 @classmethod
98 def getByJobs(cls, jobs):
99- """See `IBuildFarmJobOld`.
100- """
101- store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
102+ """See `IBuildFarmJobOld`."""
103 job_ids = [job.id for job in jobs]
104- return store.find(
105- cls, cls.job_id.is_in(job_ids))
106+ return IStore(cls).find(cls, cls.job_id.is_in(job_ids))
107
108 def score(self):
109 """See `IBuildFarmJobOld`."""
110@@ -367,13 +358,12 @@
111 def getBuildsForBuilder(self, builder_id, status=None, user=None):
112 """See `IBuildFarmJobSet`."""
113 # Imported here to avoid circular imports.
114- from lp.buildmaster.model.packagebuild import PackageBuild
115 from lp.soyuz.model.archive import (
116 Archive, get_archive_privacy_filter)
117
118 clauses = [
119 BuildFarmJob.builder == builder_id,
120- Or(PackageBuild.id == None, get_archive_privacy_filter(user))]
121+ Or(Archive.id == None, get_archive_privacy_filter(user))]
122 if status is not None:
123 clauses.append(BuildFarmJob.status == status)
124
125@@ -383,12 +373,39 @@
126 # related package build - hence the left join.
127 origin = [
128 BuildFarmJob,
129- LeftJoin(
130- PackageBuild,
131- PackageBuild.build_farm_job == BuildFarmJob.id),
132- LeftJoin(Archive, Archive.id == PackageBuild.archive_id),
133+ LeftJoin(Archive, Archive.id == BuildFarmJob.archive_id),
134 ]
135
136 return IStore(BuildFarmJob).using(*origin).find(
137 BuildFarmJob, *clauses).order_by(
138 Desc(BuildFarmJob.date_finished), BuildFarmJob.id)
139+
140+ def getBuildsForArchive(self, archive, status=None):
141+ """See `IBuildFarmJobSet`."""
142+
143+ extra_exprs = []
144+
145+ if status is not None:
146+ extra_exprs.append(BuildFarmJob.status == status)
147+
148+ result_set = IStore(BuildFarmJob).find(
149+ BuildFarmJob, BuildFarmJob.archive == archive, *extra_exprs)
150+
151+ # When we have a set of builds that may include pending or
152+ # superseded builds, we order by -date_created (as we won't
153+ # always have a date_finished). Otherwise we can order by
154+ # -date_finished.
155+ unfinished_states = [
156+ BuildStatus.NEEDSBUILD,
157+ BuildStatus.BUILDING,
158+ BuildStatus.UPLOADING,
159+ BuildStatus.SUPERSEDED,
160+ ]
161+ if status is None or status in unfinished_states:
162+ result_set.order_by(
163+ Desc(BuildFarmJob.date_created), BuildFarmJob.id)
164+ else:
165+ result_set.order_by(
166+ Desc(BuildFarmJob.date_finished), BuildFarmJob.id)
167+
168+ return result_set
169
170=== modified file 'lib/lp/buildmaster/model/packagebuild.py'
171--- lib/lp/buildmaster/model/packagebuild.py 2013-02-04 04:13:30 +0000
172+++ lib/lp/buildmaster/model/packagebuild.py 2013-02-04 04:13:30 +0000
173@@ -5,7 +5,6 @@
174 __all__ = [
175 'PackageBuild',
176 'PackageBuildMixin',
177- 'PackageBuildSet',
178 ]
179
180
181@@ -26,10 +25,8 @@
182 )
183
184 from lp.buildmaster.enums import BuildStatus
185-from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
186 from lp.buildmaster.interfaces.packagebuild import (
187 IPackageBuild,
188- IPackageBuildSet,
189 IPackageBuildSource,
190 )
191 from lp.buildmaster.model.buildfarmjob import (
192@@ -228,43 +225,3 @@
193 virtualized=specific_job.virtualized)
194 Store.of(self).add(queue_entry)
195 return queue_entry
196-
197-
198-class PackageBuildSet:
199- implements(IPackageBuildSet)
200-
201- def getBuildsForArchive(self, archive, status=None, pocket=None):
202- """See `IPackageBuildSet`."""
203-
204- extra_exprs = []
205-
206- if status is not None:
207- extra_exprs.append(BuildFarmJob.status == status)
208-
209- if pocket:
210- extra_exprs.append(PackageBuild.pocket == pocket)
211-
212- store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
213- result_set = store.find(PackageBuild,
214- PackageBuild.archive == archive,
215- PackageBuild.build_farm_job == BuildFarmJob.id,
216- *extra_exprs)
217-
218- # When we have a set of builds that may include pending or
219- # superseded builds, we order by -date_created (as we won't
220- # always have a date_finished). Otherwise we can order by
221- # -date_finished.
222- unfinished_states = [
223- BuildStatus.NEEDSBUILD,
224- BuildStatus.BUILDING,
225- BuildStatus.UPLOADING,
226- BuildStatus.SUPERSEDED,
227- ]
228- if status is None or status in unfinished_states:
229- result_set.order_by(
230- Desc(BuildFarmJob.date_created), BuildFarmJob.id)
231- else:
232- result_set.order_by(
233- Desc(BuildFarmJob.date_finished), BuildFarmJob.id)
234-
235- return result_set
236
237=== modified file 'lib/lp/buildmaster/tests/test_buildfarmjob.py'
238--- lib/lp/buildmaster/tests/test_buildfarmjob.py 2013-01-23 10:16:18 +0000
239+++ lib/lp/buildmaster/tests/test_buildfarmjob.py 2013-02-04 04:13:30 +0000
240@@ -52,7 +52,7 @@
241 def makeBuildFarmJob(self, builder=None,
242 job_type=BuildFarmJobType.PACKAGEBUILD,
243 status=BuildStatus.NEEDSBUILD,
244- date_finished=None):
245+ date_finished=None, archive=None):
246 """A factory method for creating PackageBuilds.
247
248 This is not included in the launchpad test factory because
249@@ -61,7 +61,7 @@
250 or eventually a SPRecipeBuild).
251 """
252 build_farm_job = getUtility(IBuildFarmJobSource).new(
253- job_type=job_type, status=status)
254+ job_type=job_type, status=status, archive=archive)
255 removeSecurityProxy(build_farm_job).builder = builder
256 removeSecurityProxy(build_farm_job).date_started = date_finished
257 removeSecurityProxy(build_farm_job).date_finished = date_finished
258@@ -327,3 +327,28 @@
259
260 result = self.build_farm_job_set.getBuildsForBuilder(self.builder)
261 self.assertEqual([build_2, build_1, build_3], list(result))
262+
263+ def makeBuildsForArchive(self):
264+ archive = self.factory.makeArchive()
265+ builds = [
266+ self.makeBuildFarmJob(archive=archive),
267+ self.makeBuildFarmJob(
268+ archive=archive, status=BuildStatus.BUILDING),
269+ ]
270+ return (archive, builds)
271+
272+ def test_getBuildsForArchive_all(self):
273+ # The default call without arguments returns all builds for the
274+ # archive.
275+ archive, builds = self.makeBuildsForArchive()
276+ self.assertContentEqual(
277+ builds, self.build_farm_job_set.getBuildsForArchive(archive))
278+
279+ def test_getBuildsForArchive_by_status(self):
280+ # If the status arg is used, the results will be filtered by
281+ # status.
282+ archive, builds = self.makeBuildsForArchive()
283+ self.assertContentEqual(
284+ builds[1:],
285+ self.build_farm_job_set.getBuildsForArchive(
286+ archive, status=BuildStatus.BUILDING))
287
288=== modified file 'lib/lp/buildmaster/tests/test_packagebuild.py'
289--- lib/lp/buildmaster/tests/test_packagebuild.py 2013-01-31 06:58:23 +0000
290+++ lib/lp/buildmaster/tests/test_packagebuild.py 2013-02-04 04:13:30 +0000
291@@ -19,7 +19,6 @@
292 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
293 from lp.buildmaster.interfaces.packagebuild import (
294 IPackageBuild,
295- IPackageBuildSet,
296 IPackageBuildSource,
297 )
298 from lp.buildmaster.model.buildfarmjob import BuildFarmJob
299@@ -203,44 +202,3 @@
300 login('admin@canonical.com')
301 self.assertTrue(checkPermission('launchpad.View', self.package_build))
302 self.assertTrue(checkPermission('launchpad.Edit', self.package_build))
303-
304-
305-class TestPackageBuildSet(TestPackageBuildBase):
306-
307- layer = LaunchpadFunctionalLayer
308-
309- def setUp(self):
310- super(TestPackageBuildSet, self).setUp()
311- person = self.factory.makePerson()
312- self.archive = self.factory.makeArchive(owner=person)
313- self.package_builds = []
314- self.package_builds.append(
315- self.makePackageBuild(archive=self.archive,
316- pocket=PackagePublishingPocket.UPDATES))
317- self.package_builds.append(
318- self.makePackageBuild(archive=self.archive,
319- status=BuildStatus.BUILDING))
320- self.package_build_set = getUtility(IPackageBuildSet)
321-
322- def test_getBuildsForArchive_all(self):
323- # The default call without arguments returns all builds for the
324- # archive.
325- self.assertContentEqual(
326- self.package_builds, self.package_build_set.getBuildsForArchive(
327- self.archive))
328-
329- def test_getBuildsForArchive_by_status(self):
330- # If the status arg is used, the results will be filtered by
331- # status.
332- self.assertContentEqual(
333- self.package_builds[1:],
334- self.package_build_set.getBuildsForArchive(
335- self.archive, status=BuildStatus.BUILDING))
336-
337- def test_getBuildsForArchive_by_pocket(self):
338- # If the pocket arg is used, the results will be filtered by
339- # pocket.
340- self.assertContentEqual(
341- self.package_builds[:1],
342- self.package_build_set.getBuildsForArchive(
343- self.archive, pocket=PackagePublishingPocket.UPDATES))
344
345=== modified file 'lib/lp/code/model/sourcepackagerecipebuild.py'
346--- lib/lp/code/model/sourcepackagerecipebuild.py 2013-02-04 04:13:30 +0000
347+++ lib/lp/code/model/sourcepackagerecipebuild.py 2013-02-04 04:13:30 +0000
348@@ -328,26 +328,18 @@
349 @classmethod
350 def getByBuildFarmJob(cls, build_farm_job):
351 """See `ISpecificBuildFarmJobSource`."""
352- return Store.of(build_farm_job).find(cls,
353- cls.package_build_id == PackageBuild.id,
354- PackageBuild.build_farm_job_id == build_farm_job.id).one()
355+ return Store.of(build_farm_job).find(
356+ cls, build_farm_job_id=build_farm_job.id).one()
357
358 @classmethod
359 def preloadBuildsData(cls, builds):
360 # Circular imports.
361 from lp.code.model.sourcepackagerecipe import SourcePackageRecipe
362 from lp.services.librarian.model import LibraryFileAlias
363- from lp.buildmaster.model.buildfarmjob import BuildFarmJob
364- package_builds = load_related(
365- PackageBuild, builds, ['package_build_id'])
366- build_farm_jobs = load_related(
367- BuildFarmJob, [build.package_build for build in builds],
368- ['build_farm_job_id'])
369- load_related(LibraryFileAlias, build_farm_jobs, ['log_id'])
370- archives = load_related(Archive, package_builds, ['archive_id'])
371+ load_related(LibraryFileAlias, builds, ['_new_log_id'])
372+ archives = load_related(Archive, builds, ['_new_archive_id'])
373 load_related(Person, archives, ['ownerID'])
374- sprs = load_related(
375- SourcePackageRecipe, builds, ['recipe_id'])
376+ sprs = load_related(SourcePackageRecipe, builds, ['recipe_id'])
377 SourcePackageRecipe.preLoadDataForSourcePackageRecipes(sprs)
378
379 @classmethod
380@@ -355,14 +347,10 @@
381 """See `ISpecificBuildFarmJobSource`."""
382 if len(build_farm_jobs) == 0:
383 return EmptyResultSet()
384- build_farm_job_ids = [
385- build_farm_job.id for build_farm_job in build_farm_jobs]
386-
387- resultset = Store.of(build_farm_jobs[0]).find(cls,
388- cls.package_build_id == PackageBuild.id,
389- PackageBuild.build_farm_job_id.is_in(build_farm_job_ids))
390- return DecoratedResultSet(
391- resultset, pre_iter_hook=cls.preloadBuildsData)
392+ rows = Store.of(build_farm_jobs[0]).find(
393+ cls, cls.build_farm_job_id.is_in(
394+ bfj.id for bfj in build_farm_jobs))
395+ return DecoratedResultSet(rows, pre_iter_hook=cls.preloadBuildsData)
396
397 @classmethod
398 def getRecentBuilds(cls, requester, recipe, distroseries, _now=None):
399
400=== modified file 'lib/lp/soyuz/browser/tests/test_queue.py'
401--- lib/lp/soyuz/browser/tests/test_queue.py 2013-01-08 05:45:26 +0000
402+++ lib/lp/soyuz/browser/tests/test_queue.py 2013-02-04 04:13:30 +0000
403@@ -398,7 +398,7 @@
404 with StormStatementRecorder() as recorder:
405 view = self.makeView(distroseries, queue_admin)
406 view()
407- self.assertThat(recorder, HasQueryCount(Equals(55)))
408+ self.assertThat(recorder, HasQueryCount(Equals(54)))
409
410
411 class TestCompletePackageUpload(TestCaseWithFactory):
412
413=== modified file 'lib/lp/soyuz/interfaces/publishing.py'
414--- lib/lp/soyuz/interfaces/publishing.py 2013-01-07 02:40:55 +0000
415+++ lib/lp/soyuz/interfaces/publishing.py 2013-02-04 04:13:30 +0000
416@@ -1091,8 +1091,7 @@
417 binary publications.
418 """
419
420- def getBuildsForSourceIds(source_ids, archive=None, build_states=None,
421- need_build_farm_job=False):
422+ def getBuildsForSourceIds(source_ids, archive=None, build_states=None):
423 """Return all builds related with each given source publication.
424
425 The returned ResultSet contains entries with the wanted `Build`s
426@@ -1120,10 +1119,8 @@
427 :type build_states: ``list`` or None
428 :param need_build_farm_job: whether to include the `PackageBuild`
429 and `BuildFarmJob` in the result.
430- :type need_build_farm_job: bool
431 :return: a storm ResultSet containing tuples as
432- (`SourcePackagePublishingHistory`, `Build`, `DistroArchSeries`,
433- [`PackageBuild`, `BuildFarmJob` if need_build_farm_job])
434+ (`SourcePackagePublishingHistory`, `Build`, `DistroArchSeries`)
435 :rtype: `storm.store.ResultSet`.
436 """
437
438
439=== modified file 'lib/lp/soyuz/model/archive.py'
440--- lib/lp/soyuz/model/archive.py 2013-02-04 04:13:30 +0000
441+++ lib/lp/soyuz/model/archive.py 2013-02-04 04:13:30 +0000
442@@ -54,7 +54,7 @@
443 re_issource,
444 )
445 from lp.buildmaster.enums import BuildStatus
446-from lp.buildmaster.interfaces.packagebuild import IPackageBuildSet
447+from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSet
448 from lp.registry.enums import (
449 INCLUSIVE_TEAM_POLICY,
450 PersonVisibility,
451@@ -486,12 +486,12 @@
452 return getUtility(IBinaryPackageBuildSet).getBuildsForArchive(
453 self, build_state, name, pocket, arch_tag)
454 else:
455- if arch_tag is not None or name is not None:
456+ if arch_tag is not None or name is not None or pocket is not None:
457 raise IncompatibleArguments(
458 "The 'arch_tag' and 'name' parameters can be used only "
459 "with binary_only=True.")
460- return getUtility(IPackageBuildSet).getBuildsForArchive(
461- self, status=build_state, pocket=pocket)
462+ return getUtility(IBuildFarmJobSet).getBuildsForArchive(
463+ self, status=build_state)
464
465 def getPublishedSources(self, name=None, version=None, status=None,
466 distroseries=None, pocket=None,
467
468=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
469--- lib/lp/soyuz/model/binarypackagebuild.py 2013-02-04 04:13:30 +0000
470+++ lib/lp/soyuz/model/binarypackagebuild.py 2013-02-04 04:13:30 +0000
471@@ -47,10 +47,7 @@
472 from lp.buildmaster.model.builder import Builder
473 from lp.buildmaster.model.buildfarmjob import BuildFarmJob
474 from lp.buildmaster.model.buildqueue import BuildQueue
475-from lp.buildmaster.model.packagebuild import (
476- PackageBuild,
477- PackageBuildMixin,
478- )
479+from lp.buildmaster.model.packagebuild import PackageBuildMixin
480 from lp.registry.interfaces.pocket import PackagePublishingPocket
481 from lp.services.config import config
482 from lp.services.database.bulk import load_related
483@@ -913,15 +910,8 @@
484
485 def getByBuildFarmJob(self, build_farm_job):
486 """See `ISpecificBuildFarmJobSource`."""
487- find_spec = (BinaryPackageBuild, PackageBuild, BuildFarmJob)
488- resulting_tuple = Store.of(build_farm_job).find(
489- find_spec,
490- BinaryPackageBuild.package_build == PackageBuild.id,
491- PackageBuild.build_farm_job == BuildFarmJob.id,
492- BuildFarmJob.id == build_farm_job.id).one()
493- if resulting_tuple is None:
494- return None
495- return resulting_tuple[0]
496+ return Store.of(build_farm_job).find(
497+ BinaryPackageBuild, build_farm_job_id=build_farm_job.id).one()
498
499 def preloadBuildsData(self, builds):
500 # Circular imports.
501@@ -933,9 +923,7 @@
502 self._prefetchBuildData(builds)
503 distro_arch_series = load_related(
504 DistroArchSeries, builds, ['distro_arch_series_id'])
505- package_builds = load_related(
506- PackageBuild, builds, ['package_build_id'])
507- archives = load_related(Archive, package_builds, ['archive_id'])
508+ archives = load_related(Archive, builds, ['_new_archive_id'])
509 load_related(Person, archives, ['ownerID'])
510 distroseries = load_related(
511 DistroSeries, distro_arch_series, ['distroseriesID'])
512@@ -946,17 +934,11 @@
513 """See `ISpecificBuildFarmJobSource`."""
514 if len(build_farm_jobs) == 0:
515 return EmptyResultSet()
516- clause_tables = (BinaryPackageBuild, PackageBuild, BuildFarmJob)
517- build_farm_job_ids = [
518- build_farm_job.id for build_farm_job in build_farm_jobs]
519-
520- resultset = Store.of(build_farm_jobs[0]).using(*clause_tables).find(
521+ rows = Store.of(build_farm_jobs[0]).find(
522 BinaryPackageBuild,
523- BinaryPackageBuild.package_build == PackageBuild.id,
524- PackageBuild.build_farm_job == BuildFarmJob.id,
525- BuildFarmJob.id.is_in(build_farm_job_ids))
526- return DecoratedResultSet(
527- resultset, pre_iter_hook=self.preloadBuildsData)
528+ BinaryPackageBuild.build_farm_job_id.is_in(
529+ bfj.id for bfj in build_farm_jobs))
530+ return DecoratedResultSet(rows, pre_iter_hook=self.preloadBuildsData)
531
532 def handleOptionalParamsForBuildQueries(
533 self, clauses, origin, status=None, name=None, pocket=None,
534@@ -1163,10 +1145,8 @@
535
536 query = """
537 source_package_release IN %s AND
538- package_build = packagebuild.id AND
539 archive.id = binarypackagebuild.archive AND
540- archive.purpose != %s AND
541- packagebuild.build_farm_job = buildfarmjob.id
542+ archive.purpose != %s
543 """ % sqlvalues(sourcepackagerelease_ids, ArchivePurpose.PPA)
544
545 if buildstate is not None:
546@@ -1174,12 +1154,12 @@
547 "AND binarypackagebuild.status = %s" % sqlvalues(buildstate))
548
549 resultset = IStore(BinaryPackageBuild).using(
550- BinaryPackageBuild, PackageBuild, BuildFarmJob, Archive).find(
551- (BinaryPackageBuild, PackageBuild, BuildFarmJob),
552+ BinaryPackageBuild, Archive).find(
553+ BinaryPackageBuild,
554 SQL(query))
555 resultset.order_by(
556 Desc(BinaryPackageBuild._new_date_created), BinaryPackageBuild.id)
557- return DecoratedResultSet(resultset, operator.itemgetter(0))
558+ return resultset
559
560 def getStatusSummaryForBuilds(self, builds):
561 """See `IBinaryPackageBuildSet`."""
562@@ -1252,31 +1232,24 @@
563 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
564 origin = (
565 BinaryPackageBuild,
566- LeftJoin(
567- PackageBuild,
568- BinaryPackageBuild.package_build == PackageBuild.id),
569- LeftJoin(
570- BuildFarmJob,
571- PackageBuild.build_farm_job == BuildFarmJob.id),
572- LeftJoin(
573+ Join(
574 SourcePackageRelease,
575 (SourcePackageRelease.id ==
576 BinaryPackageBuild.source_package_release_id)),
577- LeftJoin(
578+ Join(
579 SourcePackageName,
580 SourcePackageName.id
581 == SourcePackageRelease.sourcepackagenameID),
582 LeftJoin(LibraryFileAlias,
583- LibraryFileAlias.id == BuildFarmJob.log_id),
584+ LibraryFileAlias.id == BinaryPackageBuild._new_log_id),
585 LeftJoin(LibraryFileContent,
586 LibraryFileContent.id == LibraryFileAlias.contentID),
587 LeftJoin(
588- Builder,
589- Builder.id == BuildFarmJob.builder_id),
590+ Builder, Builder.id == BinaryPackageBuild._new_builder_id),
591 )
592 result_set = store.using(*origin).find(
593 (SourcePackageRelease, LibraryFileAlias, SourcePackageName,
594- LibraryFileContent, Builder, PackageBuild, BuildFarmJob),
595+ LibraryFileContent, Builder),
596 BinaryPackageBuild.id.is_in(build_ids))
597
598 # Force query execution so that the ancillary data gets fetched
599
600=== modified file 'lib/lp/soyuz/model/publishing.py'
601--- lib/lp/soyuz/model/publishing.py 2013-02-04 04:13:30 +0000
602+++ lib/lp/soyuz/model/publishing.py 2013-02-04 04:13:30 +0000
603@@ -1567,7 +1567,7 @@
604 return pub
605
606 def getBuildsForSourceIds(self, source_publication_ids, archive=None,
607- build_states=None, need_build_farm_job=False):
608+ build_states=None):
609 """See `IPublishingSet`."""
610 # If an archive was passed in as a parameter, add an extra expression
611 # to filter by archive:
612@@ -1630,22 +1630,16 @@
613 SourcePackagePublishingHistory,
614 BinaryPackageBuild,
615 DistroArchSeries,
616- ) + ((PackageBuild, BuildFarmJob) if need_build_farm_job else ())
617+ )
618
619 # Storm doesn't let us do builds_union.values('id') -
620 # ('Union' object has no attribute 'columns'). So instead
621 # we have to instantiate the objects just to get the id.
622 build_ids = [build.id for build in builds_union]
623
624- prejoin_exprs = (
625- BinaryPackageBuild.package_build == PackageBuild.id,
626- PackageBuild.build_farm_job == BuildFarmJob.id,
627- ) if need_build_farm_job else ()
628-
629 result_set = store.find(
630 find_spec, builds_for_distroseries_expr,
631- BinaryPackageBuild.id.is_in(build_ids),
632- *prejoin_exprs)
633+ BinaryPackageBuild.id.is_in(build_ids))
634
635 return result_set.order_by(
636 SourcePackagePublishingHistory.id,
637@@ -1896,8 +1890,7 @@
638 # Find relevant builds while also getting PackageBuilds and
639 # BuildFarmJobs into the cache. They're used later.
640 build_info = list(
641- self.getBuildsForSourceIds(
642- source_ids, archive=archive, need_build_farm_job=True))
643+ self.getBuildsForSourceIds(source_ids, archive=archive))
644 source_pubs = set()
645 found_source_ids = set()
646 for row in build_info:
647
648=== modified file 'lib/lp/soyuz/model/queue.py'
649--- lib/lp/soyuz/model/queue.py 2013-01-08 01:10:35 +0000
650+++ lib/lp/soyuz/model/queue.py 2013-02-04 04:13:30 +0000
651@@ -1728,7 +1728,6 @@
652 source_sprs = load_related(
653 SourcePackageRelease, puses, ['sourcepackagereleaseID'])
654 bpbs = load_related(BinaryPackageBuild, pubs, ['buildID'])
655- load_related(PackageBuild, bpbs, ['package_build_id'])
656 load_related(DistroArchSeries, bpbs, ['distro_arch_series_id'])
657 binary_sprs = load_related(
658 SourcePackageRelease, bpbs, ['source_package_release_id'])
659
660=== modified file 'lib/lp/soyuz/scripts/retrydepwait.py'
661--- lib/lp/soyuz/scripts/retrydepwait.py 2013-01-22 08:30:35 +0000
662+++ lib/lp/soyuz/scripts/retrydepwait.py 2013-02-04 04:13:30 +0000
663@@ -8,10 +8,8 @@
664
665
666 import transaction
667-from zope.component import getUtility
668
669 from lp.buildmaster.enums import BuildStatus
670-from lp.buildmaster.model.buildfarmjob import BuildFarmJob
671 from lp.registry.interfaces.series import SeriesStatus
672 from lp.registry.model.sourcepackagename import SourcePackageName
673 from lp.services.database.bulk import load_related
674@@ -20,10 +18,7 @@
675 LoopTuner,
676 TunableLoop,
677 )
678-from lp.soyuz.interfaces.binarypackagebuild import (
679- IBinaryPackageBuildSet,
680- UnparsableDependencies,
681- )
682+from lp.soyuz.interfaces.binarypackagebuild import UnparsableDependencies
683 from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
684 from lp.soyuz.model.distroarchseries import PocketChroot
685 from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
686@@ -44,19 +39,18 @@
687 self.start_at = 1
688 self.store = IStore(BinaryPackageBuild)
689
690- def findBuildFarmJobs(self):
691+ def findBuilds(self):
692 return self.store.find(
693- BuildFarmJob,
694- BuildFarmJob.id >= self.start_at,
695- BuildFarmJob.status == BuildStatus.MANUALDEPWAIT,
696- ).order_by(BuildFarmJob.id)
697+ BinaryPackageBuild,
698+ BinaryPackageBuild.id >= self.start_at,
699+ BinaryPackageBuild._new_status == BuildStatus.MANUALDEPWAIT,
700+ ).order_by(BinaryPackageBuild.id)
701
702 def isDone(self):
703- return self.findBuildFarmJobs().is_empty()
704+ return self.findBuilds().is_empty()
705
706 def __call__(self, chunk_size):
707- bfjs = list(self.findBuildFarmJobs()[:chunk_size])
708- bpbs = getUtility(IBinaryPackageBuildSet).getByBuildFarmJobs(bfjs)
709+ bpbs = list(self.findBuilds()[:chunk_size])
710 sprs = load_related(
711 SourcePackageRelease, bpbs, ['source_package_release_id'])
712 load_related(SourcePackageName, sprs, ['sourcepackagenameID'])
713@@ -83,7 +77,7 @@
714 build.retry()
715 build.buildqueue_record.score()
716
717- self.start_at = bfjs[-1].id + 1
718+ self.start_at = bpbs[-1].id + 1
719
720 if not self.dry_run:
721 transaction.commit()
722
723=== modified file 'lib/lp/soyuz/tests/test_hasbuildrecords.py'
724--- lib/lp/soyuz/tests/test_hasbuildrecords.py 2013-01-31 06:58:23 +0000
725+++ lib/lp/soyuz/tests/test_hasbuildrecords.py 2013-02-04 04:13:30 +0000
726@@ -14,7 +14,6 @@
727 IBuildFarmJob,
728 IBuildFarmJobSource,
729 )
730-from lp.buildmaster.interfaces.packagebuild import IPackageBuildSource
731 from lp.registry.interfaces.person import IPersonSet
732 from lp.registry.interfaces.pocket import PackagePublishingPocket
733 from lp.registry.model.sourcepackage import SourcePackage
734@@ -177,14 +176,8 @@
735 def test_binary_only_false(self):
736 # An archive can optionally return the more general
737 # package build objects.
738-
739- # Until we have different IBuildFarmJob types implemented, we
740- # can only test this by creating a lone PackageBuild of a
741- # different type.
742- bfj = getUtility(IBuildFarmJobSource).new(
743- BuildFarmJobType.RECIPEBRANCHBUILD, virtualized=True)
744- getUtility(IPackageBuildSource).new(
745- bfj, archive=self.context, pocket=PackagePublishingPocket.RELEASE)
746+ getUtility(IBuildFarmJobSource).new(
747+ BuildFarmJobType.RECIPEBRANCHBUILD, archive=self.context)
748
749 builds = self.context.getBuildRecords(binary_only=True)
750 self.failUnlessEqual(3, builds.count())
751@@ -223,13 +216,9 @@
752 def test_binary_only_false(self):
753 # A builder can optionally return the more general
754 # build farm job objects.
755-
756- # Until we have different IBuildFarmJob types implemented, we
757- # can only test this by creating a lone IBuildFarmJob of a
758- # different type.
759 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
760 getUtility(IBuildFarmJobSource).new(
761- job_type=BuildFarmJobType.RECIPEBRANCHBUILD, virtualized=True,
762+ job_type=BuildFarmJobType.RECIPEBRANCHBUILD,
763 status=BuildStatus.BUILDING, builder=self.context)
764
765 builds = self.context.getBuildRecords(binary_only=True)
766
767=== modified file 'lib/lp/soyuz/tests/test_packageupload.py'
768--- lib/lp/soyuz/tests/test_packageupload.py 2013-01-07 06:25:23 +0000
769+++ lib/lp/soyuz/tests/test_packageupload.py 2013-02-04 04:13:30 +0000
770@@ -1304,4 +1304,4 @@
771 IStore(uploads[0].__class__).invalidate()
772 with StormStatementRecorder() as recorder:
773 ws_distroseries.getPackageUploads()
774- self.assertThat(recorder, HasQueryCount(Equals(33)))
775+ self.assertThat(recorder, HasQueryCount(Equals(32)))
776
777=== modified file 'lib/lp/translations/model/translationtemplatesbuild.py'
778--- lib/lp/translations/model/translationtemplatesbuild.py 2013-02-04 04:13:30 +0000
779+++ lib/lp/translations/model/translationtemplatesbuild.py 2013-02-04 04:13:30 +0000
780@@ -159,22 +159,18 @@
781 """See `ITranslationTemplatesBuildSource`."""
782 store = cls._getStore(store)
783 match = store.find(
784- TranslationTemplatesBuild,
785- TranslationTemplatesBuild.build_farm_job_id == buildfarmjob.id)
786+ TranslationTemplatesBuild, build_farm_job_id=buildfarmjob.id)
787 return match.one()
788
789 @classmethod
790 def getByBuildFarmJobs(cls, buildfarmjobs, store=None):
791- buildfarmjob_ids = [buildfarmjob.id for buildfarmjob in buildfarmjobs]
792 """See `ITranslationTemplatesBuildSource`."""
793 store = cls._getStore(store)
794-
795- resultset = store.find(
796+ rows = store.find(
797 TranslationTemplatesBuild,
798 TranslationTemplatesBuild.build_farm_job_id.is_in(
799- buildfarmjob_ids))
800- return DecoratedResultSet(
801- resultset, pre_iter_hook=cls.preloadBuildsData)
802+ bfj.id for bfj in buildfarmjobs))
803+ return DecoratedResultSet(rows, pre_iter_hook=cls.preloadBuildsData)
804
805 @classmethod
806 def preloadBuildsData(cls, builds):
807@@ -188,9 +184,7 @@
808 # Preload branches cached associated product series and
809 # suite source packages for all the related branches.
810 GenericBranchCollection.preloadDataForBranches(branches)
811- build_farm_jobs = [
812- build.build_farm_job for build in builds]
813- load_related(LibraryFileAlias, build_farm_jobs, ['log_id'])
814+ load_related(LibraryFileAlias, builds, ['_new_log_id'])
815
816 @classmethod
817 def findByBranch(cls, branch, store=None):