← Back to team overview

launchpad-reviewers team mailing list archive

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

 

William Grant has proposed merging lp:~wgrant/launchpad/flatten-bfj-3.5-more-query into lp:launchpad with lp:~wgrant/launchpad/flatten-bfj-3-query as a prerequisite.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #758258 in Launchpad itself: "buildfarmjob schema is inefficient for reporting"
  https://bugs.launchpad.net/launchpad/+bug/758258

For more details, see:
https://code.launchpad.net/~wgrant/launchpad/flatten-bfj-3.5-more-query/+merge/145819

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).
-- 
https://code.launchpad.net/~wgrant/launchpad/flatten-bfj-3.5-more-query/+merge/145819
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/flatten-bfj-3.5-more-query into lp:launchpad.
=== modified file 'lib/lp/buildmaster/configure.zcml'
--- lib/lp/buildmaster/configure.zcml	2013-01-07 05:25:16 +0000
+++ lib/lp/buildmaster/configure.zcml	2013-01-31 23:12:23 +0000
@@ -76,12 +76,6 @@
         <allow
             interface="lp.buildmaster.interfaces.packagebuild.IPackageBuildSource" />
     </securedutility>
-    <securedutility
-        class="lp.buildmaster.model.packagebuild.PackageBuildSet"
-        provides="lp.buildmaster.interfaces.packagebuild.IPackageBuildSet">
-        <allow
-            interface="lp.buildmaster.interfaces.packagebuild.IPackageBuildSet" />
-    </securedutility>
 
     <!-- BuildQueue -->
     <class

=== modified file 'lib/lp/buildmaster/interfaces/buildfarmjob.py'
--- lib/lp/buildmaster/interfaces/buildfarmjob.py	2013-01-31 23:12:23 +0000
+++ lib/lp/buildmaster/interfaces/buildfarmjob.py	2013-01-31 23:12:23 +0000
@@ -374,3 +374,12 @@
             that should be included.
         :return: a `ResultSet` representing the requested builds.
         """
+
+    def getBuildsForArchive(archive, status=None):
+        """Return `IBuildFarmJob` records targeted to a given `IArchive`.
+
+        :param archive: The archive for which builds will be returned.
+        :param status: If status is provided, only builders with that
+            status will be returned.
+        :return: a `ResultSet` representing the requested `IBuildFarmJobs`.
+        """

=== modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
--- lib/lp/buildmaster/interfaces/packagebuild.py	2013-01-31 23:12:23 +0000
+++ lib/lp/buildmaster/interfaces/packagebuild.py	2013-01-31 23:12:23 +0000
@@ -6,7 +6,6 @@
 __all__ = [
     'IPackageBuild',
     'IPackageBuildSource',
-    'IPackageBuildSet',
     ]
 
 
@@ -23,7 +22,6 @@
     )
 
 from lp import _
-from lp.buildmaster.enums import BuildStatus
 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob
 from lp.registry.interfaces.distribution import IDistribution
 from lp.registry.interfaces.distroseries import IDistroSeries
@@ -136,18 +134,3 @@
         :param archive: An `IArchive`.
         :param pocket: An item of `PackagePublishingPocket`.
         """
-
-
-class IPackageBuildSet(Interface):
-    """A utility representing a set of package builds."""
-
-    def getBuildsForArchive(archive, status=None, pocket=None):
-        """Return package build records targeted to a given IArchive.
-
-        :param archive: The archive for which builds will be returned.
-        :param status: If status is provided, only builders with that
-            status will be returned.
-        :param pocket: If pocket is provided only builds for that pocket
-            will be returned.
-        :return: a `ResultSet` representing the requested package builds.
-        """

=== modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
--- lib/lp/buildmaster/model/buildfarmjob.py	2013-01-31 23:12:23 +0000
+++ lib/lp/buildmaster/model/buildfarmjob.py	2013-01-31 23:12:23 +0000
@@ -367,13 +367,12 @@
     def getBuildsForBuilder(self, builder_id, status=None, user=None):
         """See `IBuildFarmJobSet`."""
         # Imported here to avoid circular imports.
-        from lp.buildmaster.model.packagebuild import PackageBuild
         from lp.soyuz.model.archive import (
             Archive, get_archive_privacy_filter)
 
         clauses = [
             BuildFarmJob.builder == builder_id,
-            Or(PackageBuild.id == None, get_archive_privacy_filter(user))]
+            Or(Archive.id == None, get_archive_privacy_filter(user))]
         if status is not None:
             clauses.append(BuildFarmJob.status == status)
 
