1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#!/usr/bin/python -S
#
# Copyright 2009 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
# pylint: disable-msg=W0403
# (Suppressing pylint "relative import" warning 0403 for _pythonpath)
import _pythonpath
from zope.interface import implements
from canonical.database.postgresql import drop_tables
from canonical.database.sqlbase import (
cursor, quote, quote_identifier, sqlvalues)
from canonical.launchpad.interfaces.looptuner import ITunableLoop
from lp.services.scripts.base import LaunchpadScript
from canonical.launchpad.utilities.looptuner import DBLoopTuner
class ShareJauntyTranslationMessages:
"""`ITunableLoop` to share Jaunty TranslationMessages."""
implements(ITunableLoop)
def __init__(self, txn, logger, flag, seriesname):
self.txn = txn
self.logger = logger
self.last_id = 0
cur = cursor()
cur.execute("""
SELECT DistroSeries.id
FROM DistroSeries
JOIN Distribution ON Distribution.id = DistroSeries.distribution
WHERE
Distribution.name = 'ubuntu' AND DistroSeries.name = %s
""" % quote(seriesname))
self.series_id = cur.fetchone()
substitutions = {
'flag': quote_identifier(flag),
'series_id': quote(self.series_id),
}
cur.execute("""
SELECT DISTINCT Candidate.id
INTO TEMP TABLE temp_todo
FROM TranslationMessage Candidate
JOIN POTemplate ON Candidate.potemplate = POTemplate.id
LEFT JOIN TranslationMessage AS FlagHolder ON
FlagHolder.%(flag)s IS TRUE AND
FlagHolder.potmsgset = Candidate.potmsgset AND
FlagHolder.potemplate IS NULL AND
FlagHolder.language = Candidate.language
WHERE
POTemplate.distroseries = %(series_id)s AND
POTemplate.iscurrent IS TRUE AND
Candidate.%(flag)s IS TRUE AND
FlagHolder.id IS NULL
ORDER BY id
""" % substitutions)
cur.execute(
"CREATE UNIQUE INDEX temp_todo__pkey ON temp_todo(id)")
cur.execute("ANALYZE temp_todo(id)")
cur.execute("SELECT max(id) FROM temp_todo")
max_id, = cur.fetchone()
if max_id is None:
self.finish_id = 0
else:
self.finish_id = max_id + 1
def isDone(self):
"""See `ITunableLoop`."""
done = (self.last_id >= self.finish_id)
if done:
drop_tables(cursor(), 'temp_todo')
return done
def __call__(self, chunk_size):
"""See `ITunableLoop`."""
chunk_size = int(chunk_size)
cur = cursor()
cur.execute("""
SELECT id
FROM temp_todo
WHERE id >= %s
ORDER BY id
OFFSET %s
LIMIT 1
""" % sqlvalues(self.last_id, chunk_size))
batch_limit = cur.fetchone()
if batch_limit is None:
end_id = self.finish_id
else:
end_id, = batch_limit
cur.execute("""
UPDATE TranslationMessage
SET potemplate = NULL
WHERE id IN (
SELECT id
FROM temp_todo
WHERE id >= %s AND id < %s
)
""" % sqlvalues(self.last_id, end_id))
self.logger.info(
"Updated %d rows: %d - %d." % (
cur.rowcount, self.last_id, end_id))
self.txn.commit()
self.txn.begin()
self.last_id = end_id
class ShareJauntyTranslationsScript(LaunchpadScript):
def main(self):
series = 'jaunty'
self.logger.info("Making '%s' TranslationMessages shared." % series)
for flag in ('is_current', 'is_imported'):
self.logger.info("Sharing %s messages." % flag)
loop = ShareJauntyTranslationMessages(
self.txn, self.logger, flag, series)
DBLoopTuner(loop, 5, log=self.logger).run()
if __name__ == '__main__':
script = ShareJauntyTranslationsScript(
'rosetta.scripts.share-jaunty-translations')
script.run()
|