60
60
from lp.answers.model.answercontact import AnswerContact
61
61
from lp.bugs.interfaces.bug import IBugSet
62
from lp.bugs.interfaces.bugtask import (
62
66
from lp.bugs.model.bug import Bug
63
67
from lp.bugs.model.bugattachment import BugAttachment
64
68
from lp.bugs.model.bugnotification import BugNotification
69
from lp.bugs.model.bugtask import BugTask
65
70
from lp.bugs.model.bugwatch import BugWatchActivity
66
71
from lp.bugs.scripts.checkwatches.scheduler import (
808
813
transaction.commit()
816
class BugTaskIncompleteMigrator(TunableLoop):
817
"""Migrate BugTaskStatus 'INCOMPLETE' to a concrete WITH/WITHOUT value."""
819
maximum_chunk_size = 20000
820
minimum_chunk_size = 100
822
def __init__(self, log, abort_time=None, max_heat_age=None):
823
super(BugTaskIncompleteMigrator, self).__init__(log, abort_time)
824
self.transaction = transaction
825
self.total_processed = 0
828
self.store = IMasterStore(BugTask)
829
self.query = self.store.find(
831
BugTask._status == BugTaskStatus.INCOMPLETE,
832
BugTask.bugID == Bug.id)
835
"""See `ITunableLoop`."""
836
return self.query.is_empty()
838
def __call__(self, chunk_size):
839
"""See `ITunableLoop`."""
841
tasks = list(self.query[:chunk_size])
842
for (task, bug) in tasks:
843
if (bug.date_last_message is None or
844
task.date_incomplete > bug.date_last_message):
845
task._status = BugTaskStatusSearch.INCOMPLETE_WITHOUT_RESPONSE
847
task._status = BugTaskStatusSearch.INCOMPLETE_WITH_RESPONSE
848
self.log.debug("Updated status on %d tasks" % len(tasks))
811
852
class BugWatchActivityPruner(BulkPruner):
812
853
"""A TunableLoop to prune BugWatchActivity entries."""
813
854
target_table_class = BugWatchActivity
1270
1311
BugHeatUpdater,
1271
1312
SourcePackagePublishingHistorySPNPopulator,
1272
1313
BinaryPackagePublishingHistoryBPNPopulator,
1314
BugTaskIncompleteMigrator,
1274
1316
experimental_tunable_loops = []