19
19
from lazr.enum import DBItem
20
20
from sqlobject import StringCol
21
from storm.exceptions import NotOneError
21
22
from storm.expr import (
23
25
compile as storm_compile,
27
from storm.info import ClassAlias
28
30
from storm.locals import (
61
64
from lp.registry.interfaces.distroseriesdifferencecomment import (
62
65
IDistroSeriesDifferenceCommentSource,
67
from lp.registry.interfaces.distroseriesparent import IDistroSeriesParentSet
64
68
from lp.registry.interfaces.person import IPersonSet
65
69
from lp.registry.model.distroseries import DistroSeries
66
70
from lp.registry.model.distroseriesdifferencecomment import (
100
105
:param in_parent: A boolean indicating if we should look in the parent
101
106
series' archive instead of the derived series' archive.
103
distinct_on = "DistroSeriesDifference.source_package_name"
105
# XXX: GavinPanella 2010-04-06 bug=374777: This SQL(...) is a hack; it
106
# does not seem to be possible to express DISTINCT ON with Storm.
107
SQL("DISTINCT ON (%s) 0 AS ignore" % distinct_on),
108
109
DistroSeriesDifference.source_package_name_id,
109
110
SourcePackagePublishingHistory,
111
112
conditions = And(
112
113
DistroSeriesDifference.id.is_in(dsd.id for dsd in dsds),
113
DistroSeries.id == DistroSeriesDifference.derived_series_id,
114
114
SourcePackagePublishingHistory.archiveID == Archive.id,
115
115
SourcePackagePublishingHistory.sourcepackagereleaseID == (
116
116
SourcePackageRelease.id),
121
121
# Check in the parent archive or the child?
123
ParentDistroSeries = ClassAlias(DistroSeries)
124
123
conditions = And(
126
ParentDistroSeries.id == DistroSeries.parent_seriesID,
127
Archive.distributionID == ParentDistroSeries.distributionID,
125
DistroSeries.id == DistroSeriesDifference.parent_series_id,
126
Archive.distributionID == DistroSeries.distributionID,
128
127
Archive.purpose == ArchivePurpose.PRIMARY,
131
130
conditions = And(
132
DistroSeries.id == DistroSeriesDifference.derived_series_id,
133
133
Archive.distributionID == DistroSeries.distributionID,
134
134
Archive.purpose == ArchivePurpose.PRIMARY,
149
149
DistroSeriesDifference.source_package_name_id,
150
150
Desc(SourcePackagePublishingHistory.id),
153
DistroSeriesDifference.source_package_name_id,
152
155
store = IStore(SourcePackagePublishingHistory)
153
results = store.find(columns, conditions).order_by(*order_by)
154
return DecoratedResultSet(results, itemgetter(1, 2))
157
columns, conditions).order_by(*order_by).config(distinct=distinct_on)
157
160
def most_recent_comments(dsds):
163
166
:param dsds: An iterable of `DistroSeriesDifference` instances.
165
distinct_on = storm_compile(
166
DistroSeriesDifferenceComment.distro_series_difference_id)
168
# XXX: GavinPanella 2010-04-06 bug=374777: This SQL(...) is a
169
# hack; it does not seem to be possible to express DISTINCT ON
171
SQL("DISTINCT ON (%s) 0 AS ignore" % distinct_on),
172
169
DistroSeriesDifferenceComment,
180
177
DistroSeriesDifferenceComment.distro_series_difference_id,
181
178
Desc(DistroSeriesDifferenceComment.id),
181
DistroSeriesDifferenceComment.distro_series_difference_id,
183
183
store = IStore(DistroSeriesDifferenceComment)
184
comments = store.find(columns, conditions).order_by(*order_by)
185
return DecoratedResultSet(comments, itemgetter(1))
184
comments = store.find(
185
columns, conditions).order_by(*order_by).config(distinct=distinct_on)
186
return DecoratedResultSet(comments, itemgetter(0))
189
def packagesets(dsds, in_parent):
190
"""Return the packagesets for the given dsds inside the parent or
191
the derived `DistroSeries`.
193
Returns a dict with the corresponding packageset list for each dsd id.
195
:param dsds: An iterable of `DistroSeriesDifference` instances.
196
:param in_parent: A boolean indicating if we should look in the parent
197
series' archive instead of the derived series' archive.
202
PackagesetSources = Table("PackageSetSources")
203
FlatPackagesetInclusion = Table("FlatPackagesetInclusion")
205
tables = IStore(Packageset).using(
206
DistroSeriesDifference, Packageset,
207
PackagesetSources, FlatPackagesetInclusion)
208
results = tables.find(
209
(DistroSeriesDifference.id, Packageset),
210
Column("packageset", PackagesetSources) == (
211
Column("child", FlatPackagesetInclusion)),
212
Packageset.distroseries_id == (
213
DistroSeriesDifference.parent_series_id if in_parent else
214
DistroSeriesDifference.derived_series_id),
215
Column("parent", FlatPackagesetInclusion) == Packageset.id,
216
Column("sourcepackagename", PackagesetSources) == (
217
DistroSeriesDifference.source_package_name_id),
218
DistroSeriesDifference.id.is_in(dsd.id for dsd in dsds))
219
results = results.order_by(
220
Column("sourcepackagename", PackagesetSources),
224
for dsd_id, packageset in results:
225
if dsd_id in grouped:
226
grouped[dsd_id].append(packageset)
228
grouped[dsd_id] = [packageset]
188
233
class DistroSeriesDifference(StormBase):
197
242
derived_series = Reference(
198
243
derived_series_id, 'DistroSeries.id')
245
parent_series_id = Int(name='parent_series', allow_none=False)
246
parent_series = Reference(parent_series_id, 'DistroSeries.id')
200
248
source_package_name_id = Int(
201
249
name='source_package_name', allow_none=False)
202
250
source_package_name = Reference(
222
270
base_version = StringCol(dbName='base_version', notNull=False)
225
def new(derived_series, source_package_name):
273
def new(derived_series, source_package_name, parent_series=None):
226
274
"""See `IDistroSeriesDifferenceSource`."""
227
if not derived_series.is_derived_series:
228
raise NotADerivedSeriesError()
275
if parent_series is None:
277
dsps = getUtility(IDistroSeriesParentSet)
278
dsp = dsps.getByDerivedSeries(
279
derived_series).one()
281
raise MultipleParentsForDerivedSeriesError()
284
raise NotADerivedSeriesError()
286
parent_series = dsp.parent_series
230
288
store = IMasterStore(DistroSeriesDifference)
231
289
diff = DistroSeriesDifference()
232
290
diff.derived_series = derived_series
291
diff.parent_series = parent_series
233
292
diff.source_package_name = source_package_name
235
294
# The status and type is set to default values - they will be
244
303
def getForDistroSeries(
246
difference_type=DistroSeriesDifferenceType.DIFFERENT_VERSIONS,
305
difference_type=None,
247
306
source_package_name_filter=None,
249
child_version_higher=False):
308
child_version_higher=False,
250
310
"""See `IDistroSeriesDifferenceSource`."""
311
if difference_type is None:
312
difference_type = DistroSeriesDifferenceType.DIFFERENT_VERSIONS
251
313
if status is None:
253
315
DistroSeriesDifferenceStatus.NEEDS_ATTENTION,
313
379
parent_source_pubs_for_release.itervalues()),
314
380
("sourcepackagereleaseID",))
382
# Get packagesets and parent_packagesets for each DSD.
383
dsd_packagesets = packagesets(dsds, in_parent=False)
384
dsd_parent_packagesets = packagesets(dsds, in_parent=True)
317
387
spn_id = dsd.source_package_name_id
318
388
cache = get_property_cache(dsd)
319
389
cache.source_pub = source_pubs.get(spn_id)
320
390
cache.parent_source_pub = parent_source_pubs.get(spn_id)
391
cache.packagesets = dsd_packagesets.get(dsd.id)
392
cache.parent_packagesets = dsd_parent_packagesets.get(dsd.id)
321
393
if spn_id in source_pubs_for_release:
322
394
spph = source_pubs_for_release[spn_id]
323
395
cache.source_package_release = (
330
402
spph = parent_source_pubs_for_release[spn_id]
331
403
cache.parent_source_package_release = (
332
404
DistroSeriesSourcePackageRelease(
333
dsd.derived_series.parent_series,
334
spph.sourcepackagerelease))
405
dsd.parent_series, spph.sourcepackagerelease))
336
407
cache.parent_source_package_release = None
337
408
cache.latest_comment = latest_comment_by_dsd_id.get(dsd.id)
364
435
differences, pre_iter_hook=eager_load)
367
def getByDistroSeriesAndName(distro_series, source_package_name):
438
def getByDistroSeriesNameAndParentSeries(distro_series,
368
441
"""See `IDistroSeriesDifferenceSource`."""
369
443
return IStore(DistroSeriesDifference).find(
370
444
DistroSeriesDifference,
371
445
DistroSeriesDifference.derived_series == distro_series,
446
DistroSeriesDifference.parent_series == parent_series,
372
447
DistroSeriesDifference.source_package_name == (
373
448
SourcePackageName.id),
374
449
SourcePackageName.name == source_package_name).one()
452
def getSimpleUpgrades(distro_series):
453
"""See `IDistroSeriesDifferenceSource`.
455
Eager-load related `ISourcePackageName` records.
457
differences = IStore(DistroSeriesDifference).find(
458
(DistroSeriesDifference, SourcePackageName),
459
DistroSeriesDifference.derived_series == distro_series,
460
DistroSeriesDifference.difference_type ==
461
DistroSeriesDifferenceType.DIFFERENT_VERSIONS,
462
DistroSeriesDifference.status ==
463
DistroSeriesDifferenceStatus.NEEDS_ATTENTION,
464
DistroSeriesDifference.parent_source_version !=
465
DistroSeriesDifference.base_version,
466
DistroSeriesDifference.source_version ==
467
DistroSeriesDifference.base_version,
468
SourcePackageName.id ==
469
DistroSeriesDifference.source_package_name_id)
470
return DecoratedResultSet(differences, itemgetter(0))
473
def collateDifferencesByParentArchive(differences):
475
for difference in differences:
476
archive = difference.parent_series.main_archive
477
if archive in by_archive:
478
by_archive[archive].append(difference)
480
by_archive[archive] = [difference]
377
484
def source_pub(self):
378
485
"""See `IDistroSeriesDifference`."""
387
494
"""Helper to keep source_pub/parent_source_pub DRY."""
388
495
distro_series = self.derived_series
390
distro_series = self.derived_series.parent_series
497
distro_series = self.parent_series
392
499
pubs = distro_series.getPublishedSources(
393
500
self.source_package_name, include_pending=True)
402
509
def base_source_pub(self):
403
510
"""See `IDistroSeriesDifference`."""
404
511
if self.base_version is not None:
405
parent = self.derived_series.parent_series
512
parent = self.parent_series
406
513
result = parent.main_archive.getPublishedSources(
407
514
name=self.source_package_name.name,
408
515
version=self.base_version).first()
426
533
"""See `IDistroSeriesDifference`."""
427
parent_name = self.derived_series.parent_series.displayname
534
parent_name = self.parent_series.displayname
428
535
return ("Difference between distroseries '%(parent_name)s' and "
429
536
"'%(derived_name)s' for package '%(pkg_name)s' "
430
537
"(%(parent_version)s/%(source_version)s)" % {
469
576
"""See `IDistroSeriesDifference`."""
470
577
return self._getPackageDiffURL(self.parent_package_diff)
472
def getPackageSets(self):
580
def packagesets(self):
473
581
"""See `IDistroSeriesDifference`."""
474
582
if self.derived_series is not None:
475
return getUtility(IPackagesetSet).setsIncludingSource(
476
self.source_package_name, self.derived_series)
583
return list(getUtility(IPackagesetSet).setsIncludingSource(
584
self.source_package_name, self.derived_series))
480
def getParentPackageSets(self):
589
def parent_packagesets(self):
481
590
"""See `IDistroSeriesDifference`."""
482
has_parent_series = self.derived_series is not None and (
483
self.derived_series.parent_series is not None)
484
if has_parent_series:
485
return getUtility(IPackagesetSet).setsIncludingSource(
486
self.source_package_name,
487
self.derived_series.parent_series)
591
return list(getUtility(IPackagesetSet).setsIncludingSource(
592
self.source_package_name, self.parent_series))
492
595
def package_diff_status(self):
508
611
def parent_source_package_release(self):
509
612
return self._package_release(
510
self.derived_series.parent_series,
511
self.parent_source_version)
613
self.parent_series, self.parent_source_version)
514
616
def source_package_release(self):
515
617
return self._package_release(
618
self.derived_series, self.source_version)
519
620
def _package_release(self, distro_series, version):