@@ -383,12 +382,40 @@
         # related package build - hence the left join.
         origin = [
             BuildFarmJob,
-            LeftJoin(
-                PackageBuild,
-                PackageBuild.build_farm_job == BuildFarmJob.id),
-            LeftJoin(Archive, Archive.id == PackageBuild.archive_id),
+            LeftJoin(Archive, Archive.id == BuildFarmJob.archive_id),
             ]
 
         return IStore(BuildFarmJob).using(*origin).find(
             BuildFarmJob, *clauses).order_by(
                 Desc(BuildFarmJob.date_finished), BuildFarmJob.id)
+
+    def getBuildsForArchive(self, archive, status=None):
+        """See `IBuildFarmJobSet`."""
+
+        extra_exprs = []
+
+        if status is not None:
+            extra_exprs.append(BuildFarmJob.status == status)
+
+        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
+        result_set = store.find(
+            BuildFarmJob, BuildFarmJob.archive == archive, *extra_exprs)
+
+        # When we have a set of builds that may include pending or
+        # superseded builds, we order by -date_created (as we won't
+        # always have a date_finished). Otherwise we can order by
+        # -date_finished.
+        unfinished_states = [
+            BuildStatus.NEEDSBUILD,
+            BuildStatus.BUILDING,
+            BuildStatus.UPLOADING,
+            BuildStatus.SUPERSEDED,
+            ]
+        if status is None or status in unfinished_states:
+            result_set.order_by(
+                Desc(BuildFarmJob.date_created), BuildFarmJob.id)
+        else:
+            result_set.order_by(
+                Desc(BuildFarmJob.date_finished), BuildFarmJob.id)
+
+        return result_set

=== modified file 'lib/lp/buildmaster/model/packagebuild.py'
--- lib/lp/buildmaster/model/packagebuild.py	2013-01-31 23:12:23 +0000
+++ lib/lp/buildmaster/model/packagebuild.py	2013-01-31 23:12:23 +0000
@@ -5,7 +5,6 @@
 __all__ = [
     'PackageBuild',
     'PackageBuildMixin',
-    'PackageBuildSet',
     ]
 
 
@@ -26,10 +25,8 @@
     )
 
 from lp.buildmaster.enums import BuildStatus
-from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
 from lp.buildmaster.interfaces.packagebuild import (
     IPackageBuild,
-    IPackageBuildSet,
     IPackageBuildSource,
     )
 from lp.buildmaster.model.buildfarmjob import (
@@ -228,43 +225,3 @@
             virtualized=specific_job.virtualized)
         Store.of(self).add(queue_entry)
         return queue_entry
-
-
-class PackageBuildSet:
-    implements(IPackageBuildSet)
-
-    def getBuildsForArchive(self, archive, status=None, pocket=None):
-        """See `IPackageBuildSet`."""
-
-        extra_exprs = []
-
-        if status is not None:
-            extra_exprs.append(BuildFarmJob.status == status)
-
-        if pocket:
-            extra_exprs.append(PackageBuild.pocket == pocket)
-
-        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
-        result_set = store.find(PackageBuild,
-            PackageBuild.archive == archive,
-            PackageBuild.build_farm_job == BuildFarmJob.id,
-            *extra_exprs)
-
-        # When we have a set of builds that may include pending or
-        # superseded builds, we order by -date_created (as we won't
-        # always have a date_finished). Otherwise we can order by
-        # -date_finished.
-        unfinished_states = [
-            BuildStatus.NEEDSBUILD,
-            BuildStatus.BUILDING,
-            BuildStatus.UPLOADING,
-            BuildStatus.SUPERSEDED,
-            ]
-        if status is None or status in unfinished_states:
-            result_set.order_by(
-                Desc(BuildFarmJob.date_created), BuildFarmJob.id)
-        else:
-            result_set.order_by(
-                Desc(BuildFarmJob.date_finished), BuildFarmJob.id)
-
-        return result_set

