1
# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
1
# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
2
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
4
"""Database garbage collection."""
35
35
from zope.component import getUtility
36
36
from zope.security.proxy import removeSecurityProxy
38
from lp.services.config import config
39
from canonical.database import postgresql
40
from canonical.database.constants import UTC_NOW
41
from canonical.database.sqlbase import (
46
from lp.services.webapp.interfaces import (
38
51
from lp.answers.model.answercontact import AnswerContact
39
52
from lp.bugs.interfaces.bug import IBugSet
40
53
from lp.bugs.model.bug import Bug
55
68
from lp.hardwaredb.model.hwdb import HWSubmission
56
69
from lp.registry.model.person import Person
57
from lp.services.config import config
58
from lp.services.database import postgresql
59
from lp.services.database.constants import UTC_NOW
60
70
from lp.services.database.lpstorm import IMasterStore
61
from lp.services.database.sqlbase import (
66
71
from lp.services.identity.interfaces.account import AccountStatus
67
72
from lp.services.identity.interfaces.emailaddress import EmailAddressStatus
68
from lp.services.identity.model.account import Account
69
73
from lp.services.identity.model.emailaddress import EmailAddress
70
74
from lp.services.job.model.job import Job
71
75
from lp.services.librarian.model import TimeLimitedToken
82
86
from lp.services.session.model import SessionData
83
87
from lp.services.verification.model.logintoken import LoginToken
84
from lp.services.webapp.interfaces import (
89
from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
90
88
from lp.translations.interfaces.potemplate import IPOTemplateSet
91
89
from lp.translations.model.potmsgset import POTMsgSet
92
90
from lp.translations.model.potranslation import POTranslation
315
class AccountOnlyEmailAddressPruner(BulkPruner):
316
"""Remove EmailAddress records not linked to a Person."""
317
target_table_class = EmailAddress
318
ids_to_prune_query = "SELECT id FROM EmailAddress WHERE person IS NULL"
321
class UnlinkedAccountPruner(BulkPruner):
322
"""Remove Account records not linked to a Person."""
323
target_table_class = Account
324
# We join with EmailAddress to ensure we only attempt removal after
325
# the EmailAddress rows have been removed by
326
# AccountOnlyEmailAddressPruner. We join with Person to work around
327
# records with bad crosslinks. These bad crosslinks will be fixed by
328
# dropping the EmailAddress.account column.
329
ids_to_prune_query = """
332
LEFT OUTER JOIN EmailAddress ON Account.id = EmailAddress.account
333
LEFT OUTER JOIN Person ON Account.id = Person.account
335
EmailAddress.id IS NULL
336
AND Person.id IS NULL
340
313
class BugSummaryJournalRollup(TunableLoop):
341
314
"""Rollup BugSummaryJournal rows into BugSummary."""
342
315
maximum_chunk_size = 5000
902
875
self._update_oldest()
905
class SourcePackageReleaseDscBinariesUpdater(TunableLoop):
906
"""Fix incorrect values for SourcePackageRelease.dsc_binaries."""
908
maximum_chunk_size = 1000
910
def __init__(self, log, abort_time=None):
911
super(SourcePackageReleaseDscBinariesUpdater, self).__init__(
913
self.store = IMasterStore(SourcePackageRelease)
916
SourcePackageRelease.id,
917
# Get all SPR IDs which have an incorrectly-separated
918
# dsc_binaries value (space rather than comma-space).
919
SQL("dsc_binaries ~ '[a-z0-9+.-] '"),
920
# Skip rows with dsc_binaries in dependency relationship
921
# format. This is a different bug.
922
SQL("dsc_binaries NOT LIKE '%(%'")))
925
"""See `TunableLoop`."""
926
return len(self.ids) == 0
928
def __call__(self, chunk_size):
929
"""See `TunableLoop`."""
930
chunk_size = int(chunk_size + 0.5)
931
chunk_ids = self.ids[:chunk_size]
932
del self.ids[:chunk_size]
933
self.store.execute("""
934
UPDATE SourcePackageRelease
935
SET dsc_binaries = regexp_replace(
936
dsc_binaries, '([a-z0-9+.-]) ', E'\\\\1, ', 'g')
937
WHERE id IN %s""" % sqlvalues(chunk_ids), noresult=True)
941
878
class SuggestiveTemplatesCacheUpdater(TunableLoop):
942
879
"""Refresh the SuggestivePOTemplate cache.
1302
1239
ObsoleteBugAttachmentPruner,
1303
1240
OldTimeLimitedTokenDeleter,
1304
1241
RevisionAuthorEmailLinker,
1305
SourcePackageReleaseDscBinariesUpdater,
1306
1242
SuggestiveTemplatesCacheUpdater,
1307
1243
POTranslationPruner,
1308
1244
UnusedPOTMsgSetPruner,
1309
AccountOnlyEmailAddressPruner,
1310
UnlinkedAccountPruner,
1312
1246
experimental_tunable_loops = [