Merge lp:~stevenk/launchpad/stormier-getbuildsforbuilder into lp:launchpad
- stormier-getbuildsforbuilder
- Merge into devel
Proposed by
Steve Kowalik
on 2012-09-25
| Status: | Merged | ||||
|---|---|---|---|---|---|
| Approved by: | Steve Kowalik on 2012-09-25 | ||||
| Approved revision: | no longer in the source branch. | ||||
| Merged at revision: | 16034 | ||||
| Proposed branch: | lp:~stevenk/launchpad/stormier-getbuildsforbuilder | ||||
| Merge into: | lp:launchpad | ||||
| Diff against target: |
635 lines (+91/-227) 8 files modified
lib/lp/buildmaster/model/buildfarmjob.py (+6/-23) lib/lp/registry/interfaces/distroseries.py (+0/-21) lib/lp/registry/model/distributionsourcepackage.py (+0/-3) lib/lp/registry/model/distroseries.py (+0/-23) lib/lp/registry/model/sourcepackage.py (+9/-41) lib/lp/registry/tests/test_distroseries.py (+0/-32) lib/lp/soyuz/model/archive.py (+21/-3) lib/lp/soyuz/model/binarypackagebuild.py (+55/-81) |
||||
| To merge this branch: | bzr merge lp:~stevenk/launchpad/stormier-getbuildsforbuilder | ||||
| Related bugs: |
|
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| William Grant | code | 2012-09-25 | Approve on 2012-09-25 |
|
Review via email:
|
|||
Commit Message
Switch BinaryPackageBu
Description of the Change
Switch BinaryPackageBu
I have cleaned up the pylint garbage and trimmed a bit of whitespace.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
| 1 | === modified file 'lib/lp/buildmaster/model/buildfarmjob.py' |
| 2 | --- lib/lp/buildmaster/model/buildfarmjob.py 2012-09-11 06:18:18 +0000 |
| 3 | +++ lib/lp/buildmaster/model/buildfarmjob.py 2012-09-26 04:19:22 +0000 |
| 4 | @@ -16,9 +16,7 @@ |
| 5 | from storm.expr import ( |
| 6 | Desc, |
| 7 | LeftJoin, |
| 8 | - Not, |
| 9 | Or, |
| 10 | - Select, |
| 11 | ) |
| 12 | from storm.locals import ( |
| 13 | Bool, |
| 14 | @@ -53,8 +51,6 @@ |
| 15 | ISpecificBuildFarmJobSource, |
| 16 | ) |
| 17 | from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet |
| 18 | -from lp.registry.interfaces.role import IPersonRoles |
| 19 | -from lp.registry.model.teammembership import TeamParticipation |
| 20 | from lp.services.database.constants import UTC_NOW |
| 21 | from lp.services.database.enumcol import DBEnum |
| 22 | from lp.services.database.lpstorm import ( |
| 23 | @@ -418,9 +414,12 @@ |
| 24 | """See `IBuildFarmJobSet`.""" |
| 25 | # Imported here to avoid circular imports. |
| 26 | from lp.buildmaster.model.packagebuild import PackageBuild |
| 27 | - from lp.soyuz.model.archive import Archive |
| 28 | + from lp.soyuz.model.archive import ( |
| 29 | + Archive, get_archive_privacy_filter) |
| 30 | |
| 31 | - clauses = [BuildFarmJob.builder == builder_id] |
| 32 | + clauses = [ |
| 33 | + BuildFarmJob.builder == builder_id, |
| 34 | + Or(PackageBuild.id == None, get_archive_privacy_filter(user))] |
| 35 | if status is not None: |
| 36 | clauses.append(BuildFarmJob.status == status) |
| 37 | |
| 38 | @@ -433,25 +432,9 @@ |
| 39 | LeftJoin( |
| 40 | PackageBuild, |
| 41 | PackageBuild.build_farm_job == BuildFarmJob.id), |
| 42 | + LeftJoin(Archive, Archive.id == PackageBuild.archive_id), |
| 43 | ] |
| 44 | |
| 45 | - if user is None: |
| 46 | - # Anonymous requests don't get to see private builds at all. |
| 47 | - origin.append( |
| 48 | - LeftJoin(Archive, Archive.id == PackageBuild.archive_id)) |
| 49 | - clauses.append(Or(PackageBuild.id == None, Not(Archive._private))) |
| 50 | - elif not IPersonRoles(user).in_admin: |
| 51 | - # Non-admin users see all public builds and the specific |
| 52 | - # private builds to which they have access. |
| 53 | - origin.append( |
| 54 | - LeftJoin(Archive, Archive.id == PackageBuild.archive_id)) |
| 55 | - clauses.append( |
| 56 | - Or(PackageBuild.id == None, Not(Archive._private), |
| 57 | - Archive.ownerID.is_in( |
| 58 | - Select( |
| 59 | - TeamParticipation.teamID, |
| 60 | - where=(TeamParticipation.person == user))))) |
| 61 | - |
| 62 | return IStore(BuildFarmJob).using(*origin).find( |
| 63 | BuildFarmJob, *clauses).order_by( |
| 64 | Desc(BuildFarmJob.date_finished), BuildFarmJob.id) |
| 65 | |
| 66 | === modified file 'lib/lp/registry/interfaces/distroseries.py' |
| 67 | --- lib/lp/registry/interfaces/distroseries.py 2012-09-07 05:13:57 +0000 |
| 68 | +++ lib/lp/registry/interfaces/distroseries.py 2012-09-26 04:19:22 +0000 |
| 69 | @@ -1,8 +1,6 @@ |
| 70 | # Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
| 71 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 72 | |
| 73 | -# pylint: disable-msg=E0211,E0213 |
| 74 | - |
| 75 | """Interfaces including and related to IDistroSeries.""" |
| 76 | |
| 77 | __metaclass__ = type |
| 78 | @@ -380,9 +378,6 @@ |
| 79 | on clients, which requires downloading Packages files for |
| 80 | multiple architectures."""))) |
| 81 | |
| 82 | - def priorReleasedSeries(): |
| 83 | - """Prior series *by date* from the same distribution.""" |
| 84 | - |
| 85 | main_archive = exported( |
| 86 | Reference( |
| 87 | Interface, # Really IArchive, see below for circular import fix. |
| 88 | @@ -1071,24 +1066,8 @@ |
| 89 | released == None will do no filtering on status. |
| 90 | """ |
| 91 | |
| 92 | - def priorReleasedSeries(distribution, prior_to_date): |
| 93 | - """Find distroseries for the supplied distro released before a |
| 94 | - certain date. |
| 95 | - |
| 96 | - :param distribution: An `IDistribution` in which to search for its |
| 97 | - series. |
| 98 | - :param prior_to_date: A `datetime` |
| 99 | - |
| 100 | - :return: `IResultSet` of `IDistroSeries` that were released before |
| 101 | - prior_to_date, ordered in increasing order of age. |
| 102 | - """ |
| 103 | - |
| 104 | |
| 105 | @error_status(httplib.BAD_REQUEST) |
| 106 | class DerivationError(Exception): |
| 107 | """Raised when there is a problem deriving a distroseries.""" |
| 108 | _message_prefix = "Error deriving distro series" |
| 109 | - |
| 110 | - |
| 111 | -# Monkey patch for circular import avoidance done in |
| 112 | -# _schema_circular_imports.py |
| 113 | |
| 114 | === modified file 'lib/lp/registry/model/distributionsourcepackage.py' |
| 115 | --- lib/lp/registry/model/distributionsourcepackage.py 2012-08-08 05:36:44 +0000 |
| 116 | +++ lib/lp/registry/model/distributionsourcepackage.py 2012-09-26 04:19:22 +0000 |
| 117 | @@ -1,8 +1,6 @@ |
| 118 | # Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
| 119 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 120 | |
| 121 | -# pylint: disable-msg=E0611,W0212 |
| 122 | - |
| 123 | """Classes to represent source packages in a distribution.""" |
| 124 | |
| 125 | __metaclass__ = type |
| 126 | @@ -35,7 +33,6 @@ |
| 127 | from zope.interface import implements |
| 128 | |
| 129 | from lp.bugs.interfaces.bugsummary import IBugSummaryDimension |
| 130 | -from lp.bugs.model.bug import BugSet |
| 131 | from lp.bugs.model.bugtarget import BugTargetBase |
| 132 | from lp.bugs.model.bugtask import BugTask |
| 133 | from lp.bugs.model.structuralsubscription import ( |
| 134 | |
| 135 | === modified file 'lib/lp/registry/model/distroseries.py' |
| 136 | --- lib/lp/registry/model/distroseries.py 2012-09-11 19:14:41 +0000 |
| 137 | +++ lib/lp/registry/model/distroseries.py 2012-09-26 04:19:22 +0000 |
| 138 | @@ -1,8 +1,6 @@ |
| 139 | # Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
| 140 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 141 | |
| 142 | -# pylint: disable-msg=E0611,W0212 |
| 143 | - |
| 144 | """Database classes for a distribution series.""" |
| 145 | |
| 146 | __metaclass__ = type |
| 147 | @@ -689,15 +687,6 @@ |
| 148 | orderBy=["Language.englishname"]) |
| 149 | return result |
| 150 | |
| 151 | - def priorReleasedSeries(self): |
| 152 | - """See `IDistroSeries`.""" |
| 153 | - datereleased = self.datereleased |
| 154 | - # if this one is unreleased, use the last released one |
| 155 | - if not datereleased: |
| 156 | - datereleased = UTC_NOW |
| 157 | - return getUtility(IDistroSeriesSet).priorReleasedSeries( |
| 158 | - self.distribution, datereleased) |
| 159 | - |
| 160 | @property |
| 161 | def bug_reporting_guidelines(self): |
| 162 | """See `IBugTarget`.""" |
| 163 | @@ -1728,15 +1717,3 @@ |
| 164 | else: |
| 165 | |
| 166 | return DistroSeries.select(where_clause) |
| 167 | - |
| 168 | - def priorReleasedSeries(self, distribution, prior_to_date): |
| 169 | - """See `IDistroSeriesSet`.""" |
| 170 | - store = Store.of(distribution) |
| 171 | - results = store.find( |
| 172 | - DistroSeries, |
| 173 | - DistroSeries.distributionID == distribution.id, |
| 174 | - DistroSeries.datereleased < prior_to_date, |
| 175 | - DistroSeries.datereleased != None |
| 176 | - ).order_by(Desc(DistroSeries.datereleased)) |
| 177 | - |
| 178 | - return results |
| 179 | |
| 180 | === modified file 'lib/lp/registry/model/sourcepackage.py' |
| 181 | --- lib/lp/registry/model/sourcepackage.py 2012-08-08 05:36:44 +0000 |
| 182 | +++ lib/lp/registry/model/sourcepackage.py 2012-09-26 04:19:22 +0000 |
| 183 | @@ -1,7 +1,6 @@ |
| 184 | -# Copyright 2009, 2011 Canonical Ltd. This software is licensed under the |
| 185 | +# Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
| 186 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 187 | |
| 188 | -# pylint: disable-msg=E0611,W0212 |
| 189 | """Database classes that implement SourcePackage items.""" |
| 190 | |
| 191 | __metaclass__ = type |
| 192 | @@ -156,10 +155,6 @@ |
| 193 | return recipients |
| 194 | |
| 195 | @property |
| 196 | - def _store(self): |
| 197 | - return Store.of(self.sourcepackagename) |
| 198 | - |
| 199 | - @property |
| 200 | def answer_contacts(self): |
| 201 | """See `IQuestionTarget`.""" |
| 202 | answer_contacts = set() |
| 203 | @@ -222,18 +217,6 @@ |
| 204 | return '<%s %r %r %r>' % (self.__class__.__name__, |
| 205 | self.distribution, self.distroseries, self.sourcepackagename) |
| 206 | |
| 207 | - def _get_ubuntu(self): |
| 208 | - # XXX: kiko 2006-03-20: Ideally, it would be possible to just do |
| 209 | - # ubuntu = getUtility(ILaunchpadCelebrities).ubuntu |
| 210 | - # and not need this method. However, importd currently depends |
| 211 | - # on SourcePackage methods that require the ubuntu celebrity, |
| 212 | - # and given it does not execute_zcml_for_scripts, we are forced |
| 213 | - # here to do this hack instead of using components. Ideally, |
| 214 | - # imports is rewritten to not use SourcePackage, or it |
| 215 | - # initializes the component architecture correctly. |
| 216 | - from lp.registry.model.distribution import Distribution |
| 217 | - return Distribution.byName("ubuntu") |
| 218 | - |
| 219 | def _getPublishingHistory(self, version=None, include_status=None, |
| 220 | exclude_status=None, order_by=None): |
| 221 | """Build a query and return a list of SourcePackagePublishingHistory. |
| 222 | @@ -423,32 +406,17 @@ |
| 223 | """See `ISourcePackage`""" |
| 224 | # First we look to see if there is packaging data for this |
| 225 | # distroseries and sourcepackagename. If not, we look up through |
| 226 | - # parent distroseries, and when we hit Ubuntu, we look backwards in |
| 227 | - # time through Ubuntu series till we find packaging information or |
| 228 | - # blow past the Warty Warthog. |
| 229 | + # parent distroseries. |
| 230 | |
| 231 | - # see if there is a direct packaging |
| 232 | result = self.direct_packaging |
| 233 | if result is not None: |
| 234 | return result |
| 235 | |
| 236 | - ubuntu = self._get_ubuntu() |
| 237 | - # if we are an ubuntu sourcepackage, try the previous series of |
| 238 | - # ubuntu |
| 239 | - if self.distribution == ubuntu: |
| 240 | - ubuntuseries = self.distroseries.priorReleasedSeries() |
| 241 | - previous_ubuntu_series = ubuntuseries.first() |
| 242 | - if previous_ubuntu_series is not None: |
| 243 | - sp = SourcePackage(sourcepackagename=self.sourcepackagename, |
| 244 | - distroseries=previous_ubuntu_series) |
| 245 | - return sp.packaging |
| 246 | - # if we have a parent distroseries, try that |
| 247 | + # If we have a parent distroseries, try that. |
| 248 | if self.distroseries.previous_series is not None: |
| 249 | sp = SourcePackage(sourcepackagename=self.sourcepackagename, |
| 250 | distroseries=self.distroseries.previous_series) |
| 251 | return sp.packaging |
| 252 | - # capitulate |
| 253 | - return None |
| 254 | |
| 255 | @property |
| 256 | def published_by_pocket(self): |
| 257 | @@ -626,7 +594,7 @@ |
| 258 | # binary_only parameter as a source package can only have |
| 259 | # binary builds. |
| 260 | |
| 261 | - clauseTables = ['SourcePackageRelease', |
| 262 | + clauseTables = ['SourcePackageRelease', 'PackageBuild', |
| 263 | 'SourcePackagePublishingHistory'] |
| 264 | |
| 265 | condition_clauses = [""" |
| 266 | @@ -673,17 +641,17 @@ |
| 267 | clauseTables.append('BuildQueue') |
| 268 | condition_clauses.append('BuildQueue.job = BuildPackageJob.job') |
| 269 | elif build_state == BuildStatus.SUPERSEDED or build_state is None: |
| 270 | - orderBy = ["-BuildFarmJob.date_created"] |
| 271 | + orderBy = [Desc("BuildFarmJob.date_created")] |
| 272 | else: |
| 273 | - orderBy = ["-BuildFarmJob.date_finished"] |
| 274 | + orderBy = [Desc("BuildFarmJob.date_finished")] |
| 275 | |
| 276 | # Fallback to ordering by -id as a tie-breaker. |
| 277 | - orderBy.append("-id") |
| 278 | + orderBy.append(Desc("id")) |
| 279 | |
| 280 | # End of duplication (see XXX cprov 2006-09-25 above). |
| 281 | |
| 282 | - return BinaryPackageBuild.select(' AND '.join(condition_clauses), |
| 283 | - clauseTables=clauseTables, orderBy=orderBy) |
| 284 | + return IStore(BinaryPackageBuild).using(clauseTables).find( |
| 285 | + BinaryPackageBuild, *condition_clauses).order_by(*orderBy) |
| 286 | |
| 287 | @property |
| 288 | def latest_published_component(self): |
| 289 | |
| 290 | === modified file 'lib/lp/registry/tests/test_distroseries.py' |
| 291 | --- lib/lp/registry/tests/test_distroseries.py 2012-06-06 16:04:34 +0000 |
| 292 | +++ lib/lp/registry/tests/test_distroseries.py 2012-09-26 04:19:22 +0000 |
| 293 | @@ -9,7 +9,6 @@ |
| 294 | 'CurrentSourceReleasesMixin', |
| 295 | ] |
| 296 | |
| 297 | -from datetime import timedelta |
| 298 | from logging import getLogger |
| 299 | |
| 300 | import transaction |
| 301 | @@ -20,7 +19,6 @@ |
| 302 | from lp.registry.interfaces.distroseries import IDistroSeriesSet |
| 303 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
| 304 | from lp.registry.interfaces.series import SeriesStatus |
| 305 | -from lp.services.utils import utc_now |
| 306 | from lp.soyuz.enums import ( |
| 307 | ArchivePurpose, |
| 308 | PackagePublishingStatus, |
| 309 | @@ -281,36 +279,6 @@ |
| 310 | job = job_source.create(distroseries, [parent_distroseries.id]) |
| 311 | self.assertEqual(job, distroseries.getInitializationJob()) |
| 312 | |
| 313 | - def test_priorReleasedSeries(self): |
| 314 | - # Make sure that previousReleasedSeries returns all series with a |
| 315 | - # release date less than the contextual series, |
| 316 | - # ordered by descending date. |
| 317 | - distro = self.factory.makeDistribution() |
| 318 | - # Make an unreleased series. |
| 319 | - self.factory.makeDistroSeries(distribution=distro) |
| 320 | - ds1 = self.factory.makeDistroSeries(distribution=distro) |
| 321 | - ds2 = self.factory.makeDistroSeries(distribution=distro) |
| 322 | - ds3 = self.factory.makeDistroSeries(distribution=distro) |
| 323 | - ds4 = self.factory.makeDistroSeries(distribution=distro) |
| 324 | - |
| 325 | - now = utc_now() |
| 326 | - older = now - timedelta(days=5) |
| 327 | - oldest = now - timedelta(days=10) |
| 328 | - newer = now + timedelta(days=15) |
| 329 | - removeSecurityProxy(ds1).datereleased = oldest |
| 330 | - removeSecurityProxy(ds2).datereleased = older |
| 331 | - removeSecurityProxy(ds3).datereleased = now |
| 332 | - removeSecurityProxy(ds4).datereleased = newer |
| 333 | - |
| 334 | - # The data set up here is 5 distroseries. where one is unreleased, |
| 335 | - # ds1 and ds2 are released and in the past and ds4 is released but |
| 336 | - # in the future compared to ds3. |
| 337 | - |
| 338 | - prior = ds3.priorReleasedSeries() |
| 339 | - self.assertEqual( |
| 340 | - [ds2, ds1], |
| 341 | - list(prior)) |
| 342 | - |
| 343 | def test_getDifferenceComments_gets_DistroSeriesDifferenceComments(self): |
| 344 | distroseries = self.factory.makeDistroSeries() |
| 345 | dsd = self.factory.makeDistroSeriesDifference( |
| 346 | |
| 347 | === modified file 'lib/lp/soyuz/model/archive.py' |
| 348 | --- lib/lp/soyuz/model/archive.py 2012-09-21 07:02:26 +0000 |
| 349 | +++ lib/lp/soyuz/model/archive.py 2012-09-26 04:19:22 +0000 |
| 350 | @@ -1,8 +1,6 @@ |
| 351 | # Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
| 352 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 353 | |
| 354 | -# pylint: disable-msg=E0611,W0212 |
| 355 | - |
| 356 | """Database class for table Archive.""" |
| 357 | |
| 358 | __metaclass__ = type |
| 359 | @@ -10,6 +8,7 @@ |
| 360 | __all__ = [ |
| 361 | 'Archive', |
| 362 | 'ArchiveSet', |
| 363 | + 'get_archive_privacy_filter', |
| 364 | 'validate_ppa', |
| 365 | ] |
| 366 | |
| 367 | @@ -28,6 +27,7 @@ |
| 368 | And, |
| 369 | Desc, |
| 370 | Or, |
| 371 | + Not, |
| 372 | Select, |
| 373 | SQL, |
| 374 | Sum, |
| 375 | @@ -68,7 +68,10 @@ |
| 376 | validate_person, |
| 377 | ) |
| 378 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
| 379 | -from lp.registry.interfaces.role import IHasOwner |
| 380 | +from lp.registry.interfaces.role import ( |
| 381 | + IHasOwner, |
| 382 | + IPersonRoles, |
| 383 | + ) |
| 384 | from lp.registry.interfaces.series import SeriesStatus |
| 385 | from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet |
| 386 | from lp.registry.model.sourcepackagename import SourcePackageName |
| 387 | @@ -2574,3 +2577,18 @@ |
| 388 | ) |
| 389 | |
| 390 | return results.order_by(SourcePackagePublishingHistory.id) |
| 391 | + |
| 392 | + |
| 393 | +def get_archive_privacy_filter(user): |
| 394 | + if user is None: |
| 395 | + privacy_filter = Not(Archive._private) |
| 396 | + elif IPersonRoles(user).in_admin: |
| 397 | + privacy_filter = True |
| 398 | + else: |
| 399 | + privacy_filter = Or( |
| 400 | + Not(Archive._private), |
| 401 | + Archive.ownerID.is_in( |
| 402 | + Select( |
| 403 | + TeamParticipation.teamID, |
| 404 | + where=(TeamParticipation.person == user)))) |
| 405 | + return privacy_filter |
| 406 | |
| 407 | === modified file 'lib/lp/soyuz/model/binarypackagebuild.py' |
| 408 | --- lib/lp/soyuz/model/binarypackagebuild.py 2012-07-05 09:13:42 +0000 |
| 409 | +++ lib/lp/soyuz/model/binarypackagebuild.py 2012-09-26 04:19:22 +0000 |
| 410 | @@ -1,8 +1,6 @@ |
| 411 | # Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
| 412 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 413 | |
| 414 | -# pylint: disable-msg=E0611,W0212 |
| 415 | - |
| 416 | __metaclass__ = type |
| 417 | __all__ = [ |
| 418 | 'BinaryPackageBuild', |
| 419 | @@ -872,15 +870,9 @@ |
| 420 | |
| 421 | def preloadBuildsData(self, builds): |
| 422 | # Circular imports. |
| 423 | - from lp.soyuz.model.distroarchseries import ( |
| 424 | - DistroArchSeries |
| 425 | - ) |
| 426 | - from lp.registry.model.distroseries import ( |
| 427 | - DistroSeries |
| 428 | - ) |
| 429 | - from lp.registry.model.distribution import ( |
| 430 | - Distribution |
| 431 | - ) |
| 432 | + from lp.soyuz.model.distroarchseries import DistroArchSeries |
| 433 | + from lp.registry.model.distroseries import DistroSeries |
| 434 | + from lp.registry.model.distribution import Distribution |
| 435 | from lp.soyuz.model.archive import Archive |
| 436 | from lp.registry.model.person import Person |
| 437 | self._prefetchBuildData(builds) |
| 438 | @@ -926,15 +918,15 @@ |
| 439 | BuildFarmJob.status == BuildStatus.NEEDSBUILD) |
| 440 | |
| 441 | def handleOptionalParamsForBuildQueries( |
| 442 | - self, queries, tables, status=None, name=None, pocket=None, |
| 443 | + self, clauses, origin, status=None, name=None, pocket=None, |
| 444 | arch_tag=None): |
| 445 | """Construct query clauses needed/shared by all getBuild..() methods. |
| 446 | |
| 447 | This method is not exposed via the public interface as it is only |
| 448 | used to DRY-up trusted code. |
| 449 | |
| 450 | - :param queries: container to which to add any resulting query clauses. |
| 451 | - :param tables: container to which to add joined tables. |
| 452 | + :param clauses: container to which to add any resulting query clauses. |
| 453 | + :param origin: container to which to add joined tables. |
| 454 | :param status: optional build state for which to add a query clause if |
| 455 | present. |
| 456 | :param name: optional source package release name (or list of source |
| 457 | @@ -945,112 +937,96 @@ |
| 458 | :param arch_tag: optional architecture tag for which to add a |
| 459 | query clause if present. |
| 460 | """ |
| 461 | + # Circular. :( |
| 462 | + from lp.registry.model.sourcepackagename import SourcePackageName |
| 463 | + from lp.soyuz.model.distroarchseries import DistroArchSeries |
| 464 | + from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease |
| 465 | |
| 466 | # Ensure the underlying buildfarmjob and package build tables |
| 467 | # are included. |
| 468 | - queries.append('BinaryPackageBuild.package_build = PackageBuild.id') |
| 469 | - queries.append('PackageBuild.build_farm_job = BuildFarmJob.id') |
| 470 | - tables.extend(['PackageBuild', 'BuildFarmJob']) |
| 471 | + clauses.extend([ |
| 472 | + BinaryPackageBuild.package_build == PackageBuild.id, |
| 473 | + PackageBuild.build_farm_job == BuildFarmJob.id]) |
| 474 | + origin.extend([BinaryPackageBuild, BuildFarmJob]) |
| 475 | |
| 476 | # Add query clause that filters on build state if the latter is |
| 477 | # provided. |
| 478 | if status is not None: |
| 479 | - queries.append('BuildFarmJob.status=%s' % sqlvalues(status)) |
| 480 | + clauses.append(BuildFarmJob.status == status) |
| 481 | |
| 482 | # Add query clause that filters on pocket if the latter is provided. |
| 483 | if pocket: |
| 484 | if not isinstance(pocket, (list, tuple)): |
| 485 | pocket = (pocket,) |
| 486 | - |
| 487 | - queries.append('PackageBuild.pocket IN %s' % sqlvalues(pocket)) |
| 488 | + clauses.append(PackageBuild.pocket.is_in(pocket)) |
| 489 | |
| 490 | # Add query clause that filters on architecture tag if provided. |
| 491 | if arch_tag is not None: |
| 492 | - queries.append(''' |
| 493 | - BinaryPackageBuild.distro_arch_series = DistroArchSeries.id |
| 494 | - AND DistroArchSeries.architecturetag = %s |
| 495 | - ''' % sqlvalues(arch_tag)) |
| 496 | - tables.extend(['DistroArchSeries']) |
| 497 | + clauses.extend([ |
| 498 | + BinaryPackageBuild.distro_arch_series_id == |
| 499 | + DistroArchSeries.id, |
| 500 | + DistroArchSeries.architecturetag == arch_tag]) |
| 501 | + origin.append(DistroArchSeries) |
| 502 | |
| 503 | # Add query clause that filters on source package release name if the |
| 504 | # latter is provided. |
| 505 | if name is not None: |
| 506 | + clauses.extend( |
| 507 | + [BinaryPackageBuild.source_package_release_id == |
| 508 | + SourcePackageRelease.id, |
| 509 | + SourcePackageRelease.sourcepackagenameID == |
| 510 | + SourcePackageName.id]) |
| 511 | + origin.extend([SourcePackageRelease, SourcePackageName]) |
| 512 | if not isinstance(name, (list, tuple)): |
| 513 | - queries.append(''' |
| 514 | - BinaryPackageBuild.source_package_release = |
| 515 | - SourcePackageRelease.id AND |
| 516 | - SourcePackageRelease.sourcepackagename = |
| 517 | - SourcePackageName.id |
| 518 | - AND SourcepackageName.name LIKE '%%%%' || %s || '%%%%' |
| 519 | - ''' % quote_like(name)) |
| 520 | + clauses.append( |
| 521 | + "SourcepackageName.name LIKE '%%%%' || %s || '%%%%'" % ( |
| 522 | + quote_like(name))) |
| 523 | else: |
| 524 | - queries.append(''' |
| 525 | - BinaryPackageBuild.source_package_release = |
| 526 | - SourcePackageRelease.id AND |
| 527 | - SourcePackageRelease.sourcepackagename = |
| 528 | - SourcePackageName.id |
| 529 | - AND SourcepackageName.name IN %s |
| 530 | - ''' % sqlvalues(name)) |
| 531 | - tables.extend(['SourcePackageRelease', 'SourcePackageName']) |
| 532 | + clauses.append(SourcePackageName.name.is_in(name)) |
| 533 | |
| 534 | def getBuildsForBuilder(self, builder_id, status=None, name=None, |
| 535 | arch_tag=None, user=None): |
| 536 | """See `IBinaryPackageBuildSet`.""" |
| 537 | - queries = [] |
| 538 | - clauseTables = [] |
| 539 | + # Circular. :( |
| 540 | + from lp.soyuz.model.archive import ( |
| 541 | + Archive, get_archive_privacy_filter) |
| 542 | + |
| 543 | + clauses = [ |
| 544 | + PackageBuild.archive_id == Archive.id, |
| 545 | + BuildFarmJob.builder_id == builder_id, |
| 546 | + get_archive_privacy_filter(user)] |
| 547 | + origin = [PackageBuild, Archive] |
| 548 | |
| 549 | self.handleOptionalParamsForBuildQueries( |
| 550 | - queries, clauseTables, status, name, pocket=None, |
| 551 | - arch_tag=arch_tag) |
| 552 | - |
| 553 | - # This code MUST match the logic in the Build security adapter, |
| 554 | - # otherwise users are likely to get 403 errors, or worse. |
| 555 | - queries.append("Archive.id = PackageBuild.archive") |
| 556 | - clauseTables.append('Archive') |
| 557 | - if user is not None: |
| 558 | - if not user.inTeam(getUtility(ILaunchpadCelebrities).admin): |
| 559 | - queries.append(""" |
| 560 | - (Archive.private = FALSE |
| 561 | - OR %s IN (SELECT TeamParticipation.person |
| 562 | - FROM TeamParticipation |
| 563 | - WHERE TeamParticipation.person = %s |
| 564 | - AND TeamParticipation.team = Archive.owner) |
| 565 | - )""" % sqlvalues(user, user)) |
| 566 | - else: |
| 567 | - queries.append("Archive.private = FALSE") |
| 568 | - |
| 569 | - queries.append("builder=%s" % builder_id) |
| 570 | - |
| 571 | - return BinaryPackageBuild.select( |
| 572 | - " AND ".join(queries), clauseTables=clauseTables, |
| 573 | - orderBy=["-BuildFarmJob.date_finished", "id"]) |
| 574 | + clauses, origin, status, name, pocket=None, arch_tag=arch_tag) |
| 575 | + |
| 576 | + return IStore(BinaryPackageBuild).using(*origin).find( |
| 577 | + BinaryPackageBuild, *clauses).order_by( |
| 578 | + Desc(BuildFarmJob.date_finished), BinaryPackageBuild.id) |
| 579 | |
| 580 | def getBuildsForArchive(self, archive, status=None, name=None, |
| 581 | pocket=None, arch_tag=None): |
| 582 | """See `IBinaryPackageBuildSet`.""" |
| 583 | - queries = [] |
| 584 | - clauseTables = [] |
| 585 | + clauses = [PackageBuild.archive_id == archive.id] |
| 586 | + origin = [PackageBuild] |
| 587 | |
| 588 | self.handleOptionalParamsForBuildQueries( |
| 589 | - queries, clauseTables, status, name, pocket, arch_tag) |
| 590 | + clauses, origin, status, name, pocket, arch_tag) |
| 591 | |
| 592 | # Ordering according status |
| 593 | # * SUPERSEDED & All by -datecreated |
| 594 | # * FULLYBUILT & FAILURES by -datebuilt |
| 595 | # It should present the builds in a more natural order. |
| 596 | if status == BuildStatus.SUPERSEDED or status is None: |
| 597 | - orderBy = ["-BuildFarmJob.date_created"] |
| 598 | + orderBy = [Desc(BuildFarmJob.date_created)] |
| 599 | else: |
| 600 | - orderBy = ["-BuildFarmJob.date_finished"] |
| 601 | + orderBy = [Desc(BuildFarmJob.date_finished)] |
| 602 | # All orders fallback to id if the primary order doesn't succeed |
| 603 | - orderBy.append("id") |
| 604 | - |
| 605 | - queries.append("archive=%s" % sqlvalues(archive)) |
| 606 | - clause = " AND ".join(queries) |
| 607 | + orderBy.append(BinaryPackageBuild.id) |
| 608 | |
| 609 | return self._decorate_with_prejoins( |
| 610 | - BinaryPackageBuild.select( |
| 611 | - clause, clauseTables=clauseTables, orderBy=orderBy)) |
| 612 | + IStore(BinaryPackageBuild).using(*origin).find( |
| 613 | + BinaryPackageBuild, *clauses).order_by(*orderBy)) |
| 614 | |
| 615 | def getBuildsByArchIds(self, distribution, arch_ids, status=None, |
| 616 | name=None, pocket=None): |
| 617 | @@ -1059,7 +1035,7 @@ |
| 618 | if not arch_ids: |
| 619 | return EmptyResultSet() |
| 620 | |
| 621 | - clauseTables = [] |
| 622 | + clauseTables = [PackageBuild] |
| 623 | |
| 624 | # format clause according single/multiple architecture(s) form |
| 625 | if len(arch_ids) == 1: |
| 626 | @@ -1124,9 +1100,7 @@ |
| 627 | "PackageBuild.archive IN %s" % |
| 628 | sqlvalues(list(distribution.all_distro_archive_ids))) |
| 629 | |
| 630 | - store = Store.of(distribution) |
| 631 | - clauseTables = [BinaryPackageBuild] + clauseTables |
| 632 | - result_set = store.using(*clauseTables).find( |
| 633 | + result_set = Store.of(distribution).using(*clauseTables).find( |
| 634 | (BinaryPackageBuild, order_by_table), *condition_clauses) |
| 635 | result_set.order_by(*order_by) |
| 636 |

78 +def get_archive_ privacy_ filter( user): _private) , ownerID. is_in( on.teamID, TeamParticipati on.person == user)))]
79 + return [
80 + Not(Archive.
81 + Archive.
82 + Select(
83 + TeamParticipati
84 + where=(
The indentation here is wrong, and it might be better to just say Or() rather than returning a list.
174 + clauses.extend( uild.package_ build == PackageBuild.id, build_farm_ job == BuildFarmJob.id])
175 + [BinaryPackageB
176 + PackageBuild.
The opening square bracket should probably be on the previous line.
221 - AND SourcepackageNa me.name LIKE '%%%%' || %s || '%%%%' append( SourcePackageNa me.name. like(name) )
222 - ''' % quote_like(name))
223 + clauses.
These aren't equivalent. You need to use quote_like and wrap it in % to get a substring match; see Distribution. searchSourcePac kageCaches' s LIKE stuff for an example of hacking around Storm. There's also another instance of this in the following block.
274 + if user is None: append( Not(Archive. _private) ) user).in_ admin: append( *get_archive_ privacy_ filter( user))
275 + clauses.
276 + elif not IPersonRoles(
277 + clauses.
Shouldn't this be in get_archive_ privacy_ filter?
279 + clauses. append( BuildFarmJob. builder_ id == builder_id)
Can you put this in the initial clauses?
288 - queries = []
289 - clauseTables = []
290 + clauses = []
291 + origin = [PackageBuild]
Why the new table?