=== modified file 'lib/lp/buildmaster/tests/test_buildfarmjob.py'
--- lib/lp/buildmaster/tests/test_buildfarmjob.py	2013-01-23 10:16:18 +0000
+++ lib/lp/buildmaster/tests/test_buildfarmjob.py	2013-01-31 23:12:23 +0000
@@ -52,7 +52,7 @@
     def makeBuildFarmJob(self, builder=None,
                          job_type=BuildFarmJobType.PACKAGEBUILD,
                          status=BuildStatus.NEEDSBUILD,
-                         date_finished=None):
+                         date_finished=None, archive=None):
         """A factory method for creating PackageBuilds.
 
         This is not included in the launchpad test factory because
@@ -61,7 +61,7 @@
         or eventually a SPRecipeBuild).
         """
         build_farm_job = getUtility(IBuildFarmJobSource).new(
-            job_type=job_type, status=status)
+            job_type=job_type, status=status, archive=archive)
         removeSecurityProxy(build_farm_job).builder = builder
         removeSecurityProxy(build_farm_job).date_started = date_finished
         removeSecurityProxy(build_farm_job).date_finished = date_finished
@@ -327,3 +327,28 @@
 
         result = self.build_farm_job_set.getBuildsForBuilder(self.builder)
         self.assertEqual([build_2, build_1, build_3], list(result))
+
+    def makeBuildsForArchive(self):
+        archive = self.factory.makeArchive()
+        builds = [
+            self.makeBuildFarmJob(archive=archive),
+            self.makeBuildFarmJob(
+                archive=archive, status=BuildStatus.BUILDING),
+            ]
+        return (archive, builds)
+
+    def test_getBuildsForArchive_all(self):
+        # The default call without arguments returns all builds for the
+        # archive.
+        archive, builds = self.makeBuildsForArchive()
+        self.assertContentEqual(
+            builds, self.build_farm_job_set.getBuildsForArchive(archive))
+
+    def test_getBuildsForArchive_by_status(self):
+        # If the status arg is used, the results will be filtered by
+        # status.
+        archive, builds = self.makeBuildsForArchive()
+        self.assertContentEqual(
+            builds[1:],
+            self.build_farm_job_set.getBuildsForArchive(
+                archive, status=BuildStatus.BUILDING))

=== modified file 'lib/lp/buildmaster/tests/test_packagebuild.py'
--- lib/lp/buildmaster/tests/test_packagebuild.py	2013-01-31 23:12:23 +0000
+++ lib/lp/buildmaster/tests/test_packagebuild.py	2013-01-31 23:12:23 +0000
@@ -19,7 +19,6 @@
 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
 from lp.buildmaster.interfaces.packagebuild import (
     IPackageBuild,
-    IPackageBuildSet,
     IPackageBuildSource,
     )
 from lp.buildmaster.model.buildfarmjob import BuildFarmJob
@@ -203,44 +202,3 @@
         login('admin@xxxxxxxxxxxxx')
         self.assertTrue(checkPermission('launchpad.View', self.package_build))
         self.assertTrue(checkPermission('launchpad.Edit', self.package_build))
-
-
-class TestPackageBuildSet(TestPackageBuildBase):
-
-    layer = LaunchpadFunctionalLayer
-
-    def setUp(self):
-        super(TestPackageBuildSet, self).setUp()
-        person = self.factory.makePerson()
-        self.archive = self.factory.makeArchive(owner=person)
-        self.package_builds = []
-        self.package_builds.append(
-            self.makePackageBuild(archive=self.archive,
-                                  pocket=PackagePublishingPocket.UPDATES))
-        self.package_builds.append(
-            self.makePackageBuild(archive=self.archive,
-                                  status=BuildStatus.BUILDING))
-        self.package_build_set = getUtility(IPackageBuildSet)
-
-    def test_getBuildsForArchive_all(self):
-        # The default call without arguments returns all builds for the
-        # archive.
-        self.assertContentEqual(
-            self.package_builds, self.package_build_set.getBuildsForArchive(
-                self.archive))
-
-    def test_getBuildsForArchive_by_status(self):
-        # If the status arg is used, the results will be filtered by
-        # status.
-        self.assertContentEqual(
-            self.package_builds[1:],
-            self.package_build_set.getBuildsForArchive(
-                self.archive, status=BuildStatus.BUILDING))
-
-    def test_getBuildsForArchive_by_pocket(self):
-        # If the pocket arg is used, the results will be filtered by
-        # pocket.
-        self.assertContentEqual(
-            self.package_builds[:1],
-            self.package_build_set.getBuildsForArchive(
-                self.archive, pocket=PackagePublishingPocket.UPDATES))

