launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #04493
[Merge] lp:~stub/launchpad/staging into lp:launchpad
Stuart Bishop has proposed merging lp:~stub/launchpad/staging into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #798120 in Launchpad itself: "security.py --no-revoke probably shouldn't change object ownership"
https://bugs.launchpad.net/launchpad/+bug/798120
Bug #809123 in Launchpad itself: "we cannot deploy DB schema changes live"
https://bugs.launchpad.net/launchpad/+bug/809123
For more details, see:
https://code.launchpad.net/~stub/launchpad/staging/+merge/70568
= Summary =
If replication is broken, further preflight checks are not attempted.
== Proposed fix ==
Allow callsites to override abort behavior of database.replication.helpers.sync
--
https://code.launchpad.net/~stub/launchpad/staging/+merge/70568
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stub/launchpad/staging into lp:launchpad.
=== modified file 'cronscripts/generate-contents-files.py'
--- cronscripts/generate-contents-files.py 2011-07-11 13:33:13 +0000
+++ cronscripts/generate-contents-files.py 2011-08-05 13:36:41 +0000
@@ -7,7 +7,6 @@
import _pythonpath
-from canonical.config import config
from lp.archivepublisher.scripts.generate_contents_files import (
GenerateContentsFiles,
)
@@ -15,5 +14,5 @@
if __name__ == '__main__':
script = GenerateContentsFiles(
- "generate-contents", dbuser=config.archivepublisher.dbuser)
+ "generate-contents", dbuser='generate_contents_files')
script.lock_and_run()
=== modified file 'cronscripts/publish-ftpmaster.py'
--- cronscripts/publish-ftpmaster.py 2011-03-31 06:29:09 +0000
+++ cronscripts/publish-ftpmaster.py 2011-08-05 13:36:41 +0000
@@ -7,11 +7,10 @@
import _pythonpath
-from canonical.config import config
from lp.archivepublisher.scripts.publish_ftpmaster import PublishFTPMaster
if __name__ == '__main__':
script = PublishFTPMaster(
- "publish-ftpmaster", dbuser=config.archivepublisher.dbuser)
+ "publish-ftpmaster", 'publish_ftpmaster')
script.lock_and_run()
=== modified file 'database/replication/helpers.py'
--- database/replication/helpers.py 2011-07-25 13:39:10 +0000
+++ database/replication/helpers.py 2011-08-05 13:36:41 +0000
@@ -145,7 +145,7 @@
self.table_id, self.replication_set_id, self.master_node_id = row
-def sync(timeout):
+def sync(timeout, exit_on_fail=True):
"""Generate a sync event and wait for it to complete on all nodes.
This means that all pending events have propagated and are in sync
@@ -155,7 +155,7 @@
:param timeout: Number of seconds to wait for the sync. 0 to block
indefinitely.
"""
- return execute_slonik("", sync=timeout)
+ return execute_slonik("", sync=timeout, exit_on_fail=exit_on_fail)
def execute_slonik(script, sync=None, exit_on_fail=True, auto_preamble=True):
=== modified file 'database/replication/slon_ctl.py'
--- database/replication/slon_ctl.py 2010-10-11 10:32:29 +0000
+++ database/replication/slon_ctl.py 2011-08-05 13:36:41 +0000
@@ -104,7 +104,7 @@
log.debug("Logging to %s" % logfile)
log.debug("PID file %s" % pidfile)
# Hard code suitable command line arguments for development.
- slon_args = "-d 2 -s 2000 -t 10000"
+ slon_args = "-d 2 -s 500 -t 2500"
if lag is not None:
slon_args = "%s -l '%s'" % (slon_args, lag)
cmd = [
=== modified file 'database/sampledata/current-dev.sql'
--- database/sampledata/current-dev.sql 2011-07-13 06:06:53 +0000
+++ database/sampledata/current-dev.sql 2011-08-05 13:36:41 +0000
@@ -1888,21 +1888,21 @@
ALTER TABLE distroseries DISABLE TRIGGER ALL;
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (1, 1, 'warty', 'The Warty Warthog Release', 'Warty was the first stable release of Ubuntu. Key feature goals included releasing on time, with the latest version of the Gnome Desktop Environment, and the creation of all the infrastructure required to manage Ubuntu itself. Warty includes excellent support for Python, with most of the widely used Python libraries installed by default.', '4.10', 4, '2004-08-20 00:00:00', NULL, 17, 'Warty is the first release of Ubuntu, with a planned release date of October 2004.', 'Warty', NULL, 0, 1, 'warty-changes@xxxxxxxxxx', 4, 3, NULL, '2006-10-16 18:31:43.475428', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (2, 2, 'six', 'Six Six Six', 'some text to describe the whole 666 release of RH', '6.0.1', 4, '2004-03-21 00:00:00', NULL, 8, 'some text to describe the whole 666 release of RH', 'Six', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.482603', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (3, 1, 'hoary', 'The Hoary Hedgehog Release', 'Hoary is the second release of Ubuntu. Key feature goals include the integration of Hoary with the Launchpad for bugs and translation information, as well as Gnome 2.10 and the X.org window system.', '5.04', 2, NULL, 1, 1, 'Hoary is the second released of Ubuntu, with release planned for April 2005.', 'Hoary', NULL, 96, 6, 'hoary-changes@xxxxxxxxxx', 1, 4, NULL, '2006-10-16 18:31:43.483559', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (4, 2, '7.0', 'Seven', 'The release that we would not expect', '7.0.1', 3, NULL, 2, 7, 'The release that we would not expect', '7.0', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.484426', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (5, 1, 'grumpy', 'The Grumpy Groundhog Release', 'Grumpy, the third release of Ubuntu Linux, is not yet in active development. This information is purely a placeholder.', '5.10', 1, NULL, 1, 1, 'Grumpy is the third release of Ubuntu, planned for October 2005.', 'Grumpy', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.485233', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (6, 3, 'woody', 'WOODY', 'WOODY is the current stable verison of Debian GNU/Linux', '3.0', 4, '2003-01-01 00:00:00', NULL, 2, 'WOODY is the current stable verison of Debian GNU/Linux', 'Woody', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.486054', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (7, 3, 'sarge', 'Sarge', 'Sarge is the FROZEN unstable version of Debian GNU/Linux.', '3.1', 3, NULL, 6, 5, 'Sarge is the FROZEN unstable version of Debian GNU/Linux.', 'Sarge', NULL, 0, NULL, NULL, 0, 0, 6, '2006-10-16 18:31:43.486972', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (8, 3, 'sid', 'Sid', 'Sid is the CRAZY unstable version of Debian GNU/Linux.', '3.2', 1, NULL, 6, 6, 'Sid is the CRAZY unstable version of Debian GNU/Linux.', 'Sid', NULL, 0, NULL, NULL, 0, 1, NULL, '2006-10-16 18:31:43.487779', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (9, 7, '2k5', 'Guada 2005', 'This release places extra emphasis on usability and installability. The installer is adapted from Ubuntu to assume your country, language, keyboard and time zone preference, thus ensuring that installs ask the minimum number of questions possible.', '2005', 2, NULL, 3, 4, 'Guada 2005 is a rapid-install version of
-Ubuntu Hoary for the Andalucian marketplace.', 'Guada2005', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.488598', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (10, 1, 'breezy-autotest', 'Breezy Badger Autotest', 'Autotest version of Breezy', '6.6.6', 1, NULL, 3, 1, 'Autosync uploader test', 'Breezy Badger Autotest', NULL, 0, 8, 'autotest_changes@xxxxxxxxxx', 0, 0, NULL, '2006-10-16 18:31:43.489468', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (11, 8, 'breezy-autotest', 'Breezy Badger Autotest', 'Autotest version of Breezy', '6.6.6', 1, NULL, 1, 1, 'Autosync uploader test', 'Breezy Badger Autotest', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.490333', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (12, 5, 'krunch', 'The Krunchy Kangaroo', 'The archive split allows us to use different kernel settings for Kubuntu, as well as make other pervasive low-level fixes, and release on our own schedule.', '8.06', 1, NULL, 3, 1, 'This is the first experimental release of Kubuntu that uses a separate archive from the main Ubuntu release.', 'Krunch', NULL, 0, NULL, NULL, 0, 0, 33, '2006-10-16 18:31:43.491929', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (13, 8, 'hoary-test', 'Mock Hoary', 'nothing special', '9.9.9', 1, NULL, 1, 1, 'summmmmmmary', 'Hoary Mock', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.492845', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (14, 9, 'deriwarty', 'Deriwarty', 'Deriwarty', '1', 1, NULL, 1, 16, 'Deriwarty', 'Deriwarty', NULL, 0, NULL, NULL, 0, 0, NULL, '2011-03-17 14:29:23.190835', true, true, NULL, NULL, NULL, false, false);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (1, 1, 'warty', 'The Warty Warthog Release', 'Warty was the first stable release of Ubuntu. Key feature goals included releasing on time, with the latest version of the Gnome Desktop Environment, and the creation of all the infrastructure required to manage Ubuntu itself. Warty includes excellent support for Python, with most of the widely used Python libraries installed by default.', '4.10', 4, '2004-08-20 00:00:00', NULL, 17, 'Warty is the first release of Ubuntu, with a planned release date of October 2004.', 'Warty', NULL, 0, 1, 'warty-changes@xxxxxxxxxx', 4, 3, NULL, '2006-10-16 18:31:43.475428', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (2, 2, 'six', 'Six Six Six', 'some text to describe the whole 666 release of RH', '6.0.1', 4, '2004-03-21 00:00:00', NULL, 8, 'some text to describe the whole 666 release of RH', 'Six', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.482603', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (3, 1, 'hoary', 'The Hoary Hedgehog Release', 'Hoary is the second release of Ubuntu. Key feature goals include the integration of Hoary with the Launchpad for bugs and translation information, as well as Gnome 2.10 and the X.org window system.', '5.04', 2, NULL, 1, 1, 'Hoary is the second released of Ubuntu, with release planned for April 2005.', 'Hoary', NULL, 96, 6, 'hoary-changes@xxxxxxxxxx', 1, 4, NULL, '2006-10-16 18:31:43.483559', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (4, 2, '7.0', 'Seven', 'The release that we would not expect', '7.0.1', 3, NULL, 2, 7, 'The release that we would not expect', '7.0', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.484426', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (5, 1, 'grumpy', 'The Grumpy Groundhog Release', 'Grumpy, the third release of Ubuntu Linux, is not yet in active development. This information is purely a placeholder.', '5.10', 1, NULL, 1, 1, 'Grumpy is the third release of Ubuntu, planned for October 2005.', 'Grumpy', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.485233', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (6, 3, 'woody', 'WOODY', 'WOODY is the current stable verison of Debian GNU/Linux', '3.0', 4, '2003-01-01 00:00:00', NULL, 2, 'WOODY is the current stable verison of Debian GNU/Linux', 'Woody', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.486054', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (7, 3, 'sarge', 'Sarge', 'Sarge is the FROZEN unstable version of Debian GNU/Linux.', '3.1', 3, NULL, 6, 5, 'Sarge is the FROZEN unstable version of Debian GNU/Linux.', 'Sarge', NULL, 0, NULL, NULL, 0, 0, 6, '2006-10-16 18:31:43.486972', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (8, 3, 'sid', 'Sid', 'Sid is the CRAZY unstable version of Debian GNU/Linux.', '3.2', 1, NULL, 6, 6, 'Sid is the CRAZY unstable version of Debian GNU/Linux.', 'Sid', NULL, 0, NULL, NULL, 0, 1, NULL, '2006-10-16 18:31:43.487779', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (9, 7, '2k5', 'Guada 2005', 'This release places extra emphasis on usability and installability. The installer is adapted from Ubuntu to assume your country, language, keyboard and time zone preference, thus ensuring that installs ask the minimum number of questions possible.', '2005', 2, NULL, 3, 4, 'Guada 2005 is a rapid-install version of
+Ubuntu Hoary for the Andalucian marketplace.', 'Guada2005', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.488598', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (10, 1, 'breezy-autotest', 'Breezy Badger Autotest', 'Autotest version of Breezy', '6.6.6', 1, NULL, 3, 1, 'Autosync uploader test', 'Breezy Badger Autotest', NULL, 0, 8, 'autotest_changes@xxxxxxxxxx', 0, 0, NULL, '2006-10-16 18:31:43.489468', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (11, 8, 'breezy-autotest', 'Breezy Badger Autotest', 'Autotest version of Breezy', '6.6.6', 1, NULL, 1, 1, 'Autosync uploader test', 'Breezy Badger Autotest', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.490333', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (12, 5, 'krunch', 'The Krunchy Kangaroo', 'The archive split allows us to use different kernel settings for Kubuntu, as well as make other pervasive low-level fixes, and release on our own schedule.', '8.06', 1, NULL, 3, 1, 'This is the first experimental release of Kubuntu that uses a separate archive from the main Ubuntu release.', 'Krunch', NULL, 0, NULL, NULL, 0, 0, 33, '2006-10-16 18:31:43.491929', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (13, 8, 'hoary-test', 'Mock Hoary', 'nothing special', '9.9.9', 1, NULL, 1, 1, 'summmmmmmary', 'Hoary Mock', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.492845', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (14, 9, 'deriwarty', 'Deriwarty', 'Deriwarty', '1', 1, NULL, 1, 16, 'Deriwarty', 'Deriwarty', NULL, 0, NULL, NULL, 0, 0, NULL, '2011-03-17 14:29:23.190835', true, true, NULL, NULL, NULL, false, false, true);
ALTER TABLE distroseries ENABLE TRIGGER ALL;
=== modified file 'database/sampledata/current.sql'
--- database/sampledata/current.sql 2011-07-13 06:06:53 +0000
+++ database/sampledata/current.sql 2011-08-05 13:36:41 +0000
@@ -1888,20 +1888,20 @@
ALTER TABLE distroseries DISABLE TRIGGER ALL;
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (1, 1, 'warty', 'The Warty Warthog Release', 'Warty was the first stable release of Ubuntu. Key feature goals included releasing on time, with the latest version of the Gnome Desktop Environment, and the creation of all the infrastructure required to manage Ubuntu itself. Warty includes excellent support for Python, with most of the widely used Python libraries installed by default.', '4.10', 4, '2004-08-20 00:00:00', NULL, 17, 'Warty is the first release of Ubuntu, with a planned release date of October 2004.', 'Warty', NULL, 0, 1, 'warty-changes@xxxxxxxxxx', 4, 3, NULL, '2006-10-16 18:31:43.475428', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (2, 2, 'six', 'Six Six Six', 'some text to describe the whole 666 release of RH', '6.0.1', 4, '2004-03-21 00:00:00', NULL, 8, 'some text to describe the whole 666 release of RH', 'Six', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.482603', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (3, 1, 'hoary', 'The Hoary Hedgehog Release', 'Hoary is the second release of Ubuntu. Key feature goals include the integration of Hoary with the Launchpad for bugs and translation information, as well as Gnome 2.10 and the X.org window system.', '5.04', 2, NULL, 1, 1, 'Hoary is the second released of Ubuntu, with release planned for April 2005.', 'Hoary', NULL, 96, 6, 'hoary-changes@xxxxxxxxxx', 1, 4, NULL, '2006-10-16 18:31:43.483559', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (4, 2, '7.0', 'Seven', 'The release that we would not expect', '7.0.1', 3, NULL, 2, 7, 'The release that we would not expect', '7.0', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.484426', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (5, 1, 'grumpy', 'The Grumpy Groundhog Release', 'Grumpy, the third release of Ubuntu Linux, is not yet in active development. This information is purely a placeholder.', '5.10', 1, NULL, 1, 1, 'Grumpy is the third release of Ubuntu, planned for October 2005.', 'Grumpy', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.485233', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (6, 3, 'woody', 'WOODY', 'WOODY is the current stable verison of Debian GNU/Linux', '3.0', 4, '2003-01-01 00:00:00', NULL, 2, 'WOODY is the current stable verison of Debian GNU/Linux', 'Woody', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.486054', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (7, 3, 'sarge', 'Sarge', 'Sarge is the FROZEN unstable version of Debian GNU/Linux.', '3.1', 3, NULL, 6, 5, 'Sarge is the FROZEN unstable version of Debian GNU/Linux.', 'Sarge', NULL, 0, NULL, NULL, 0, 0, 6, '2006-10-16 18:31:43.486972', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (8, 3, 'sid', 'Sid', 'Sid is the CRAZY unstable version of Debian GNU/Linux.', '3.2', 1, NULL, 6, 6, 'Sid is the CRAZY unstable version of Debian GNU/Linux.', 'Sid', NULL, 0, NULL, NULL, 0, 1, NULL, '2006-10-16 18:31:43.487779', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (9, 7, '2k5', 'Guada 2005', 'This release places extra emphasis on usability and installability. The installer is adapted from Ubuntu to assume your country, language, keyboard and time zone preference, thus ensuring that installs ask the minimum number of questions possible.', '2005', 2, NULL, 3, 4, 'Guada 2005 is a rapid-install version of
-Ubuntu Hoary for the Andalucian marketplace.', 'Guada2005', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.488598', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (10, 1, 'breezy-autotest', 'Breezy Badger Autotest', 'Autotest version of Breezy', '6.6.6', 1, NULL, 3, 1, 'Autosync uploader test', 'Breezy Badger Autotest', NULL, 0, 8, 'autotest_changes@xxxxxxxxxx', 0, 0, NULL, '2006-10-16 18:31:43.489468', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (11, 8, 'breezy-autotest', 'Breezy Badger Autotest', 'Autotest version of Breezy', '6.6.6', 1, NULL, 1, 1, 'Autosync uploader test', 'Breezy Badger Autotest', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.490333', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (12, 5, 'krunch', 'The Krunchy Kangaroo', 'The archive split allows us to use different kernel settings for Kubuntu, as well as make other pervasive low-level fixes, and release on our own schedule.', '8.06', 1, NULL, 3, 1, 'This is the first experimental release of Kubuntu that uses a separate archive from the main Ubuntu release.', 'Krunch', NULL, 0, NULL, NULL, 0, 0, 33, '2006-10-16 18:31:43.491929', false, false, NULL, NULL, NULL, false, false);
-INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic) VALUES (13, 8, 'hoary-test', 'Mock Hoary', 'nothing special', '9.9.9', 1, NULL, 1, 1, 'summmmmmmary', 'Hoary Mock', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.492845', false, false, NULL, NULL, NULL, false, false);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (1, 1, 'warty', 'The Warty Warthog Release', 'Warty was the first stable release of Ubuntu. Key feature goals included releasing on time, with the latest version of the Gnome Desktop Environment, and the creation of all the infrastructure required to manage Ubuntu itself. Warty includes excellent support for Python, with most of the widely used Python libraries installed by default.', '4.10', 4, '2004-08-20 00:00:00', NULL, 17, 'Warty is the first release of Ubuntu, with a planned release date of October 2004.', 'Warty', NULL, 0, 1, 'warty-changes@xxxxxxxxxx', 4, 3, NULL, '2006-10-16 18:31:43.475428', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (2, 2, 'six', 'Six Six Six', 'some text to describe the whole 666 release of RH', '6.0.1', 4, '2004-03-21 00:00:00', NULL, 8, 'some text to describe the whole 666 release of RH', 'Six', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.482603', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (3, 1, 'hoary', 'The Hoary Hedgehog Release', 'Hoary is the second release of Ubuntu. Key feature goals include the integration of Hoary with the Launchpad for bugs and translation information, as well as Gnome 2.10 and the X.org window system.', '5.04', 2, NULL, 1, 1, 'Hoary is the second released of Ubuntu, with release planned for April 2005.', 'Hoary', NULL, 96, 6, 'hoary-changes@xxxxxxxxxx', 1, 4, NULL, '2006-10-16 18:31:43.483559', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (4, 2, '7.0', 'Seven', 'The release that we would not expect', '7.0.1', 3, NULL, 2, 7, 'The release that we would not expect', '7.0', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.484426', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (5, 1, 'grumpy', 'The Grumpy Groundhog Release', 'Grumpy, the third release of Ubuntu Linux, is not yet in active development. This information is purely a placeholder.', '5.10', 1, NULL, 1, 1, 'Grumpy is the third release of Ubuntu, planned for October 2005.', 'Grumpy', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.485233', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (6, 3, 'woody', 'WOODY', 'WOODY is the current stable verison of Debian GNU/Linux', '3.0', 4, '2003-01-01 00:00:00', NULL, 2, 'WOODY is the current stable verison of Debian GNU/Linux', 'Woody', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.486054', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (7, 3, 'sarge', 'Sarge', 'Sarge is the FROZEN unstable version of Debian GNU/Linux.', '3.1', 3, NULL, 6, 5, 'Sarge is the FROZEN unstable version of Debian GNU/Linux.', 'Sarge', NULL, 0, NULL, NULL, 0, 0, 6, '2006-10-16 18:31:43.486972', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (8, 3, 'sid', 'Sid', 'Sid is the CRAZY unstable version of Debian GNU/Linux.', '3.2', 1, NULL, 6, 6, 'Sid is the CRAZY unstable version of Debian GNU/Linux.', 'Sid', NULL, 0, NULL, NULL, 0, 1, NULL, '2006-10-16 18:31:43.487779', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (9, 7, '2k5', 'Guada 2005', 'This release places extra emphasis on usability and installability. The installer is adapted from Ubuntu to assume your country, language, keyboard and time zone preference, thus ensuring that installs ask the minimum number of questions possible.', '2005', 2, NULL, 3, 4, 'Guada 2005 is a rapid-install version of
+Ubuntu Hoary for the Andalucian marketplace.', 'Guada2005', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.488598', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (10, 1, 'breezy-autotest', 'Breezy Badger Autotest', 'Autotest version of Breezy', '6.6.6', 1, NULL, 3, 1, 'Autosync uploader test', 'Breezy Badger Autotest', NULL, 0, 8, 'autotest_changes@xxxxxxxxxx', 0, 0, NULL, '2006-10-16 18:31:43.489468', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (11, 8, 'breezy-autotest', 'Breezy Badger Autotest', 'Autotest version of Breezy', '6.6.6', 1, NULL, 1, 1, 'Autosync uploader test', 'Breezy Badger Autotest', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.490333', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (12, 5, 'krunch', 'The Krunchy Kangaroo', 'The archive split allows us to use different kernel settings for Kubuntu, as well as make other pervasive low-level fixes, and release on our own schedule.', '8.06', 1, NULL, 3, 1, 'This is the first experimental release of Kubuntu that uses a separate archive from the main Ubuntu release.', 'Krunch', NULL, 0, NULL, NULL, 0, 0, 33, '2006-10-16 18:31:43.491929', false, false, NULL, NULL, NULL, false, false, true);
+INSERT INTO distroseries (id, distribution, name, title, description, version, releasestatus, datereleased, parent_series, registrant, summary, displayname, datelastlangpack, messagecount, nominatedarchindep, changeslist, binarycount, sourcecount, driver, date_created, hide_all_translations, defer_translation_imports, language_pack_base, language_pack_delta, language_pack_proposed, language_pack_full_export_requested, backports_not_automatic, include_long_descriptions) VALUES (13, 8, 'hoary-test', 'Mock Hoary', 'nothing special', '9.9.9', 1, NULL, 1, 1, 'summmmmmmary', 'Hoary Mock', NULL, 0, NULL, NULL, 0, 0, NULL, '2006-10-16 18:31:43.492845', false, false, NULL, NULL, NULL, false, false, true);
ALTER TABLE distroseries ENABLE TRIGGER ALL;
=== modified file 'database/schema/Makefile'
--- database/schema/Makefile 2011-01-31 11:10:39 +0000
+++ database/schema/Makefile 2011-08-05 13:36:41 +0000
@@ -128,7 +128,6 @@
@ psql -d ${EMPTY_DBNAME} -q -c "CREATE SCHEMA todrop;"
@ echo "* Creating functions"
@ psql -d ${EMPTY_DBNAME} -f trusted.sql | grep : | cat
- @ psql -d ${EMPTY_DBNAME} -f testfuncs.sql | grep : | cat
@ echo "* Installing tsearch2 into ts2 schema"
@ ${PYTHON} fti.py -q --setup-only -d ${EMPTY_DBNAME}
@ echo "* Loading base database schema"
=== modified file 'database/schema/comments.sql'
--- database/schema/comments.sql 2011-07-08 17:12:15 +0000
+++ database/schema/comments.sql 2011-08-05 13:36:41 +0000
@@ -1676,6 +1676,7 @@
COMMENT ON COLUMN DistroSeries.driver IS 'This is a person or team who can act as a driver for this specific release - note that the distribution drivers can also set goals for any release.';
COMMENT ON COLUMN DistroSeries.changeslist IS 'The email address (name name) of the changes announcement list for this distroseries. If NULL, no announcement mail will be sent.';
COMMENT ON COLUMN DistroSeries.defer_translation_imports IS 'Don''t accept PO imports for this release just now.';
+COMMENT ON COLUMN DistroSeries.include_long_descriptions IS 'Include long descriptions in Packages rather than in Translation-en.';
-- DistroArchSeries
@@ -1900,6 +1901,7 @@
COMMENT ON COLUMN PackagingJob.productseries IS 'The productseries of the Packaging.';
COMMENT ON COLUMN PackagingJob.sourcepackagename IS 'The sourcepackage of the Packaging.';
COMMENT ON COLUMN PackagingJob.distroseries IS 'The distroseries of the Packaging.';
+COMMENT ON COLUMN PackagingJob.potemplate IS 'A POTemplate to restrict the job to or NULL if all templates need to be handled.';
-- Translator / TranslationGroup
=== modified file 'database/schema/full-update.py'
--- database/schema/full-update.py 2011-07-26 08:37:52 +0000
+++ database/schema/full-update.py 2011-08-05 13:36:41 +0000
@@ -6,7 +6,7 @@
import _pythonpath
-import os.path
+from datetime import datetime
from optparse import OptionParser
import subprocess
import sys
@@ -111,6 +111,7 @@
return 99
# Confirm we can invoke PGBOUNCER_INITD
+ log.debug("Confirming sudo access to pgbouncer startup script")
pgbouncer_rc = run_pgbouncer(log, 'status')
if pgbouncer_rc != 0:
return pgbouncer_rc
@@ -125,8 +126,11 @@
upgrade_run = False
security_run = False
+ outage_start = datetime.now()
+
try:
# Shutdown pgbouncer
+ log.info("Outage starts. Shutting down pgbouncer.")
pgbouncer_rc = run_pgbouncer(log, 'stop')
if pgbouncer_rc != 0:
log.fatal("pgbouncer not shut down [%s]", pgbouncer_rc)
@@ -136,10 +140,12 @@
if not KillConnectionsPreflight(log).check_all():
return 100
+ log.info("Preflight check succeeded. Starting upgrade.")
upgrade_rc = run_upgrade(options, log)
if upgrade_rc != 0:
return upgrade_rc
upgrade_run = True
+ log.info("Database patches applied. Stored procedures updated.")
security_rc = run_security(options, log)
if security_rc != 0:
@@ -148,11 +154,13 @@
log.info("All database upgrade steps completed")
+ log.info("Restarting pgbouncer")
pgbouncer_rc = run_pgbouncer(log, 'start')
if pgbouncer_rc != 0:
log.fatal("pgbouncer not restarted [%s]", pgbouncer_rc)
return pgbouncer_rc
pgbouncer_down = False
+ log.info("Outage complete. %s", datetime.now() - outage_start)
# We will start seeing connections as soon as pgbouncer is
# reenabled, so ignore them here.
@@ -180,6 +188,7 @@
pgbouncer_rc = run_pgbouncer(log, 'start')
if pgbouncer_rc == 0:
log.info("Despite failures, pgbouncer restarted.")
+ log.info("Outage complete. %s", datetime.now() - outage_start)
else:
log.fatal("pgbouncer is down and refuses to restart")
if not upgrade_run:
=== added file 'database/schema/patch-2208-76-3.sql'
--- database/schema/patch-2208-76-3.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2208-76-3.sql 2011-08-05 13:36:41 +0000
@@ -0,0 +1,15 @@
+-- Copyright 2011 Canonical Ltd. This software is licensed under the
+-- GNU Affero General Public License version 3 (see the file LICENSE).
+
+SET client_min_messages = ERROR;
+
+-- Drop old unused functions still lurking on production.
+DROP FUNCTION IF EXISTS is_blacklisted_name(text);
+DROP FUNCTION IF EXISTS name_blacklist_match(text);
+DROP FUNCTION IF EXISTS reverse(text);
+DROP FUNCTION IF EXISTS bug_summary_temp_journal_clean_row(bugsummary);
+DROP FUNCTION IF EXISTS valid_version(text);
+DROP FUNCTION IF EXISTS decendantrevision(integer);
+DROP FUNCTION IF EXISTS sleep_for_testing(float);
+
+INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 76, 3);
=== added file 'database/schema/patch-2208-76-4.sql'
--- database/schema/patch-2208-76-4.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2208-76-4.sql 2011-08-05 13:36:41 +0000
@@ -0,0 +1,159 @@
+-- Copyright 2011 Canonical Ltd. This software is licensed under the
+-- GNU Affero General Public License version 3 (see the file LICENSE).
+
+SET client_min_messages=ERROR;
+
+DROP FUNCTION bugsummary_rollup_journal();
+
+CREATE OR REPLACE FUNCTION bugsummary_rollup_journal(batchsize integer=NULL)
+RETURNS VOID
+LANGUAGE plpgsql VOLATILE
+CALLED ON NULL INPUT
+SECURITY DEFINER SET search_path TO public AS
+$$
+DECLARE
+ d bugsummary%ROWTYPE;
+ max_id integer;
+BEGIN
+ -- Lock so we don't content with other invokations of this
+ -- function. We can happily lock the BugSummary table for writes
+ -- as this function is the only thing that updates that table.
+ -- BugSummaryJournal remains unlocked so nothing should be blocked.
+ LOCK TABLE BugSummary IN ROW EXCLUSIVE MODE;
+
+ IF batchsize IS NULL THEN
+ SELECT MAX(id) INTO max_id FROM BugSummaryJournal;
+ ELSE
+ SELECT MAX(id) INTO max_id FROM (
+ SELECT id FROM BugSummaryJournal ORDER BY id LIMIT batchsize
+ ) AS Whatever;
+ END IF;
+
+ FOR d IN
+ SELECT
+ NULL as id,
+ SUM(count),
+ product,
+ productseries,
+ distribution,
+ distroseries,
+ sourcepackagename,
+ viewed_by,
+ tag,
+ status,
+ milestone,
+ importance,
+ has_patch,
+ fixed_upstream
+ FROM BugSummaryJournal
+ WHERE id <= max_id
+ GROUP BY
+ product, productseries, distribution, distroseries,
+ sourcepackagename, viewed_by, tag, status, milestone,
+ importance, has_patch, fixed_upstream
+ HAVING sum(count) <> 0
+ LOOP
+ IF d.count < 0 THEN
+ PERFORM bug_summary_dec(d);
+ ELSIF d.count > 0 THEN
+ PERFORM bug_summary_inc(d);
+ END IF;
+ END LOOP;
+
+ -- Clean out any counts we reduced to 0.
+ DELETE FROM BugSummary WHERE count=0;
+ -- Clean out the journal entries we have handled.
+ DELETE FROM BugSummaryJournal WHERE id <= max_id;
+END;
+$$;
+
+COMMENT ON FUNCTION bugsummary_rollup_journal(integer) IS
+'Collate and migrate rows from BugSummaryJournal to BugSummary';
+
+
+CREATE OR REPLACE FUNCTION bug_summary_dec(bugsummary) RETURNS VOID
+LANGUAGE SQL AS
+$$
+ -- We own the row reference, so in the absence of bugs this cannot
+ -- fail - just decrement the row.
+ UPDATE BugSummary SET count = count + $1.count
+ WHERE
+ ((product IS NULL AND $1.product IS NULL)
+ OR product = $1.product)
+ AND ((productseries IS NULL AND $1.productseries IS NULL)
+ OR productseries = $1.productseries)
+ AND ((distribution IS NULL AND $1.distribution IS NULL)
+ OR distribution = $1.distribution)
+ AND ((distroseries IS NULL AND $1.distroseries IS NULL)
+ OR distroseries = $1.distroseries)
+ AND ((sourcepackagename IS NULL AND $1.sourcepackagename IS NULL)
+ OR sourcepackagename = $1.sourcepackagename)
+ AND ((viewed_by IS NULL AND $1.viewed_by IS NULL)
+ OR viewed_by = $1.viewed_by)
+ AND ((tag IS NULL AND $1.tag IS NULL)
+ OR tag = $1.tag)
+ AND status = $1.status
+ AND ((milestone IS NULL AND $1.milestone IS NULL)
+ OR milestone = $1.milestone)
+ AND importance = $1.importance
+ AND has_patch = $1.has_patch
+ AND fixed_upstream = $1.fixed_upstream;
+$$;
+
+CREATE OR REPLACE FUNCTION bug_summary_inc(d bugsummary) RETURNS VOID
+LANGUAGE plpgsql AS
+$$
+BEGIN
+ -- Shameless adaption from postgresql manual
+ LOOP
+ -- first try to update the row
+ UPDATE BugSummary SET count = count + d.count
+ WHERE
+ ((product IS NULL AND $1.product IS NULL)
+ OR product = $1.product)
+ AND ((productseries IS NULL AND $1.productseries IS NULL)
+ OR productseries = $1.productseries)
+ AND ((distribution IS NULL AND $1.distribution IS NULL)
+ OR distribution = $1.distribution)
+ AND ((distroseries IS NULL AND $1.distroseries IS NULL)
+ OR distroseries = $1.distroseries)
+ AND ((sourcepackagename IS NULL AND $1.sourcepackagename IS NULL)
+ OR sourcepackagename = $1.sourcepackagename)
+ AND ((viewed_by IS NULL AND $1.viewed_by IS NULL)
+ OR viewed_by = $1.viewed_by)
+ AND ((tag IS NULL AND $1.tag IS NULL)
+ OR tag = $1.tag)
+ AND status = $1.status
+ AND ((milestone IS NULL AND $1.milestone IS NULL)
+ OR milestone = $1.milestone)
+ AND importance = $1.importance
+ AND has_patch = $1.has_patch
+ AND fixed_upstream = $1.fixed_upstream;
+ IF found THEN
+ RETURN;
+ END IF;
+ -- not there, so try to insert the key
+ -- if someone else inserts the same key concurrently,
+ -- we could get a unique-key failure
+ BEGIN
+ INSERT INTO BugSummary(
+ count, product, productseries, distribution,
+ distroseries, sourcepackagename, viewed_by, tag,
+ status, milestone,
+ importance, has_patch, fixed_upstream)
+ VALUES (
+ d.count, d.product, d.productseries, d.distribution,
+ d.distroseries, d.sourcepackagename, d.viewed_by, d.tag,
+ d.status, d.milestone,
+ d.importance, d.has_patch, d.fixed_upstream);
+ RETURN;
+ EXCEPTION WHEN unique_violation THEN
+ -- do nothing, and loop to try the UPDATE again
+ END;
+ END LOOP;
+END;
+$$;
+
+
+
+INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 76, 4);
=== added file 'database/schema/patch-2208-79-0.sql'
--- database/schema/patch-2208-79-0.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2208-79-0.sql 2011-08-05 13:36:41 +0000
@@ -0,0 +1,9 @@
+-- Copyright 2011 Canonical Ltd. This software is licensed under the
+-- GNU Affero General Public License version 3 (see the file LICENSE).
+
+SET client_min_messages=ERROR;
+
+ALTER TABLE distroseries
+ ADD COLUMN include_long_descriptions BOOLEAN NOT NULL DEFAULT TRUE;
+
+INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 79, 0);
=== added file 'database/schema/patch-2208-79-1.sql'
--- database/schema/patch-2208-79-1.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2208-79-1.sql 2011-08-05 13:36:41 +0000
@@ -0,0 +1,26 @@
+-- Copyright 2011 Canonical Ltd. This software is licensed under the
+-- GNU Affero General Public License version 3 (see the file LICENSE).
+SET client_min_messages=ERROR;
+
+ALTER TABLE PackagingJob
+ ADD COLUMN
+ potemplate INTEGER DEFAULT NULL
+ CONSTRAINT potemplate_fk REFERENCES POTemplate;
+
+ALTER TABLE PackagingJob
+ ALTER COLUMN productseries DROP NOT NULL,
+ ALTER COLUMN distroseries DROP NOT NULL,
+ ALTER COLUMN sourcepackagename DROP NOT NULL,
+ ADD CONSTRAINT translationtemplatejob_valid_link CHECK (
+ -- If there is a template, it is the template being moved.
+ (potemplate IS NOT NULL AND productseries IS NULL AND
+ distroseries IS NULL AND sourcepackagename IS NULL) OR
+ -- If there is no template, we need all of productseries, distroseries
+ -- and sourcepackagename because we are moving translations between
+ -- a productseries and a source package.
+ (potemplate IS NULL AND productseries IS NOT NULL AND
+ distroseries IS NOT NULL AND sourcepackagename IS NOT NULL));
+
+CREATE INDEX packagingjob__potemplate__idx ON PackagingJob (potemplate);
+
+INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 79, 1);
=== modified file 'database/schema/preflight.py'
--- database/schema/preflight.py 2011-07-25 13:59:01 +0000
+++ database/schema/preflight.py 2011-08-05 13:36:41 +0000
@@ -226,7 +226,7 @@
cluster to be quiescent.
"""
if self.is_replicated:
- success = replication.helpers.sync(30)
+ success = replication.helpers.sync(30, exit_on_fail=False)
if success:
self.log.info(
"Replication events are being propagated.")
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg 2011-08-02 09:57:41 +0000
+++ database/schema/security.cfg 2011-08-05 13:36:41 +0000
@@ -11,7 +11,6 @@
[public]
type=group
-public._killall_backends(text) =
public.activity() = EXECUTE
public.add_test_openid_identifier(integer) = EXECUTE
public.alllocks =
@@ -144,7 +143,7 @@
public.bugnotificationrecipientarchive = SELECT, UPDATE
public.bugsummary = SELECT
public.bugsummaryjournal = SELECT
-public.bugsummary_rollup_journal() = EXECUTE
+public.bugsummary_rollup_journal(integer) = EXECUTE
public.bugtag = SELECT, INSERT, DELETE
public.bugtrackercomponent = SELECT, INSERT, UPDATE
public.bugtrackercomponentgroup = SELECT, INSERT, UPDATE
@@ -2157,7 +2156,7 @@
public.bugsubscriptionfilterimportance = SELECT
public.bugsubscriptionfilterstatus = SELECT
public.bugsubscriptionfiltertag = SELECT
-public.bugsummary_rollup_journal() = EXECUTE
+public.bugsummary_rollup_journal(integer) = EXECUTE
public.bugtag = SELECT
public.bugwatch = SELECT, UPDATE
public.bugwatchactivity = SELECT, DELETE
@@ -2278,3 +2277,11 @@
public.potemplate = SELECT
public.sourcepackagename = SELECT
type=user
+
+[generate_contents_files]
+type=user
+groups=archivepublisher
+
+[publish_ftpmaster]
+type=user
+groups=archivepublisher
=== modified file 'database/schema/security.py'
--- database/schema/security.py 2011-07-25 14:10:46 +0000
+++ database/schema/security.py 2011-08-05 13:36:41 +0000
@@ -134,10 +134,10 @@
def execute(self, cmd, params=None):
cmd = cmd.encode('utf8')
if params is None:
- log.debug2('%s' % (cmd, ))
+ log.debug3('%s' % (cmd, ))
return self.__dict__['_cursor'].execute(cmd)
else:
- log.debug2('%s [%r]' % (cmd, params))
+ log.debug3('%s [%r]' % (cmd, params))
return self.__dict__['_cursor'].execute(cmd, params)
def __getattr__(self, key):
@@ -342,14 +342,14 @@
if username in schema.principals:
if type_ == 'group':
if options.revoke:
- log.debug("Revoking membership of %s role", username)
+ log.debug2("Revoking membership of %s role", username)
cur.execute("REVOKE %s FROM %s" % (
quote_identifier(username), all_users))
else:
# Note - we don't drop the user because it might own
# objects in other databases. We need to ensure they are
# not superusers though!
- log.debug("Resetting role options of %s role.", username)
+ log.debug2("Resetting role options of %s role.", username)
cur.execute(
"ALTER ROLE %s WITH %s" % (
quote_identifier(username),
@@ -380,12 +380,12 @@
if user.endswith('_ro'):
groups = ['%s_ro' % group for group in groups]
if groups:
- log.debug("Adding %s to %s roles", user, ', '.join(groups))
+ log.debug2("Adding %s to %s roles", user, ', '.join(groups))
for group in groups:
cur.execute(r"""ALTER GROUP %s ADD USER %s""" % (
quote_identifier(group), quote_identifier(user)))
else:
- log.debug("%s not in any roles", user)
+ log.debug2("%s not in any roles", user)
if options.revoke:
# Change ownership of all objects to OWNER.
@@ -467,7 +467,7 @@
else:
who_ro = quote_identifier('%s_ro' % username)
- log.debug(
+ log.debug2(
"Granting %s on %s to %s", perm, obj.fullname, who)
if obj.type == 'function':
function_permissions.add(perm, obj.fullname, who)
=== removed file 'database/schema/testfuncs.sql'
--- database/schema/testfuncs.sql 2009-06-24 21:17:33 +0000
+++ database/schema/testfuncs.sql 1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
-/*
-Copyright 2009 Canonical Ltd. This software is licensed under the
-GNU Affero General Public License version 3 (see the file LICENSE).
-
-Stored procedures designed for use only by the test suite. These
-will not be loaded onto the production database
-*/
-
-CREATE OR REPLACE FUNCTION _killall_backends(text)
-RETURNS Boolean AS $$
- import os
- from signal import SIGTERM
-
- plan = plpy.prepare(
- "SELECT procpid FROM pg_stat_activity WHERE datname=$1", ['text']
- )
- success = True
- for row in plpy.execute(plan, args):
- try:
- plpy.info("Killing %d" % row['procpid'])
- os.kill(row['procpid'], SIGTERM)
- except OSError:
- success = False
-
- return success
-$$ LANGUAGE plpythonu;
-
-COMMENT ON FUNCTION _killall_backends(text) IS 'Kill all backend processes connected to the given database. Note that this is unlikely to work if you are connected to the database you are killing, as you are likely to kill your own connection before all the others have been killed.';
-
=== modified file 'database/schema/trusted.sql'
--- database/schema/trusted.sql 2011-06-13 08:39:28 +0000
+++ database/schema/trusted.sql 2011-08-05 13:36:41 +0000
@@ -1854,11 +1854,11 @@
AFFECTED_USER = 4
SUBSCRIBER = 2
-
def get_max_heat_for_bug(bug_id):
results = plpy.execute("""
SELECT MAX(
- GREATEST(Product.max_bug_heat, Distribution.max_bug_heat))
+ GREATEST(Product.max_bug_heat,
+ DistributionSourcePackage.max_bug_heat))
AS max_heat
FROM BugTask
LEFT OUTER JOIN ProductSeries ON
@@ -1871,6 +1871,9 @@
LEFT OUTER JOIN Distribution ON (
BugTask.distribution = Distribution.id
OR DistroSeries.distribution = Distribution.id)
+ LEFT OUTER JOIN DistributionSourcePackage ON (
+ BugTask.sourcepackagename =
+ DistributionSourcePackage.sourcepackagename)
WHERE
BugTask.bug = %s""" % bug_id)
=== modified file 'database/schema/upgrade.py'
--- database/schema/upgrade.py 2011-07-25 13:39:10 +0000
+++ database/schema/upgrade.py 2011-08-05 13:36:41 +0000
@@ -178,7 +178,7 @@
# The first script applies the DB patches to all nodes.
# First make sure the cluster is synced.
- log.info("Waiting for cluster to sync.")
+ log.info("Waiting for cluster to sync, pre-update.")
replication.helpers.sync(timeout=600)
outf = StringIO()
@@ -186,18 +186,15 @@
# Start a transaction block.
print >> outf, "try {"
+ sql_to_run = []
+
def run_sql(script):
if os.path.isabs(script):
full_path = script
else:
full_path = os.path.abspath(os.path.join(SCHEMA_DIR, script))
assert os.path.exists(full_path), "%s doesn't exist." % full_path
- print >> outf, dedent("""\
- execute script (
- set id = @lpmain_set, event node = @master_node,
- filename='%s'
- );
- """ % full_path)
+ sql_to_run.append(full_path)
# We are going to generate some temporary files using
# NamedTempoararyFile. Store them here so we can control when
@@ -236,6 +233,22 @@
combined_script.flush()
run_sql(combined_script.name)
+ # Now combine all the written SQL (probably trusted.sql and
+ # patch*.sql) into one big file, which we execute with a single
+ # slonik execute_script statement to avoid multiple syncs.
+ single = NamedTemporaryFile(prefix='single', suffix='.sql')
+ for path in sql_to_run:
+ print >> single, open(path, 'r').read()
+ print >> single, ""
+ single.flush()
+
+ print >> outf, dedent("""\
+ execute script (
+ set id = @lpmain_set, event node = @master_node,
+ filename='%s'
+ );
+ """ % single.name)
+
# Close transaction block and abort on error.
print >> outf, dedent("""\
}
@@ -246,9 +259,11 @@
""")
# Execute the script with slonik.
+ log.info("slonik(1) schema upgrade script generated. Invoking.")
if not replication.helpers.execute_slonik(outf.getvalue()):
log.fatal("Aborting.")
raise SystemExit(4)
+ log.info("slonik(1) schema upgrade script completed.")
# Cleanup our temporary files - they applied successfully.
for temporary_file in temporary_files:
@@ -256,6 +271,7 @@
del temporary_files
# Wait for replication to sync.
+ log.info("Waiting for patches to apply to slaves and cluster to sync.")
replication.helpers.sync(timeout=0)
# The db patches have now been applied to all nodes, and we are now
@@ -350,25 +366,33 @@
subscribe set (
id=@holding_set, provider=@master_node,
receiver=@node%d_node, forward=yes);
+ wait for event (
+ origin=@master_node, confirmed=all,
+ wait on=@master_node, timeout=0);
echo 'Waiting for sync';
sync (id=@master_node);
wait for event (
origin=@master_node, confirmed=ALL,
- wait on=@master_node, timeout=0
- );
+ wait on=@master_node, timeout=0);
""" % (slave_node.node_id, slave_node.node_id))
print >> outf, dedent("""\
echo 'Merging holding set to lpmain';
merge set (
- id=@lpmain_set, add id=@holding_set, origin=@master_node
- );
+ id=@lpmain_set, add id=@holding_set, origin=@master_node);
""")
# Execute the script and sync.
+ log.info(
+ "Generated slonik(1) script to replicate new objects. Invoking.")
if not replication.helpers.execute_slonik(outf.getvalue()):
log.fatal("Aborting.")
+ log.info(
+ "slonik(1) script to replicate new objects completed.")
+ log.info("Waiting for sync.")
replication.helpers.sync(timeout=0)
+ else:
+ log.info("No new tables or sequences to replicate.")
# We also scan for tables and sequences we want to drop and do so using
# a final slonik script. Instead of dropping tables in the DB patch,
@@ -411,8 +435,10 @@
exit 1;
}
""" % sql.name)
+ log.info("Generated slonik(1) script to drop tables. Invoking.")
if not replication.helpers.execute_slonik(sk.getvalue()):
log.fatal("Aborting.")
+ log.info("slonik(1) script to drop tables completed.")
sql.close()
# Now drop sequences. We don't do this at the same time as the tables,
@@ -455,8 +481,11 @@
exit 1;
}
""" % sql.name)
+ log.info("Generated slonik(1) script to drop sequences. Invoking.")
if not replication.helpers.execute_slonik(sk.getvalue()):
log.fatal("Aborting.")
+ log.info("slonik(1) script to drop sequences completed.")
+ log.info("Waiting for final sync.")
replication.helpers.sync(timeout=0)
=== modified file 'lib/lp/testing/pgsql.py'
--- lib/lp/testing/pgsql.py 2011-07-01 07:11:27 +0000
+++ lib/lp/testing/pgsql.py 2011-08-05 13:36:41 +0000
@@ -399,7 +399,11 @@
# always having this is a problem.
try:
cur = con.cursor()
- cur.execute('SELECT _killall_backends(%s)', [self.dbname])
+ cur.execute("""
+ SELECT pg_terminate_backend(procpid)
+ FROM pg_stat_activity
+ WHERE procpid <> pg_backend_pid() AND datname=%s
+ """, [self.dbname])
except psycopg2.DatabaseError:
pass
=== modified file 'lib/lp/translations/configure.zcml'
--- lib/lp/translations/configure.zcml 2011-07-30 14:21:23 +0000
+++ lib/lp/translations/configure.zcml 2011-08-05 13:36:41 +0000
@@ -154,6 +154,10 @@
for="lp.registry.interfaces.packaging.IPackaging
lazr.lifecycle.interfaces.IObjectEvent"
handler=".model.translationsharingjob.schedule_packaging_job" />
+ <subscriber
+ for="lp.translations.interfaces.potemplate.IPOTemplate
+ lazr.lifecycle.interfaces.IObjectModifiedEvent"
+ handler=".model.translationsharingjob.schedule_potemplate_job" />
<facet
facet="translations">
@@ -643,6 +647,10 @@
class="lp.translations.model.translationpackagingjob.TranslationSplitJob">
<allow interface='lp.services.job.interfaces.job.IRunnableJob'/>
</class>
+ <class
+ class="lp.translations.model.translationpackagingjob.TranslationTemplateChangeJob">
+ <allow interface='lp.services.job.interfaces.job.IRunnableJob'/>
+ </class>
<utility
component="lp.translations.model.translationtemplatesbuildjob.TranslationTemplatesBuildJob"
provides="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJob"
=== modified file 'lib/lp/translations/interfaces/translationsharingjob.py'
--- lib/lp/translations/interfaces/translationsharingjob.py 2011-07-30 14:05:25 +0000
+++ lib/lp/translations/interfaces/translationsharingjob.py 2011-08-05 13:36:41 +0000
@@ -19,3 +19,6 @@
sourcepackagename = Attribute(
_("The sourcepackagename of the Packaging."))
+
+ potemplate = Attribute(
+ _("The POTemplate to pass around as the relevant template."))
=== modified file 'lib/lp/translations/model/translationpackagingjob.py'
--- lib/lp/translations/model/translationpackagingjob.py 2011-07-30 14:18:38 +0000
+++ lib/lp/translations/model/translationpackagingjob.py 2011-08-05 13:36:41 +0000
@@ -10,6 +10,7 @@
__all__ = [
'TranslationMergeJob',
'TranslationSplitJob',
+ 'TranslationTemplateChangeJob',
]
import logging
@@ -17,6 +18,7 @@
from lazr.lifecycle.interfaces import (
IObjectCreatedEvent,
IObjectDeletedEvent,
+ IObjectModifiedEvent,
)
import transaction
from zope.interface import (
@@ -40,7 +42,10 @@
TransactionManager,
TranslationMerger,
)
-from lp.translations.utilities.translationsplitter import TranslationSplitter
+from lp.translations.utilities.translationsplitter import (
+ TranslationSplitter,
+ TranslationTemplateSplitter,
+ )
class TranslationPackagingJob(TranslationSharingJobDerived, BaseRunnableJob):
@@ -117,3 +122,31 @@
'Splitting %s and %s', self.productseries.displayname,
self.sourcepackage.displayname)
TranslationSplitter(self.productseries, self.sourcepackage).split()
+
+
+class TranslationTemplateChangeJob(TranslationPackagingJob):
+ """Job for merging/splitting translations when template is changed."""
+
+ implements(IRunnableJob)
+
+ class_job_type = TranslationSharingJobType.TEMPLATE_CHANGE
+
+ create_on_event = IObjectModifiedEvent
+
+ @classmethod
+ def forPOTemplate(cls, potemplate):
+ """Create a TranslationTemplateChangeJob for a POTemplate.
+
+ :param potemplate: The `POTemplate` to create the job for.
+ :return: A `TranslationTemplateChangeJob`.
+ """
+ return cls.create(potemplate=potemplate)
+
+ def run(self):
+ """See `IRunnableJob`."""
+ logger = logging.getLogger()
+ logger.info("Sanitizing translations for '%s'" % (
+ self.potemplate.displayname))
+ TranslationTemplateSplitter(self.potemplate).split()
+ tm = TransactionManager(transaction.manager, False)
+ TranslationMerger.mergeModifiedTemplates(self.potemplate, tm)
=== modified file 'lib/lp/translations/model/translationsharingjob.py'
--- lib/lp/translations/model/translationsharingjob.py 2011-07-30 14:30:41 +0000
+++ lib/lp/translations/model/translationsharingjob.py 2011-08-05 13:36:41 +0000
@@ -37,6 +37,7 @@
from lp.translations.interfaces.translationsharingjob import (
ITranslationSharingJob,
)
+from lp.translations.model.potemplate import POTemplate
class TranslationSharingJobType(DBEnumeratedType):
@@ -54,6 +55,12 @@
Split translations between productseries and sourcepackage.
""")
+ TEMPLATE_CHANGE = DBItem(2, """
+ Split/merge translations for a single translation template.
+
+ Split/merge translations for a single translation template.
+ """)
+
class TranslationSharingJob(StormBase):
"""Base class for jobs related to a packaging."""
@@ -82,8 +89,12 @@
sourcepackagename = Reference(sourcepackagename_id, SourcePackageName.id)
+ potemplate_id = Int('potemplate')
+
+ potemplate = Reference(potemplate_id, POTemplate.id)
+
def __init__(self, job, job_type, productseries, distroseries,
- sourcepackagename):
+ sourcepackagename, potemplate=None):
""""Constructor.
:param job: The `Job` to use for storing basic job state.
@@ -96,6 +107,7 @@
self.distroseries = distroseries
self.sourcepackagename = sourcepackagename
self.productseries = productseries
+ self.potemplate = potemplate
class RegisteredSubclass(type):
@@ -143,16 +155,18 @@
self.job = job
@classmethod
- def create(cls, productseries, distroseries, sourcepackagename):
+ def create(cls, productseries=None, distroseries=None,
+ sourcepackagename=None, potemplate=None):
""""Create a TranslationPackagingJob backed by TranslationSharingJob.
:param productseries: The ProductSeries side of the Packaging.
:param distroseries: The distroseries of the Packaging sourcepackage.
:param sourcepackagename: The name of the Packaging sourcepackage.
+ :param potemplate: POTemplate to restrict to (if any).
"""
context = TranslationSharingJob(
Job(), cls.class_job_type, productseries,
- distroseries, sourcepackagename)
+ distroseries, sourcepackagename, potemplate)
return cls(context)
@classmethod
@@ -170,6 +184,27 @@
job_class.forPackaging(packaging)
@classmethod
+ def schedulePOTemplateJob(cls, potemplate, event):
+ """Event subscriber to create a TranslationSharingJob on events.
+
+ :param potemplate: The `POTemplate` to create
+ a `TranslationSharingJob` for.
+ :param event: The event itself.
+ """
+ if ('name' not in event.edited_fields and
+ 'productseries' not in event.edited_fields and
+ 'distroseries' not in event.edited_fields and
+ 'sourcepackagename' not in event.edited_fields):
+ # Ignore changes to POTemplates that are neither renames,
+ # nor moves to a different package/project.
+ return
+ for event_type, job_classes in cls._event_types.iteritems():
+ if not event_type.providedBy(event):
+ continue
+ for job_class in job_classes:
+ job_class.forPOTemplate(potemplate)
+
+ @classmethod
def iterReady(cls, extra_clauses):
"""See `IJobSource`.
@@ -207,3 +242,4 @@
#make accessible to zcml
schedule_packaging_job = TranslationSharingJobDerived.schedulePackagingJob
+schedule_potemplate_job = TranslationSharingJobDerived.schedulePOTemplateJob
=== modified file 'lib/lp/translations/scripts/tests/test_packaging_translations.py'
--- lib/lp/translations/scripts/tests/test_packaging_translations.py 2011-05-19 14:40:55 +0000
+++ lib/lp/translations/scripts/tests/test_packaging_translations.py 2011-08-05 13:36:41 +0000
@@ -37,6 +37,7 @@
INFO Merging .* and .* in Ubuntu Distroseries.*
INFO Deleted POTMsgSets: 1. TranslationMessages: 1.
INFO Splitting .* and .* in Ubuntu Distroseries.*
+ INFO 1 entries split.
INFO Ran 1 TranslationMergeJob jobs.
INFO Ran 1 TranslationSplitJob jobs.
"""))
=== modified file 'lib/lp/translations/tests/test_translationpackagingjob.py'
--- lib/lp/translations/tests/test_translationpackagingjob.py 2011-08-01 14:32:07 +0000
+++ lib/lp/translations/tests/test_translationpackagingjob.py 2011-08-05 13:36:41 +0000
@@ -8,12 +8,17 @@
import transaction
from zope.component import getUtility
+from zope.event import notify
+
+from lazr.lifecycle.event import ObjectModifiedEvent
+from lazr.lifecycle.snapshot import Snapshot
from canonical.launchpad.webapp.testing import verifyObject
from canonical.testing.layers import (
LaunchpadZopelessLayer,
)
from lp.registry.interfaces.packaging import IPackagingUtil
+from lp.translations.interfaces.potemplate import IPOTemplate
from lp.translations.model.translationsharingjob import (
TranslationSharingJob,
TranslationSharingJobDerived,
@@ -36,6 +41,7 @@
TranslationMergeJob,
TranslationPackagingJob,
TranslationSplitJob,
+ TranslationTemplateChangeJob,
)
from lp.translations.tests.test_translationsplitter import (
make_shared_potmsgset,
@@ -101,20 +107,32 @@
class JobFinder:
- def __init__(self, productseries, sourcepackage, job_class):
- self.productseries = productseries
- self.sourcepackagename = sourcepackage.sourcepackagename
- self.distroseries = sourcepackage.distroseries
+ def __init__(self, productseries, sourcepackage, job_class,
+ potemplate=None):
+ if potemplate is None:
+ self.productseries = productseries
+ self.sourcepackagename = sourcepackage.sourcepackagename
+ self.distroseries = sourcepackage.distroseries
+ self.potemplate = None
+ else:
+ self.potemplate = potemplate
self.job_type = job_class.class_job_type
def find(self):
- return list(TranslationSharingJobDerived.iterReady([
- TranslationSharingJob.productseries_id == self.productseries.id,
- (TranslationSharingJob.sourcepackagename_id ==
- self.sourcepackagename.id),
- TranslationSharingJob.distroseries_id == self.distroseries.id,
- TranslationSharingJob.job_type == self.job_type,
- ]))
+ if self.potemplate is None:
+ return list(TranslationSharingJobDerived.iterReady([
+ TranslationSharingJob.productseries_id == self.productseries.id,
+ (TranslationSharingJob.sourcepackagename_id ==
+ self.sourcepackagename.id),
+ TranslationSharingJob.distroseries_id == self.distroseries.id,
+ TranslationSharingJob.job_type == self.job_type,
+ ]))
+ else:
+ return list(
+ TranslationSharingJobDerived.iterReady([
+ TranslationSharingJob.potemplate_id == self.potemplate.id,
+ TranslationSharingJob.job_type == self.job_type,
+ ]))
class TestTranslationPackagingJob(TestCaseWithFactory):
@@ -273,3 +291,62 @@
packaging.distroseries)
(job,) = finder.find()
self.assertIsInstance(job, TranslationSplitJob)
+
+
+class TestTranslationTemplateChangeJob(TestCaseWithFactory):
+
+ layer = LaunchpadZopelessLayer
+
+ def test_modifyPOTemplate_makes_job(self):
+ """Creating a Packaging should make a TranslationMergeJob."""
+ potemplate = self.factory.makePOTemplate()
+ finder = JobFinder(
+ None, None, TranslationTemplateChangeJob, potemplate)
+ self.assertEqual([], finder.find())
+ with person_logged_in(potemplate.owner):
+ snapshot = Snapshot(potemplate, providing=IPOTemplate)
+ potemplate.name = self.factory.getUniqueString()
+ notify(ObjectModifiedEvent(potemplate, snapshot, ["name"]))
+
+ (job,) = finder.find()
+ self.assertIsInstance(job, TranslationTemplateChangeJob)
+
+ def test_splits_and_merges(self):
+ """Changing a template makes the translations split and then
+ re-merged in the new target sharing set."""
+ potemplate = self.factory.makePOTemplate(name='template')
+ other_ps = self.factory.makeProductSeries(
+ product=potemplate.productseries.product)
+ old_shared = self.factory.makePOTemplate(name='template',
+ productseries=other_ps)
+ new_shared = self.factory.makePOTemplate(name='renamed',
+ productseries=other_ps)
+
+ # Set up shared POTMsgSets and translations.
+ potmsgset = self.factory.makePOTMsgSet(potemplate, sequence=1)
+ potmsgset.setSequence(old_shared, 1)
+ self.factory.makeCurrentTranslationMessage(potmsgset=potmsgset)
+
+ # This is the identical English message in the new_shared template.
+ target_potmsgset = self.factory.makePOTMsgSet(
+ new_shared, sequence=1, singular=potmsgset.singular_text)
+
+ # Rename the template and confirm that messages are now shared
+ # with new_shared instead of old_shared.
+ potemplate.name = 'renamed'
+ job = TranslationTemplateChangeJob.create(potemplate=potemplate)
+
+ self.becomeDbUser('rosettaadmin')
+ job.run()
+
+ # New POTMsgSet is now different from the old one (it's been split),
+ # but matches the target potmsgset (it's been merged into it).
+ new_potmsgset = potemplate.getPOTMsgSets()[0]
+ self.assertNotEqual(potmsgset, new_potmsgset)
+ self.assertEqual(target_potmsgset, new_potmsgset)
+
+ # Translations have been merged as well.
+ self.assertContentEqual(
+ [tm.translations for tm in potmsgset.getAllTranslationMessages()],
+ [tm.translations
+ for tm in new_potmsgset.getAllTranslationMessages()])
=== modified file 'lib/lp/translations/tests/test_translationsplitter.py'
--- lib/lp/translations/tests/test_translationsplitter.py 2011-02-25 20:23:40 +0000
+++ lib/lp/translations/tests/test_translationsplitter.py 2011-08-05 13:36:41 +0000
@@ -13,6 +13,7 @@
)
from lp.translations.utilities.translationsplitter import (
TranslationSplitter,
+ TranslationTemplateSplitter,
)
@@ -77,8 +78,6 @@
splitter = make_translation_splitter(self.factory)
upstream_item, ubuntu_item = make_shared_potmsgset(
self.factory, splitter)
- ubuntu_template = ubuntu_item.potemplate
- ubuntu_sequence = ubuntu_item.sequence
new_potmsgset = splitter.splitPOTMsgSet(ubuntu_item)
self.assertEqual(new_potmsgset, ubuntu_item.potmsgset)
@@ -91,8 +90,7 @@
potmsgset=upstream_item.potmsgset,
potemplate=upstream_item.potemplate, diverged=True)
splitter.splitPOTMsgSet(ubuntu_item)
- upstream_translation = splitter.migrateTranslations(
- upstream_item.potmsgset, ubuntu_item)
+ splitter.migrateTranslations(upstream_item.potmsgset, ubuntu_item)
self.assertEqual(
upstream_message,
upstream_item.potmsgset.getAllTranslationMessages().one())
@@ -108,8 +106,7 @@
potmsgset=ubuntu_item.potmsgset,
potemplate=ubuntu_item.potemplate, diverged=True)
splitter.splitPOTMsgSet(ubuntu_item)
- upstream_translation = splitter.migrateTranslations(
- upstream_item.potmsgset, ubuntu_item)
+ splitter.migrateTranslations(upstream_item.potmsgset, ubuntu_item)
self.assertEqual(
ubuntu_message,
ubuntu_item.potmsgset.getAllTranslationMessages().one())
@@ -139,7 +136,7 @@
splitter = make_translation_splitter(self.factory)
upstream_item, ubuntu_item = make_shared_potmsgset(
self.factory, splitter)
- upstream_message = self.factory.makeCurrentTranslationMessage(
+ self.factory.makeCurrentTranslationMessage(
potmsgset=upstream_item.potmsgset,
potemplate=upstream_item.potemplate)
splitter.split()
@@ -153,3 +150,183 @@
upstream_item.potmsgset.getAllTranslationMessages().count(),
ubuntu_item.potmsgset.getAllTranslationMessages().count(),
)
+
+
+class TestTranslationTemplateSplitterBase:
+
+ layer = ZopelessDatabaseLayer
+
+ def getPOTMsgSetAndTemplateToSplit(self, splitter):
+ return [(tti1.potmsgset, tti1.potemplate)
+ for tti1, tti2 in splitter.findShared()]
+
+ def setUpSharingTemplates(self, other_side=False):
+ """Sets up two sharing templates with one sharing message and
+ one non-sharing message in each template."""
+ template1 = self.makePOTemplate()
+ template2 = self.makeSharingTemplate(template1, other_side)
+
+ shared_potmsgset = self.factory.makePOTMsgSet(template1, sequence=1)
+ shared_potmsgset.setSequence(template2, 1)
+
+ # POTMsgSets appearing in only one of the templates are not returned.
+ self.factory.makePOTMsgSet(template1, sequence=2)
+ self.factory.makePOTMsgSet(template2, sequence=2)
+ return template1, template2, shared_potmsgset
+
+ def makePOTemplate(self):
+ raise NotImplementedError('Subclasses should implement this.')
+
+ def makeSharingTemplate(self, template, other_side=False):
+ raise NotImplementedError('Subclasses should implement this.')
+
+ def test_findShared_renamed(self):
+ """Shared POTMsgSets are included for a renamed template."""
+ template1, template2, shared_potmsgset = self.setUpSharingTemplates()
+
+ splitter = TranslationTemplateSplitter(template2)
+ self.assertContentEqual([], splitter.findShared())
+
+ template2.name = 'renamed'
+ self.assertContentEqual(
+ [(shared_potmsgset, template1)],
+ self.getPOTMsgSetAndTemplateToSplit(splitter))
+
+ def test_findShared_moved_product(self):
+ """Moving a template to a different product splits its messages."""
+ template1, template2, shared_potmsgset = self.setUpSharingTemplates()
+
+ splitter = TranslationTemplateSplitter(template2)
+ self.assertContentEqual([], splitter.findShared())
+
+ # Move the template to a different product entirely.
+ template2.productseries = self.factory.makeProduct().development_focus
+ template2.distroseries = None
+ template2.sourcepackagename = None
+ self.assertContentEqual(
+ [(shared_potmsgset, template1)],
+ self.getPOTMsgSetAndTemplateToSplit(splitter))
+
+ def test_findShared_moved_distribution(self):
+ """Moving a template to a different distribution gets it split."""
+ template1, template2, shared_potmsgset = self.setUpSharingTemplates()
+
+ splitter = TranslationTemplateSplitter(template2)
+ self.assertContentEqual([], splitter.findShared())
+
+ # Move the template to a different distribution entirely.
+ sourcepackage = self.factory.makeSourcePackage()
+ template2.distroseries = sourcepackage.distroseries
+ template2.sourcepackagename = sourcepackage.sourcepackagename
+ template2.productseries = None
+ self.assertContentEqual(
+ [(shared_potmsgset, template1)],
+ self.getPOTMsgSetAndTemplateToSplit(splitter))
+
+ def test_findShared_moved_to_nonsharing_target(self):
+ """Moving a template to a target not sharing with the existing
+ upstreams and source package gets it split."""
+ template1, template2, shared_potmsgset = self.setUpSharingTemplates(
+ other_side=True)
+
+ splitter = TranslationTemplateSplitter(template2)
+ self.assertContentEqual([], splitter.findShared())
+
+ # Move the template to a different distribution entirely.
+ sourcepackage = self.factory.makeSourcePackage()
+ template2.distroseries = sourcepackage.distroseries
+ template2.sourcepackagename = sourcepackage.sourcepackagename
+ template2.productseries = None
+ self.assertContentEqual(
+ [(shared_potmsgset, template1)],
+ self.getPOTMsgSetAndTemplateToSplit(splitter))
+
+ def test_split_messages(self):
+ """Splitting messages works properly."""
+ template1, template2, shared_potmsgset = self.setUpSharingTemplates()
+
+ splitter = TranslationTemplateSplitter(template2)
+ self.assertContentEqual([], splitter.findShared())
+
+ # Move the template to a different product entirely.
+ template2.productseries = self.factory.makeProduct().development_focus
+ template2.distroseries = None
+ template2.sourcepackagename = None
+
+ other_item, this_item = splitter.findShared()[0]
+
+ splitter.split()
+
+ self.assertNotEqual(other_item.potmsgset, this_item.potmsgset)
+ self.assertEqual(shared_potmsgset, other_item.potmsgset)
+ self.assertNotEqual(shared_potmsgset, this_item.potmsgset)
+
+
+class TestProductTranslationTemplateSplitter(
+ TestCaseWithFactory, TestTranslationTemplateSplitterBase):
+ """Templates in a product get split appropriately."""
+
+ def makePOTemplate(self):
+ return self.factory.makePOTemplate(
+ name='template',
+ side=TranslationSide.UPSTREAM)
+
+ def makeSharingTemplate(self, template, other_side=False):
+ if other_side:
+ template2 = self.factory.makePOTemplate(
+ name='template',
+ side=TranslationSide.UBUNTU)
+ self.factory.makePackagingLink(
+ productseries=template.productseries,
+ distroseries=template2.distroseries,
+ sourcepackagename=template2.sourcepackagename)
+ return template2
+ else:
+ product = template.productseries.product
+ other_series = self.factory.makeProductSeries(product=product)
+ return self.factory.makePOTemplate(name='template',
+ productseries=other_series)
+
+
+class TestDistributionTranslationTemplateSplitter(
+ TestCaseWithFactory, TestTranslationTemplateSplitterBase):
+ """Templates in a distribution get split appropriately."""
+
+ def makePOTemplate(self):
+ return self.factory.makePOTemplate(
+ name='template',
+ side=TranslationSide.UBUNTU)
+
+ def makeSharingTemplate(self, template, other_side=False):
+ if other_side:
+ template2 = self.factory.makePOTemplate(
+ name='template',
+ side=TranslationSide.UPSTREAM)
+ self.factory.makePackagingLink(
+ productseries=template2.productseries,
+ distroseries=template.distroseries,
+ sourcepackagename=template.sourcepackagename)
+ return template2
+ else:
+ distro = template.distroseries.distribution
+ other_series = self.factory.makeDistroRelease(distribution=distro)
+ return self.factory.makePOTemplate(
+ name='template',
+ distroseries=other_series,
+ sourcepackagename=template.sourcepackagename)
+
+ def test_findShared_moved_sourcepackage(self):
+ """Moving a template to a different source package gets it split."""
+ template1, template2, shared_potmsgset = self.setUpSharingTemplates()
+
+ splitter = TranslationTemplateSplitter(template2)
+ self.assertContentEqual([], splitter.findShared())
+
+ # Move the template to a different source package inside the
+ # same distroseries.
+ sourcepackage = self.factory.makeSourcePackage(
+ distroseries=template2.distroseries)
+ template2.sourcepackagename = sourcepackage.sourcepackagename
+ self.assertContentEqual(
+ [(shared_potmsgset, template1)],
+ self.getPOTMsgSetAndTemplateToSplit(splitter))
=== modified file 'lib/lp/translations/translationmerger.py'
--- lib/lp/translations/translationmerger.py 2011-05-27 21:12:25 +0000
+++ lib/lp/translations/translationmerger.py 2011-08-05 13:36:41 +0000
@@ -387,6 +387,26 @@
merger = cls(templates, tm)
merger.mergePOTMsgSets()
+ @classmethod
+ def mergeModifiedTemplates(cls, potemplate, tm):
+ subset = getUtility(IPOTemplateSet).getSharingSubset(
+ distribution=potemplate.distribution,
+ sourcepackagename=potemplate.sourcepackagename,
+ product=potemplate.product)
+ templates = list(subset.getSharingPOTemplates(potemplate.name))
+ templates.sort(key=methodcaller('sharingKey'), reverse=True)
+ merger = cls(templates, tm)
+ merger.mergeAll()
+
+ def mergeAll(self):
+ """Properly merge POTMsgSets and TranslationMessages."""
+ self._removeDuplicateMessages()
+ self.tm.endTransaction(intermediate=True)
+ self.mergePOTMsgSets()
+ self.tm.endTransaction(intermediate=True)
+ self.mergeTranslationMessages()
+ self.tm.endTransaction()
+
def __init__(self, potemplates, tm):
"""Constructor.
@@ -548,7 +568,6 @@
deletions = 0
order_check.check(template)
potmsgset_ids = self._getPOTMsgSetIds(template)
- total_ids = len(potmsgset_ids)
for potmsgset_id in potmsgset_ids:
potmsgset = POTMsgSet.get(potmsgset_id)
=== modified file 'lib/lp/translations/utilities/translationsplitter.py'
--- lib/lp/translations/utilities/translationsplitter.py 2011-05-12 20:21:58 +0000
+++ lib/lp/translations/utilities/translationsplitter.py 2011-08-05 13:36:41 +0000
@@ -6,50 +6,30 @@
import logging
-from storm.locals import ClassAlias, Store
+from storm.expr import (
+ And,
+ Join,
+ LeftJoin,
+ Not,
+ Or,
+ )
+from storm.locals import (
+ ClassAlias,
+ Store,
+ )
import transaction
+from lp.registry.model.distroseries import DistroSeries
+from lp.registry.model.packaging import Packaging
+from lp.registry.model.productseries import ProductSeries
from lp.translations.model.potemplate import POTemplate
from lp.translations.model.translationtemplateitem import (
TranslationTemplateItem,
)
-class TranslationSplitter:
- """Split translations for a productseries, sourcepackage pair.
-
- If a productseries and sourcepackage were linked in error, and then
- unlinked, they may still share some translations. This class breaks those
- associations.
- """
-
- def __init__(self, productseries, sourcepackage):
- """Constructor.
-
- :param productseries: The `ProductSeries` to split from.
- :param sourcepackage: The `SourcePackage` to split from.
- """
- self.productseries = productseries
- self.sourcepackage = sourcepackage
-
- def findShared(self):
- """Provide tuples of upstream, ubuntu for each shared POTMsgSet."""
- store = Store.of(self.productseries)
- UpstreamItem = ClassAlias(TranslationTemplateItem, 'UpstreamItem')
- UpstreamTemplate = ClassAlias(POTemplate, 'UpstreamTemplate')
- UbuntuItem = ClassAlias(TranslationTemplateItem, 'UbuntuItem')
- UbuntuTemplate = ClassAlias(POTemplate, 'UbuntuTemplate')
- return store.find(
- (UpstreamItem, UbuntuItem),
- UpstreamItem.potmsgsetID == UbuntuItem.potmsgsetID,
- UbuntuItem.potemplateID == UbuntuTemplate.id,
- UbuntuTemplate.sourcepackagenameID ==
- self.sourcepackage.sourcepackagename.id,
- UbuntuTemplate.distroseriesID ==
- self.sourcepackage.distroseries.id,
- UpstreamItem.potemplateID == UpstreamTemplate.id,
- UpstreamTemplate.productseriesID == self.productseries.id,
- )
+class TranslationSplitterBase:
+ """Base class for translation splitting jobs."""
@staticmethod
def splitPOTMsgSet(ubuntu_item):
@@ -86,9 +66,151 @@
"""Split the translations for the ProductSeries and SourcePackage."""
logger = logging.getLogger()
shared = enumerate(self.findShared(), 1)
+ total = 0
for num, (upstream_item, ubuntu_item) in shared:
self.splitPOTMsgSet(ubuntu_item)
self.migrateTranslations(upstream_item.potmsgset, ubuntu_item)
if num % 100 == 0:
logger.info('%d entries split. Committing...', num)
transaction.commit()
+ total = num
+
+ if total % 100 != 0 or total == 0:
+ transaction.commit()
+ logger.info('%d entries split.', total)
+
+
+class TranslationSplitter(TranslationSplitterBase):
+ """Split translations for a productseries, sourcepackage pair.
+
+ If a productseries and sourcepackage were linked in error, and then
+ unlinked, they may still share some translations. This class breaks those
+ associations.
+ """
+
+ def __init__(self, productseries, sourcepackage):
+ """Constructor.
+
+ :param productseries: The `ProductSeries` to split from.
+ :param sourcepackage: The `SourcePackage` to split from.
+ """
+ self.productseries = productseries
+ self.sourcepackage = sourcepackage
+
+ def findShared(self):
+ """Provide tuples of upstream, ubuntu for each shared POTMsgSet."""
+ store = Store.of(self.productseries)
+ UpstreamItem = ClassAlias(TranslationTemplateItem, 'UpstreamItem')
+ UpstreamTemplate = ClassAlias(POTemplate, 'UpstreamTemplate')
+ UbuntuItem = ClassAlias(TranslationTemplateItem, 'UbuntuItem')
+ UbuntuTemplate = ClassAlias(POTemplate, 'UbuntuTemplate')
+ return store.find(
+ (UpstreamItem, UbuntuItem),
+ UpstreamItem.potmsgsetID == UbuntuItem.potmsgsetID,
+ UbuntuItem.potemplateID == UbuntuTemplate.id,
+ UbuntuTemplate.sourcepackagenameID ==
+ self.sourcepackage.sourcepackagename.id,
+ UbuntuTemplate.distroseriesID ==
+ self.sourcepackage.distroseries.id,
+ UpstreamItem.potemplateID == UpstreamTemplate.id,
+ UpstreamTemplate.productseriesID == self.productseries.id,
+ )
+
+
+class TranslationTemplateSplitter(TranslationSplitterBase):
+ """Split translations for an extracted potemplate.
+
+ When a POTemplate is removed from a set of sharing templates,
+ it keeps sharing POTMsgSets with other templates. This class
+ removes those associations.
+ """
+
+ def __init__(self, potemplate):
+ """Constructor.
+
+ :param potemplate: The `POTemplate` to sanitize.
+ """
+ self.potemplate = potemplate
+
+ def findShared(self):
+ """Provide tuples of (other, this) items for each shared POTMsgSet.
+
+ Only return those that are shared but shouldn't be because they
+ are now in non-sharing templates.
+ """
+ store = Store.of(self.potemplate)
+ ThisItem = ClassAlias(TranslationTemplateItem, 'ThisItem')
+ OtherItem = ClassAlias(TranslationTemplateItem, 'OtherItem')
+ OtherTemplate = ClassAlias(POTemplate, 'OtherTemplate')
+
+ tables = [
+ OtherTemplate,
+ Join(OtherItem, OtherItem.potemplateID == OtherTemplate.id),
+ Join(ThisItem,
+ And(ThisItem.potmsgsetID == OtherItem.potmsgsetID,
+ ThisItem.potemplateID == self.potemplate.id)),
+ ]
+
+ if self.potemplate.productseries is not None:
+ # If the template is now in a product, we look for all
+ # effectively sharing templates that are in *different*
+ # products, or that are in a sourcepackage which is not
+ # linked (through Packaging table) with this product.
+ ps = self.potemplate.productseries
+ productseries_join = LeftJoin(
+ ProductSeries,
+ ProductSeries.id == OtherTemplate.productseriesID)
+ packaging_join = LeftJoin(
+ Packaging,
+ And(Packaging.productseriesID == ps.id,
+ (Packaging.sourcepackagenameID ==
+ OtherTemplate.sourcepackagenameID),
+ Packaging.distroseriesID == OtherTemplate.distroseriesID
+ ))
+ tables.extend([productseries_join, packaging_join])
+ # Template should not be sharing if...
+ other_clauses = Or(
+ # The name is different, or...
+ OtherTemplate.name != self.potemplate.name,
+ # It's in a different product, or...
+ And(Not(ProductSeries.id == None),
+ ProductSeries.productID != ps.productID),
+ # There is no link between this product series and
+ # a source package the template is in.
+ And(Not(OtherTemplate.distroseriesID == None),
+ Packaging.id == None))
+ else:
+ # If the template is now in a source package, we look for all
+ # effectively sharing templates that are in *different*
+ # distributions or source packages, or that are in a product
+ # which is not linked with this source package.
+ ds = self.potemplate.distroseries
+ spn = self.potemplate.sourcepackagename
+ distroseries_join = LeftJoin(
+ DistroSeries,
+ DistroSeries.id == OtherTemplate.distroseriesID)
+ packaging_join = LeftJoin(
+ Packaging,
+ And(Packaging.distroseriesID == ds.id,
+ Packaging.sourcepackagenameID == spn.id,
+ Packaging.productseriesID == OtherTemplate.productseriesID
+ ))
+ tables.extend([distroseries_join, packaging_join])
+ # Template should not be sharing if...
+ other_clauses = Or(
+ # The name is different, or...
+ OtherTemplate.name != self.potemplate.name,
+ # It's in a different distribution or source package, or...
+ And(Not(DistroSeries.id == None),
+ Or(DistroSeries.distributionID != ds.distributionID,
+ OtherTemplate.sourcepackagenameID != spn.id)),
+ # There is no link between this source package and
+ # a product the template is in.
+ And(Not(OtherTemplate.productseriesID == None),
+ Packaging.id == None))
+
+ return store.using(*tables).find(
+ (OtherItem, ThisItem),
+ OtherTemplate.id != self.potemplate.id,
+ other_clauses,
+ )
Follow ups