summaryrefslogtreecommitdiff
path: root/src/mailman/database
diff options
context:
space:
mode:
authorAurélien Bompard2016-02-02 18:10:18 +0100
committerBarry Warsaw2016-02-29 21:52:13 -0500
commit994660913bbd7dc08b8cef909b6715f43d37f0d5 (patch)
treed17930b6d325f2d785883dc17ea71cf6eaef848f /src/mailman/database
parent9bf90986117e39450ec5bf1f86d29e5ed91f480d (diff)
downloadmailman-994660913bbd7dc08b8cef909b6715f43d37f0d5.tar.gz
mailman-994660913bbd7dc08b8cef909b6715f43d37f0d5.tar.zst
mailman-994660913bbd7dc08b8cef909b6715f43d37f0d5.zip
Diffstat (limited to 'src/mailman/database')
-rw-r--r--src/mailman/database/alembic/versions/cb7fc8476779_header_match_chain_renamed_to_action.py57
-rw-r--r--src/mailman/database/tests/test_migrations.py43
2 files changed, 100 insertions, 0 deletions
diff --git a/src/mailman/database/alembic/versions/cb7fc8476779_header_match_chain_renamed_to_action.py b/src/mailman/database/alembic/versions/cb7fc8476779_header_match_chain_renamed_to_action.py
new file mode 100644
index 000000000..45a09b936
--- /dev/null
+++ b/src/mailman/database/alembic/versions/cb7fc8476779_header_match_chain_renamed_to_action.py
@@ -0,0 +1,57 @@
+"""HeaderMatch chain renamed to action
+
+Revision ID: cb7fc8476779
+Revises: d4fbb4fd34ca
+Create Date: 2016-02-02 17:23:36.199207
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = 'cb7fc8476779'
+down_revision = 'd4fbb4fd34ca'
+
+import sqlalchemy as sa
+from alembic import op
+from mailman.database.helpers import is_sqlite, exists_in_db
+from mailman.database.types import Enum
+from mailman.interfaces.action import Action
+
+
+# Don't import the table definition from the models, it may break this
+# migration when the model is updated in the future (see the Alembic doc)
+hm_table = sa.sql.table('headermatch',
+ sa.sql.column('action', Enum(Action)),
+ sa.sql.column('chain', sa.VARCHAR())
+ )
+
+
+def upgrade():
+ if not exists_in_db(op.get_bind(), 'headermatch', 'action'):
+ op.add_column(
+ 'headermatch', sa.Column('action', Enum(Action), nullable=True))
+
+ # Now migrate the data
+ for action_enum in Action:
+ op.execute(hm_table.update(
+ ).values(action=action_enum
+ ).where(hm_table.c.chain == action_enum.name))
+ # Now that data is migrated, drop the old column (except on SQLite which
+ # does not support this)
+ if not is_sqlite(op.get_bind()):
+ op.drop_column('headermatch', 'chain')
+
+
+def downgrade():
+ if not exists_in_db(op.get_bind(), 'headermatch', 'chain'):
+ op.add_column(
+ 'headermatch', sa.Column('chain', sa.VARCHAR(), nullable=True))
+
+ # Now migrate the data
+ for action_enum in Action:
+ op.execute(hm_table.update(
+ ).values(chain=action_enum.name
+ ).where(hm_table.c.action == action_enum))
+ # Now that data is migrated, drop the new column (except on SQLite which
+ # does not support this)
+ if not is_sqlite(op.get_bind()):
+ op.drop_column('headermatch', 'action')
diff --git a/src/mailman/database/tests/test_migrations.py b/src/mailman/database/tests/test_migrations.py
index c3558abea..1791a2453 100644
--- a/src/mailman/database/tests/test_migrations.py
+++ b/src/mailman/database/tests/test_migrations.py
@@ -33,6 +33,9 @@ from mailman.database.alembic import alembic_cfg
from mailman.database.helpers import exists_in_db
from mailman.database.model import Model
from mailman.database.transaction import transaction
+from mailman.database.types import Enum
+from mailman.interfaces.action import Action
+from mailman.interfaces.mailinglist import IHeaderMatchList
from mailman.testing.layers import ConfigLayer
@@ -223,3 +226,43 @@ class TestMigrations(unittest.TestCase):
os.path.join(config.LIST_DATA_DIR, 'ant@example.com')))
self.assertTrue(os.path.exists(ant.data_path))
self.assertTrue(os.path.exists(bee.data_path))
+
+ def test_cb7fc8476779_header_match_action(self):
+ # Create a mailing list through the standard API.
+ with transaction():
+ ant = create_list('ant@example.com')
+ # Create header matches
+ header_matches = IHeaderMatchList(ant)
+ header_matches.append('header-1', 'pattern', Action.accept)
+ header_matches.append('header-2', 'pattern', Action.hold)
+ header_matches.append('header-3', 'pattern', Action.discard)
+ header_matches.append('header-4', 'pattern', Action.reject)
+ hm_table = sa.sql.table(
+ 'headermatch',
+ sa.sql.column('action', Enum(Action)),
+ sa.sql.column('chain', sa.Unicode)
+ )
+ # Downgrade and verify that the chain names are correct.
+ with transaction():
+ alembic.command.downgrade(alembic_cfg, 'd4fbb4fd34ca')
+ results = config.db.store.execute(
+ hm_table.select()).fetchall()
+ self.assertEqual(len(results), 4)
+ for action, chain in results:
+ self.assertEqual(action.name, chain)
+ # Clear the previous values for testing.
+ with transaction():
+ config.db.store.execute(
+ hm_table.update().values(action=None))
+ for action, chain in config.db.store.execute(
+ hm_table.select()).fetchall():
+ self.assertEqual(action, None)
+ # Upgrade and verify that the actions are back to normal.
+ with transaction():
+ alembic.command.upgrade(alembic_cfg, 'cb7fc8476779')
+ results = config.db.store.execute(
+ hm_table.select()).fetchall()
+ self.assertEqual(len(results), 4)
+ for action, chain in results:
+ self.assertIsNotNone(action)
+ self.assertEqual(action.name, chain)