Author: astaric
Date: Wed Apr 24 11:17:27 2013
New Revision: 1471368
URL: http://svn.apache.org/r1471368
Log:
More robust upgrade of attachments.
Can handle orphan attachments. When system wikis are duplicated
to the product env, attachment are copied as well. New tests.
Modified:
bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py
bloodhound/trunk/bloodhound_multiproduct/tests/upgrade.py
Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py?rev=1471368&r1=1471367&r2=1471368&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/api.py Wed Apr 24
11:17:27 2013
@@ -295,11 +295,18 @@ class MultiProductSystem(Component):
for table in TICKET_TABLES:
if table == 'attachment':
- db("""UPDATE attachment
- SET product=(SELECT ticket.product FROM ticket
- WHERE ticket.id=%s)
- WHERE attachment.type='ticket'
- """ %(db.cast('attachment.id', 'integer'),))
+ db("""
+ UPDATE attachment
+ SET product=(SELECT ticket.product
+ FROM ticket
+ WHERE %(ticket_id)s=attachment.id
+ LIMIT 1)
+ WHERE attachment.type='ticket'
+ AND EXISTS(SELECT ticket.product
+ FROM ticket
+ WHERE %(ticket_id)s=attachment.id)
+ """ % dict(
+ ticket_id=db.cast('attachment.id', 'text')))
else:
db("""UPDATE %s
SET product=(SELECT ticket.product FROM ticket
WHERE ticket.id=%s.ticket)""" %
@@ -334,9 +341,14 @@ class MultiProductSystem(Component):
temp_table_name, cols = create_temp_table(table)
self.log.info("Migrating wikis to global context")
db("""INSERT INTO %s (%s, product) SELECT %s, '' FROM %s""" %
- (table, cols, cols, temp_table_name))
+ (table, cols, cols, temp_table_name))
+ db("""UPDATE attachment
+ SET product=''
+ WHERE attachment.type='wiki'""")
+
for wiki_name, wiki_version, wiki_product in db("""
SELECT name, version, product FROM %s""" % table):
+ attachment_cols = ','.join(table_columns['attachment'])
if wiki_name in self.system_wiki_list:
for product in all_products:
db("""INSERT INTO %s (%s, product)
@@ -344,6 +356,20 @@ class MultiProductSystem(Component):
WHERE name='%s' AND version=%s AND
product='%s'""" %
(table, cols, cols, product.prefix, table,
wiki_name, wiki_version, wiki_product))
+ db("""INSERT INTO attachment (%(cols)s, product)
+ SELECT %(cols)s, '%(new_product)s'
+ FROM attachment a
+ WHERE type='wiki'
+ AND id='%(wiki_name)s'
+ AND product='%(old_product)s'
+ AND NOT EXISTS(SELECT * FROM attachment
+ WHERE type='wiki'
+ AND id='%(wiki_name)s'
+ AND
product='%(new_product)s')
+ """ % dict(cols=attachment_cols,
+ wiki_name=wiki_name,
+ old_product=wiki_product,
+ new_product=product.prefix))
else:
self.log.info("Moving wiki page '%s' to default
product", wiki_name)
db("""UPDATE wiki
@@ -351,13 +377,14 @@ class MultiProductSystem(Component):
WHERE name='%s' AND version=%s AND
product='%s'""" %
(DEFAULT_PRODUCT,
wiki_name, wiki_version, wiki_product))
+ db("""UPDATE attachment
+ SET product='%s'
+ WHERE type='wiki'
+ AND id='%s'
+ AND product='%s'
+ """ % (DEFAULT_PRODUCT, wiki_name, wiki_product))
drop_temp_table(temp_table_name)
- db("""UPDATE attachment
- SET product=(SELECT wiki.product FROM wiki
- WHERE wiki.name=attachment.id)
- WHERE attachment.type='wiki'""")
-
# soft link existing repositories to default product
repositories_linked = []
for id, name in db("""SELECT id, value FROM repository
Modified: bloodhound/trunk/bloodhound_multiproduct/tests/upgrade.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/tests/upgrade.py?rev=1471368&r1=1471367&r2=1471368&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/tests/upgrade.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/tests/upgrade.py Wed Apr 24
11:17:27 2013
@@ -121,16 +121,16 @@ class EnvironmentUpgradeTestCase(unittes
with self.env.db_direct_transaction as db:
for i in range(5):
db("INSERT INTO dummy_table (v1) VALUES ('%d')" % i)
- rows = db("SELECT * FROM dummy_table")
- self.assertEqual(len(rows), 5)
+ self.assertEqual(
+ len(db("SELECT * FROM dummy_table")), 5)
self._enable_multiproduct()
self.env.upgrade()
with self.env.db_direct_transaction as db:
- rows = db('SELECT * FROM "dummy_table"')
- self.assertEqual(len(rows), 5)
- rows = db('SELECT * FROM "@_dummy_table"')
- self.assertEqual(len(rows), 0)
+ self.assertEqual(
+ len(db('SELECT * FROM "dummy_table"')), 5)
+ self.assertEqual(
+ len(db('SELECT * FROM "@_dummy_table"')), 0)
def test_creating_new_product_calls_environment_created(self):
self._enable_component(DummyPlugin)
@@ -143,6 +143,81 @@ class EnvironmentUpgradeTestCase(unittes
with self.env.db_direct_transaction as db:
db('SELECT * FROM "p1_dummy_table"')
+ def test_upgrade_moves_tickets_to_default_product(self):
+ with self.env.db_direct_transaction as db:
+ db("""INSERT INTO ticket (id) VALUES (1)""")
+ db("""INSERT INTO attachment (type, id)
+ VALUES ('ticket', '1')""")
+
+ self._enable_multiproduct()
+ self.env.upgrade()
+
+ with self.env.db_direct_transaction as db:
+ self.assertEqual(
+ len(db("""SELECT * FROM ticket WHERE product='@'""")), 1)
+ self.assertEqual(
+ len(db("""SELECT * FROM attachment
+ WHERE product='@'
+ AND type='ticket'""")), 1)
+
+ def test_upgrade_moves_wikis_to_default_product(self):
+ with self.env.db_direct_transaction as db:
+ db("""INSERT INTO wiki (name, version) VALUES ('MyPage', 1)""")
+ db("""INSERT INTO attachment (type, id)
+ VALUES ('wiki', 'MyPage')""")
+
+ self._enable_multiproduct()
+ self.env.upgrade()
+
+ with self.env.db_direct_transaction as db:
+ self.assertEqual(
+ len(db("""SELECT * FROM wiki WHERE product='@'""")), 1)
+ self.assertEqual(
+ len(db("""SELECT * FROM attachment
+ WHERE product='@'
+ AND type='wiki'""")), 1)
+
+ def test_upgrade_duplicates_system_wikis_to_products(self):
+ with self.env.db_direct_transaction as db:
+ db("""INSERT INTO wiki (name, version) VALUES ('WikiStart', 1)""")
+ db("""INSERT INTO attachment (type, id)
+ VALUES ('wiki', 'WikiStart')""")
+
+ self._enable_multiproduct()
+ self.env.upgrade()
+
+ with self.env.db_direct_transaction as db:
+ self.assertEqual(
+ len(db("""SELECT * FROM wiki WHERE product='@'""")), 1)
+ self.assertEqual(
+ len(db("""SELECT * FROM attachment
+ WHERE product='@'
+ AND type='wiki'""")), 1)
+ self.assertEqual(
+ len(db("""SELECT * FROM wiki WHERE product=''""")), 1)
+ self.assertEqual(
+ len(db("""SELECT * FROM attachment
+ WHERE product=''
+ AND type='wiki'""")), 1)
+
+ def test_can_upgrade_database_with_orphaned_attachments(self):
+ with self.env.db_direct_transaction as db:
+ db("""INSERT INTO attachment (id, type)
+ VALUES ('5', 'ticket')""")
+ db("""INSERT INTO attachment (id, type)
+ VALUES ('MyWiki', 'wiki')""")
+
+ self._enable_multiproduct()
+ self.env.upgrade()
+
+ def test_can_upgrade_database_with_text_attachment_ids(self):
+ with self.env.db_direct_transaction as db:
+ db("""INSERT INTO attachment (id, type)
+ VALUES ('abc', 'ticket')""")
+
+ self._enable_multiproduct()
+ self.env.upgrade()
+
def _enable_multiproduct(self):
self.env.config.set('components', 'multiproduct.*', 'enabled')
self.env.config.save()