--- a
+++ b/pyforge/flyway/migrate.py
@@ -0,0 +1,68 @@
+import logging
+
+log = logging.getLogger(__name__)
+
+class MigrationMeta(type):
+ '''Metaclass providing a registry of migrations.
+
+ If the class-level variable _current_migrations_module is
+ defined, then migrations will be registered according to that
+ module and their declared version. (The migrate command
+ sets this module according to the migration's entry point name.)
+ '''
+
+ def __init__(cls, name, bases, dct):
+ if cls._current_migrations_module is None: return
+ cls.migrations_registry[
+ cls._current_migrations_module, cls.version] = cls
+ cls.module = cls._current_migrations_module
+
+ def get(cls, module, version):
+ '''Load a Migration class from the registry'''
+ return cls.migrations_registry[module, version]
+
+ def latest_versions(cls):
+ result = {}
+ for k,v in cls.migrations_registry:
+ if result.get(k, -1) < v:
+ result[k] = v
+ return result
+
+class Migration(object):
+ __metaclass__ = MigrationMeta
+ version = 0
+ module = None # filled in automatically by Metaclass
+ migrations_registry = {}
+ _current_migrations_module = None
+
+
+ def __init__(self, session):
+ self.session = session
+
+ def requires(self):
+ '''Returns a list of requirements that must be met before upgrading to
+ this migration. By default, returns the previous-versioned migration'''
+ return [ (self.module, self.version-1) ]
+
+ def up(self):
+ '''Upgrade to a new schema version'''
+ raise NotImplementedError, 'up'
+
+ def down(self):
+ '''Downgrade from this schema version (undo an 'up') '''
+ raise NotImplementedError, 'down'
+
+ def ensure_index(self, cls, fields, **kwargs):
+ '''Ensures that a particular index has been created in the DB'''
+ self.session.ensure_index(cls, fields, **kwargs)
+
+ def drop_index(self, cls, fields):
+ '''Ensures that a particular index has been dropped from the DB'''
+ self.session.drop_index(cls, fields)
+
+ def set_indexes(self, cls):
+ '''Ensures that a the only indexes on a class are those defined in its
+ __mongometa__ attribute.'''
+ self.session.drop_indexes(cls)
+ self.session.ensure_indexes(cls)
+