=== modified file 'lib/lp/code/model/sourcepackagerecipebuild.py'
--- lib/lp/code/model/sourcepackagerecipebuild.py	2013-01-31 23:12:23 +0000
+++ lib/lp/code/model/sourcepackagerecipebuild.py	2013-01-31 23:12:23 +0000
@@ -328,26 +328,18 @@
     @classmethod
     def getByBuildFarmJob(cls, build_farm_job):
         """See `ISpecificBuildFarmJobSource`."""
-        return Store.of(build_farm_job).find(cls,
-            cls.package_build_id == PackageBuild.id,
-            PackageBuild.build_farm_job_id == build_farm_job.id).one()
+        return Store.of(build_farm_job).find(
+            cls, build_farm_job_id=build_farm_job.id).one()
 
     @classmethod
     def preloadBuildsData(cls, builds):
         # Circular imports.
         from lp.code.model.sourcepackagerecipe import SourcePackageRecipe
         from lp.services.librarian.model import LibraryFileAlias
-        from lp.buildmaster.model.buildfarmjob import BuildFarmJob
-        package_builds = load_related(
-            PackageBuild, builds, ['package_build_id'])
-        build_farm_jobs = load_related(
-            BuildFarmJob, [build.package_build for build in builds],
-            ['build_farm_job_id'])
-        load_related(LibraryFileAlias, build_farm_jobs, ['log_id'])
-        archives = load_related(Archive, package_builds, ['archive_id'])
+        load_related(LibraryFileAlias, builds, ['_new_log_id'])
+        archives = load_related(Archive, builds, ['_new_archive_id'])
         load_related(Person, archives, ['ownerID'])
-        sprs = load_related(
-            SourcePackageRecipe, builds, ['recipe_id'])
+        sprs = load_related(SourcePackageRecipe, builds, ['recipe_id'])
         SourcePackageRecipe.preLoadDataForSourcePackageRecipes(sprs)
 
     @classmethod
@@ -355,14 +347,10 @@
         """See `ISpecificBuildFarmJobSource`."""
         if len(build_farm_jobs) == 0:
             return EmptyResultSet()
-        build_farm_job_ids = [
-            build_farm_job.id for build_farm_job in build_farm_jobs]
-
-        resultset = Store.of(build_farm_jobs[0]).find(cls,
-            cls.package_build_id == PackageBuild.id,
-            PackageBuild.build_farm_job_id.is_in(build_farm_job_ids))
-        return DecoratedResultSet(
-            resultset, pre_iter_hook=cls.preloadBuildsData)
+        rows = Store.of(build_farm_jobs[0]).find(
+            cls, cls.build_farm_job_id.is_in(
+                bfj.id for bfj in build_farm_jobs))
+        return DecoratedResultSet(rows, pre_iter_hook=cls.preloadBuildsData)
 
     @classmethod
     def getRecentBuilds(cls, requester, recipe, distroseries, _now=None):

=== modified file 'lib/lp/soyuz/browser/tests/test_queue.py'
--- lib/lp/soyuz/browser/tests/test_queue.py	2013-01-08 05:45:26 +0000
+++ lib/lp/soyuz/browser/tests/test_queue.py	2013-01-31 23:12:23 +0000
@@ -398,7 +398,7 @@
             with StormStatementRecorder() as recorder:
                 view = self.makeView(distroseries, queue_admin)
                 view()
-        self.assertThat(recorder, HasQueryCount(Equals(55)))
+        self.assertThat(recorder, HasQueryCount(Equals(54)))
 
 
 class TestCompletePackageUpload(TestCaseWithFactory):

=== modified file 'lib/lp/soyuz/interfaces/publishing.py'
--- lib/lp/soyuz/interfaces/publishing.py	2013-01-07 02:40:55 +0000
+++ lib/lp/soyuz/interfaces/publishing.py	2013-01-31 23:12:23 +0000
@@ -1091,8 +1091,7 @@
             binary publications.
         """
 
-    def getBuildsForSourceIds(source_ids, archive=None, build_states=None,
-                              need_build_farm_job=False):
+    def getBuildsForSourceIds(source_ids, archive=None, build_states=None):
         """Return all builds related with each given source publication.
 
         The returned ResultSet contains entries with the wanted `Build`s
@@ -1120,10 +1119,8 @@
         :type build_states: ``list`` or None
         :param need_build_farm_job: whether to include the `PackageBuild`
             and `BuildFarmJob` in the result.
-        :type need_build_farm_job: bool
         :return: a storm ResultSet containing tuples as
-            (`SourcePackagePublishingHistory`, `Build`, `DistroArchSeries`,
-             [`PackageBuild`, `BuildFarmJob` if need_build_farm_job])
+            (`SourcePackagePublishingHistory`, `Build`, `DistroArchSeries`)
         :rtype: `storm.store.ResultSet`.
         """
 

=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py	2013-01-31 23:12:23 +0000
+++ lib/lp/soyuz/model/archive.py	2013-01-31 23:12:23 +0000
@@ -54,7 +54,7 @@
     re_issource,
     )
 from lp.buildmaster.enums import BuildStatus
-from lp.buildmaster.interfaces.packagebuild import IPackageBuildSet
+from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSet
 from lp.registry.enums import (
     INCLUSIVE_TEAM_POLICY,
     PersonVisibility,
@@ -486,12 +486,12 @@
             return getUtility(IBinaryPackageBuildSet).getBuildsForArchive(
                 self, build_state, name, pocket, arch_tag)
         else:
-            if arch_tag is not None or name is not None:
+            if arch_tag is not None or name is not None or pocket is not None:
                 raise IncompatibleArguments(
                     "The 'arch_tag' and 'name' parameters can be used only "
                     "with binary_only=True.")
-            return getUtility(IPackageBuildSet).getBuildsForArchive(
-                self, status=build_state, pocket=pocket)
+            return getUtility(IBuildFarmJobSet).getBuildsForArchive(
+                self, status=build_state)
 
     def getPublishedSources(self, name=None, version=None, status=None,
                             distroseries=None, pocket=None,

=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
--- lib/lp/soyuz/model/binarypackagebuild.py	2013-01-31 23:12:23 +0000
+++ lib/lp/soyuz/model/binarypackagebuild.py	2013-01-31 23:12:23 +0000
@@ -47,10 +47,7 @@
 from lp.buildmaster.model.builder import Builder
 from lp.buildmaster.model.buildfarmjob import BuildFarmJob
 from lp.buildmaster.model.buildqueue import BuildQueue
-from lp.buildmaster.model.packagebuild import (
-    PackageBuild,
-    PackageBuildMixin,
-    )
+from lp.buildmaster.model.packagebuild import PackageBuildMixin
 from lp.registry.interfaces.pocket import PackagePublishingPocket
 from lp.services.config import config
 from lp.services.database.bulk import load_related
@@ -898,15 +895,8 @@
 
     def getByBuildFarmJob(self, build_farm_job):
         """See `ISpecificBuildFarmJobSource`."""
-        find_spec = (BinaryPackageBuild, PackageBuild, BuildFarmJob)
-        resulting_tuple = Store.of(build_farm_job).find(
-            find_spec,
-            BinaryPackageBuild.package_build == PackageBuild.id,
-            PackageBuild.build_farm_job == BuildFarmJob.id,
-            BuildFarmJob.id == build_farm_job.id).one()
-        if resulting_tuple is None:
-            return None
-        return resulting_tuple[0]
+        return Store.of(build_farm_job).find(
+            BinaryPackageBuild, build_farm_job_id=build_farm_job.id).one()
 
     def preloadBuildsData(self, builds):
         # Circular imports.
@@ -918,9 +908,7 @@
         self._prefetchBuildData(builds)
         distro_arch_series = load_related(
             DistroArchSeries, builds, ['distro_arch_series_id'])
-        package_builds = load_related(
-            PackageBuild, builds, ['package_build_id'])
-        archives = load_related(Archive, package_builds, ['archive_id'])
+        archives = load_related(Archive, builds, ['_new_archive_id'])
         load_related(Person, archives, ['ownerID'])
         distroseries = load_related(
             DistroSeries, distro_arch_series, ['distroseriesID'])
@@ -931,17 +919,11 @@
         """See `ISpecificBuildFarmJobSource`."""
         if len(build_farm_jobs) == 0:
             return EmptyResultSet()
-        clause_tables = (BinaryPackageBuild, PackageBuild, BuildFarmJob)
-        build_farm_job_ids = [
-            build_farm_job.id for build_farm_job in build_farm_jobs]
-
-        resultset = Store.of(build_farm_jobs[0]).using(*clause_tables).find(
+        rows = Store.of(build_farm_jobs[0]).find(
             BinaryPackageBuild,
-            BinaryPackageBuild.package_build == PackageBuild.id,
-            PackageBuild.build_farm_job == BuildFarmJob.id,
-            BuildFarmJob.id.is_in(build_farm_job_ids))
-        return DecoratedResultSet(
-            resultset, pre_iter_hook=self.preloadBuildsData)
+            BinaryPackageBuild.build_farm_job_id.is_in(
+                bfj.id for bfj in build_farm_jobs))
+        return DecoratedResultSet(rows, pre_iter_hook=self.preloadBuildsData)
 
     def handleOptionalParamsForBuildQueries(
         self, clauses, origin, status=None, name=None, pocket=None,
@@ -1148,10 +1130,8 @@
 
         query = """
             source_package_release IN %s AND
-            package_build = packagebuild.id AND
             archive.id = binarypackagebuild.archive AND
-            archive.purpose != %s AND
-            packagebuild.build_farm_job = buildfarmjob.id
+            archive.purpose != %s
             """ % sqlvalues(sourcepackagerelease_ids, ArchivePurpose.PPA)
 
         if buildstate is not None:
@@ -1159,12 +1139,12 @@
                 "AND binarypackagebuild.status = %s" % sqlvalues(buildstate))
 
         resultset = IStore(BinaryPackageBuild).using(
-            BinaryPackageBuild, PackageBuild, BuildFarmJob, Archive).find(
-            (BinaryPackageBuild, PackageBuild, BuildFarmJob),
+            BinaryPackageBuild, Archive).find(
+            BinaryPackageBuild,
             SQL(query))
         resultset.order_by(
             Desc(BinaryPackageBuild._new_date_created), BinaryPackageBuild.id)
-        return DecoratedResultSet(resultset, operator.itemgetter(0))
+        return resultset
 
     def getStatusSummaryForBuilds(self, builds):
         """See `IBinaryPackageBuildSet`."""
@@ -1237,31 +1217,24 @@
         store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
         origin = (
             BinaryPackageBuild,
-            LeftJoin(
-                PackageBuild,
-                BinaryPackageBuild.package_build == PackageBuild.id),
-            LeftJoin(
-                BuildFarmJob,
-                PackageBuild.build_farm_job == BuildFarmJob.id),
-            LeftJoin(
+            Join(
                 SourcePackageRelease,
                 (SourcePackageRelease.id ==
                     BinaryPackageBuild.source_package_release_id)),
-            LeftJoin(
+            Join(
                 SourcePackageName,
                 SourcePackageName.id
                     == SourcePackageRelease.sourcepackagenameID),
             LeftJoin(LibraryFileAlias,
-                     LibraryFileAlias.id == BuildFarmJob.log_id),
+                     LibraryFileAlias.id == BinaryPackageBuild._new_log_id),
             LeftJoin(LibraryFileContent,
                      LibraryFileContent.id == LibraryFileAlias.contentID),
             LeftJoin(
-                Builder,
-                Builder.id == BuildFarmJob.builder_id),
+                Builder, Builder.id == BinaryPackageBuild._new_builder_id),
             )
         result_set = store.using(*origin).find(
             (SourcePackageRelease, LibraryFileAlias, SourcePackageName,
-             LibraryFileContent, Builder, PackageBuild, BuildFarmJob),
+             LibraryFileContent, Builder),
             BinaryPackageBuild.id.is_in(build_ids))
 
         # Force query execution so that the ancillary data gets fetched

=== modified file 'lib/lp/soyuz/model/publishing.py'
--- lib/lp/soyuz/model/publishing.py	2013-01-31 23:12:23 +0000
+++ lib/lp/soyuz/model/publishing.py	2013-01-31 23:12:23 +0000
@@ -1567,7 +1567,7 @@
         return pub
 
     def getBuildsForSourceIds(self, source_publication_ids, archive=None,
-                              build_states=None, need_build_farm_job=False):
+                              build_states=None):
         """See `IPublishingSet`."""
         # If an archive was passed in as a parameter, add an extra expression
         # to filter by archive:
@@ -1630,22 +1630,16 @@
             SourcePackagePublishingHistory,
             BinaryPackageBuild,
             DistroArchSeries,
-            ) + ((PackageBuild, BuildFarmJob) if need_build_farm_job else ())
+            )
 
         # Storm doesn't let us do builds_union.values('id') -
         # ('Union' object has no attribute 'columns'). So instead
         # we have to instantiate the objects just to get the id.
         build_ids = [build.id for build in builds_union]
 
-        prejoin_exprs = (
-            BinaryPackageBuild.package_build == PackageBuild.id,
-            PackageBuild.build_farm_job == BuildFarmJob.id,
-            ) if need_build_farm_job else ()
-
         result_set = store.find(
             find_spec, builds_for_distroseries_expr,
-            BinaryPackageBuild.id.is_in(build_ids),
-            *prejoin_exprs)
+            BinaryPackageBuild.id.is_in(build_ids))
 
         return result_set.order_by(
             SourcePackagePublishingHistory.id,
@@ -1896,8 +1890,7 @@
         # Find relevant builds while also getting PackageBuilds and
         # BuildFarmJobs into the cache. They're used later.
         build_info = list(
-            self.getBuildsForSourceIds(
-                source_ids, archive=archive, need_build_farm_job=True))
+            self.getBuildsForSourceIds(source_ids, archive=archive))
         source_pubs = set()
         found_source_ids = set()
         for row in build_info:

=== modified file 'lib/lp/soyuz/model/queue.py'
--- lib/lp/soyuz/model/queue.py	2013-01-08 01:10:35 +0000
+++ lib/lp/soyuz/model/queue.py	2013-01-31 23:12:23 +0000
@@ -1728,7 +1728,6 @@
     source_sprs = load_related(
         SourcePackageRelease, puses, ['sourcepackagereleaseID'])
     bpbs = load_related(BinaryPackageBuild, pubs, ['buildID'])
-    load_related(PackageBuild, bpbs, ['package_build_id'])
     load_related(DistroArchSeries, bpbs, ['distro_arch_series_id'])
     binary_sprs = load_related(
         SourcePackageRelease, bpbs, ['source_package_release_id'])

=== modified file 'lib/lp/soyuz/scripts/retrydepwait.py'
--- lib/lp/soyuz/scripts/retrydepwait.py	2013-01-22 08:30:35 +0000
+++ lib/lp/soyuz/scripts/retrydepwait.py	2013-01-31 23:12:23 +0000
@@ -8,10 +8,8 @@
 
 
 import transaction
-from zope.component import getUtility
 
 from lp.buildmaster.enums import BuildStatus
-from lp.buildmaster.model.buildfarmjob import BuildFarmJob
 from lp.registry.interfaces.series import SeriesStatus
 from lp.registry.model.sourcepackagename import SourcePackageName
 from lp.services.database.bulk import load_related
@@ -20,10 +18,7 @@
     LoopTuner,
     TunableLoop,
     )
-from lp.soyuz.interfaces.binarypackagebuild import (
-    IBinaryPackageBuildSet,
-    UnparsableDependencies,
-    )
+from lp.soyuz.interfaces.binarypackagebuild import UnparsableDependencies
 from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
 from lp.soyuz.model.distroarchseries import PocketChroot
 from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
@@ -44,19 +39,18 @@
         self.start_at = 1
         self.store = IStore(BinaryPackageBuild)
 
-    def findBuildFarmJobs(self):
+    def findBuilds(self):
         return self.store.find(
-            BuildFarmJob,
-            BuildFarmJob.id >= self.start_at,
-            BuildFarmJob.status == BuildStatus.MANUALDEPWAIT,
-            ).order_by(BuildFarmJob.id)
+            BinaryPackageBuild,
+            BinaryPackageBuild.id >= self.start_at,
+            BinaryPackageBuild._new_status == BuildStatus.MANUALDEPWAIT,
+            ).order_by(BinaryPackageBuild.id)
 
     def isDone(self):
-        return self.findBuildFarmJobs().is_empty()
+        return self.findBuilds().is_empty()
 
     def __call__(self, chunk_size):
-        bfjs = list(self.findBuildFarmJobs()[:chunk_size])
-        bpbs = getUtility(IBinaryPackageBuildSet).getByBuildFarmJobs(bfjs)
+        bpbs = list(self.findBuilds()[:chunk_size])
         sprs = load_related(
             SourcePackageRelease, bpbs, ['source_package_release_id'])
         load_related(SourcePackageName, sprs, ['sourcepackagenameID'])
@@ -83,7 +77,7 @@
                 build.retry()
                 build.buildqueue_record.score()
 
-        self.start_at = bfjs[-1].id + 1
+        self.start_at = bpbs[-1].id + 1
 
         if not self.dry_run:
             transaction.commit()

=== modified file 'lib/lp/soyuz/tests/test_hasbuildrecords.py'
--- lib/lp/soyuz/tests/test_hasbuildrecords.py	2013-01-31 23:12:23 +0000
+++ lib/lp/soyuz/tests/test_hasbuildrecords.py	2013-01-31 23:12:23 +0000
@@ -14,7 +14,6 @@
     IBuildFarmJob,
     IBuildFarmJobSource,
     )
-from lp.buildmaster.interfaces.packagebuild import IPackageBuildSource
 from lp.registry.interfaces.person import IPersonSet
 from lp.registry.interfaces.pocket import PackagePublishingPocket
 from lp.registry.model.sourcepackage import SourcePackage
@@ -181,10 +180,8 @@
         # Until we have different IBuildFarmJob types implemented, we
         # can only test this by creating a lone PackageBuild of a
         # different type.
-        bfj = getUtility(IBuildFarmJobSource).new(
-            BuildFarmJobType.RECIPEBRANCHBUILD, virtualized=True)
-        getUtility(IPackageBuildSource).new(
-            bfj, archive=self.context, pocket=PackagePublishingPocket.RELEASE)
+        getUtility(IBuildFarmJobSource).new(
+            BuildFarmJobType.RECIPEBRANCHBUILD, archive=self.context)
 
         builds = self.context.getBuildRecords(binary_only=True)
         self.failUnlessEqual(3, builds.count())
@@ -229,7 +226,7 @@
         # different type.
         from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
         getUtility(IBuildFarmJobSource).new(
-            job_type=BuildFarmJobType.RECIPEBRANCHBUILD, virtualized=True,
+            job_type=BuildFarmJobType.RECIPEBRANCHBUILD,
             status=BuildStatus.BUILDING, builder=self.context)
 
         builds = self.context.getBuildRecords(binary_only=True)

=== modified file 'lib/lp/soyuz/tests/test_packageupload.py'
--- lib/lp/soyuz/tests/test_packageupload.py	2013-01-07 06:25:23 +0000
+++ lib/lp/soyuz/tests/test_packageupload.py	2013-01-31 23:12:23 +0000
@@ -1304,4 +1304,4 @@
         IStore(uploads[0].__class__).invalidate()
         with StormStatementRecorder() as recorder:
             ws_distroseries.getPackageUploads()
-        self.assertThat(recorder, HasQueryCount(Equals(33)))
+        self.assertThat(recorder, HasQueryCount(Equals(32)))

=== modified file 'lib/lp/translations/model/translationtemplatesbuild.py'
--- lib/lp/translations/model/translationtemplatesbuild.py	2013-01-31 23:12:23 +0000
+++ lib/lp/translations/model/translationtemplatesbuild.py	2013-01-31 23:12:23 +0000
@@ -159,22 +159,18 @@
         """See `ITranslationTemplatesBuildSource`."""
         store = cls._getStore(store)
         match = store.find(
-            TranslationTemplatesBuild,
-            TranslationTemplatesBuild.build_farm_job_id == buildfarmjob.id)
+            TranslationTemplatesBuild, build_farm_job_id=buildfarmjob.id)
         return match.one()
 
     @classmethod
     def getByBuildFarmJobs(cls, buildfarmjobs, store=None):
-        buildfarmjob_ids = [buildfarmjob.id for buildfarmjob in buildfarmjobs]
         """See `ITranslationTemplatesBuildSource`."""
         store = cls._getStore(store)
-
-        resultset = store.find(
+        rows = store.find(
             TranslationTemplatesBuild,
             TranslationTemplatesBuild.build_farm_job_id.is_in(
-                buildfarmjob_ids))
-        return DecoratedResultSet(
-            resultset, pre_iter_hook=cls.preloadBuildsData)
+                bfj.id for bfj in buildfarmjobs))
+        return DecoratedResultSet(rows, pre_iter_hook=cls.preloadBuildsData)
 
     @classmethod
     def preloadBuildsData(cls, builds):
@@ -188,9 +184,7 @@
         # Preload branches cached associated product series and
         # suite source packages for all the related branches.
         GenericBranchCollection.preloadDataForBranches(branches)
-        build_farm_jobs = [
-            build.build_farm_job for build in builds]
-        load_related(LibraryFileAlias, build_farm_jobs, ['log_id'])
+        load_related(LibraryFileAlias, builds, ['_new_log_id'])
 
     @classmethod
     def findByBranch(cls, branch, store=None):