Esempio n. 1
0
 def test_rollback_to_rev_id(self):
     wd = WorkDirectory(self.work_dir)
     migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
     self.assertIsNone(migr_ctx.head)
     one = gen_rev_id()
     two = gen_rev_id()
     three = gen_rev_id()
     revisions = [
         Revision(one,
                  "adding table foo",
                  datetime.now(),
                  upgrade_sql="create table test.foo (a string);",
                  downgrade_sql="drop table test.foo;"),
         Revision(two,
                  "adding table bar",
                  datetime.now(),
                  upgrade_sql="create table test.bar (a string);",
                  downgrade_sql="drop table test.bar;"),
         Revision(three,
                  "add column b foo",
                  datetime.now(),
                  upgrade_sql="alter table test.foo add column b string;",
                  downgrade_sql="alter table test.foo drop column b;")
     ]
     for rev in revisions:
         wd.add_revision(rev)
     runner = CliRunner()
     res = runner.invoke(upgrade)
     self.assertTrue(res.exit_code == 0)
     self.assertIsNotNone(migr_ctx.head)
     self.assertTrue(len(migr_ctx.revisions) == 3)
     res = runner.invoke(rollback, ['-r', two])
     self.assertTrue(res.exit_code == 0)
     self.assertTrue(len(migr_ctx.revisions) == 1)
Esempio n. 2
0
 def test_rollback_step_cmd(self):
     wd = WorkDirectory(self.work_dir)
     migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
     self.assertIsNone(migr_ctx.head)
     runner = CliRunner()
     wd.add_revision(
         Revision(gen_rev_id(),
                  "adding table foo",
                  datetime.now(),
                  upgrade_sql="create table test.foo (a string);",
                  downgrade_sql="drop table test.foo"))
     res = runner.invoke(upgrade)
     self.assertTrue(res.exit_code == 0)
     wd.add_revision(
         Revision(gen_rev_id(),
                  "adding table bar",
                  datetime.now(),
                  upgrade_sql="create table test.bar (a string);",
                  downgrade_sql="drop table test.bar"))
     res = runner.invoke(upgrade)
     self.assertTrue(res.exit_code == 0)
     self.assertIsNotNone(migr_ctx.head)
     self.assertTrue(len(migr_ctx.revisions) == 2)
     res = runner.invoke(rollback, ['-n', 2])
     self.assertIsNone(migr_ctx.head)
Esempio n. 3
0
def ensure_init():
    ensure_setup()
    config = Config.from_file(MROLL_CONFIG_FILE)
    wd = WorkDirectory(config.work_dir)
    try:
        ctx = create_migration_ctx(wd.get_migration_ctx_config())
        head = ctx.head
    except:
        raise SystemExit("Error: mroll not initialized! Run init command first.")
Esempio n. 4
0
 def test_upgrade_raise(self):
     wd = WorkDirectory(self.work_dir)
     migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
     self.assertIsNone(migr_ctx.head)
     wd.add_revision(
         Revision(gen_rev_id(), "adding table foo", datetime.now()))
     self.assertTrue(len(wd.revisions) == 1)
     runner = CliRunner()
     res = runner.invoke(upgrade)
     self.assertTrue(res.exit_code == 1)
 def test_migr_ctx_head(self):
     wd = WorkDirectory(path=self.work_dir)
     ctx = create_migration_ctx(wd.get_migration_ctx_config())
     ctx.create_revisions_tbl()
     self.assertIsNone(ctx.head)
     conn = pymonetdb.connect(self.db_name)
     sql = """insert into sys.mroll_revisions values ('{}', '{}', '{}')""".format(
         gen_rev_id(), "bla bla", datetime.now())
     conn.execute(sql)
     conn.commit()
     self.assertIsNotNone(ctx.head)
 def test_ctx_revisions(self):
     wd = WorkDirectory(path=self.work_dir)
     ctx = create_migration_ctx(wd.get_migration_ctx_config())
     ctx.create_revisions_tbl()
     self.assertTrue(len(ctx.revisions) == 0)
     conn = pymonetdb.connect(self.db_name)
     sql = """insert into sys.mroll_revisions values ('{}', '{}', '{}'), ('{}', '{}', '{}');""".format(
         gen_rev_id(), "revision 1", datetime.now(), gen_rev_id(),
         "revision 2", datetime.now())
     conn.execute(sql)
     conn.commit()
     self.assertTrue(len(ctx.revisions) == 2)
Esempio n. 7
0
def applied_revisions(show_patch=False):
    config = Config.from_file(MROLL_CONFIG_FILE)
    wd = WorkDirectory(config.work_dir)
    migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
    if migr_ctx.head is None:
        print('No revisions have being applied yet!')
        return
    # create lookup
    lookup = {}
    for r in migr_ctx.revisions:
        lookup[r.id] = r
    working_set: List[Revision] = list(filter(lambda rev: lookup.get(rev.id, None) is not None, wd.revisions))
    for rev in working_set:
        if show_patch:
            print(rev.serialize())
        else:
            print(rev)
Esempio n. 8
0
def rollback(step, rev_id):
    """
    Downgrades to previous revision by default. 
    """
    ensure_init()
    config = Config.from_file(MROLL_CONFIG_FILE)
    wd = WorkDirectory(config.work_dir)
    migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
    if migr_ctx.head is None:
        raise SystemExit('Nothing to do!')
    # create lookup
    lookup = {}
    for r in migr_ctx.revisions:
        lookup[r.id] = r
    working_set: List[Revision] = list(filter(lambda rev: lookup.get(rev.id, None) is not None, wd.revisions))
    count = 0
    buff=[]
    for rev in reversed(working_set):
        if rev_id is None and count==step:
            break
        if rev_id is not None:
            if rev.id == rev_id:
                buff.append(rev)
                break
        buff.append(rev)
        count+=1
    working_set: List[Revision] = [] + buff
     # insure idempotency
    for rev in working_set:
        if rev.downgrade_sql is None:
            msg="""
                Error: No downgrade sql script @{}!
                """.format(rev.id)
            if rev.upgrade_sql is not None:
                msg="""
                Error: No downgrade sql script @{}, while there is a
                upgrade sql:
                {}
                Scripts should be idempotent.
                """.format(rev.id, rev.upgrade_sql)
            raise SystemExit(msg)
    try:
        migr_ctx.remove_revisions(working_set)
    except RevisionOperationError as e:
        raise SystemExit(repr(e))
    print('Done')
Esempio n. 9
0
def pending_revisions(show_patch=False):
    """
    Shows pending revisions not yet applied.
    """
    config = Config.from_file(MROLL_CONFIG_FILE)
    wd = WorkDirectory(config.work_dir)
    migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
    # create lookup
    lookup = {}
    for r in migr_ctx.revisions:
        lookup[r.id] = r
    working_set: List[Revision] = list(filter(lambda rev: lookup.get(rev.id, None) is None, wd.revisions))
    for r in working_set:
        if show_patch:
            print(r.serialize())
        else:
            print(r)
Esempio n. 10
0
 def test_rollback_raises(self):
     wd = WorkDirectory(self.work_dir)
     migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
     self.assertIsNone(migr_ctx.head)
     runner = CliRunner()
     # add revison with no downgrade_sql
     wd.add_revision(
         Revision(
             gen_rev_id(),
             "adding table foo",
             datetime.now(),
             upgrade_sql="create table test.foo (a string);",
         ))
     res = runner.invoke(upgrade)
     self.assertTrue(res.exit_code == 0)
     self.assertIsNotNone(migr_ctx.head)
     self.assertTrue(len(migr_ctx.revisions) == 1)
     res = runner.invoke(rollback)
     self.assertNotEqual(res.exit_code, 0)
 def test_ctx_add_revisions(self):
     wd = WorkDirectory(path=self.work_dir)
     ctx = create_migration_ctx(wd.get_migration_ctx_config())
     ctx.create_revisions_tbl()
     self.assertTrue(len(ctx.revisions) == 0)
     revisions = [
         Revision(gen_rev_id(),
                  "adding table foo",
                  datetime.now(),
                  upgrade_sql="create table test.foo (a string);",
                  downgrade_sql="drop table test.foo;"),
         Revision(gen_rev_id(),
                  "adding table bar",
                  datetime.now(),
                  upgrade_sql="create table test.bar (a string);",
                  downgrade_sql="drop table test.bar;")
     ]
     ctx.add_revisions(revisions)
     self.assertTrue(len(ctx.revisions) == 2)
Esempio n. 12
0
 def test_show_pending_revisions(self):
     wd = WorkDirectory(self.work_dir)
     wd.add_revision(
         Revision(gen_rev_id(),
                  "adding table bar",
                  datetime.now(),
                  upgrade_sql="create table test.bar (a string);",
                  downgrade_sql="drop table test.bar;"))
     self.assertTrue(len(wd.revisions) == 1)
     runner = CliRunner()
     res = runner.invoke(upgrade)
     self.assertTrue(res.exit_code == 0)
     migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
     self.assertIsNotNone(migr_ctx.head)
     self.assertTrue(len(migr_ctx.revisions) == 1)
     self.add_rev_cmd('add column a to bar')
     self.add_rev_cmd('add column a to baz')
     self.assertTrue(len(wd.revisions) == 3)
     res = runner.invoke(show, ['pending'])
     self.assertTrue(res.exit_code == 0)
Esempio n. 13
0
 def test_rollback_default_cmd(self):
     # test rollback no cli options
     wd = WorkDirectory(self.work_dir)
     migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
     self.assertIsNone(migr_ctx.head)
     rev = Revision(gen_rev_id(),
                    "adding table foo",
                    datetime.now(),
                    upgrade_sql="create table test.foo (a string);",
                    downgrade_sql="drop table test.foo;")
     wd.add_revision(rev)
     self.assertTrue(len(wd.revisions) == 1)
     runner = CliRunner()
     res = runner.invoke(upgrade)
     self.assertTrue(res.exit_code == 0)
     self.assertIsNotNone(migr_ctx.head)
     self.assertTrue(len(migr_ctx.revisions) == 1)
     res = runner.invoke(rollback)
     self.assertTrue(res.exit_code == 0)
     self.assertIsNone(migr_ctx.head)
     self.assertTrue(len(migr_ctx.revisions) == 0)
Esempio n. 14
0
def init():
    """
    Creates mroll_revisions tbl. Should be run once.
    """
    ensure_setup()
    config = Config.from_file(MROLL_CONFIG_FILE)
    wd = WorkDirectory(config.work_dir)
    migr_ctx_config = wd.get_migration_ctx_config()
    migr_ctx = create_migration_ctx(migr_ctx_config)
    try:
        # if following succeeds then mroll revisons tbl exist.
        migr_ctx.head
        return print("Nothing to do! Mroll revisions table already exist.")
    except:
        pass
    try:
        migr_ctx.create_revisions_tbl()
    except Exception as e:
        raise SystemExit(e)
    print('{} table created'.format(migr_ctx_config.tbl_name))
    print('Done')
Esempio n. 15
0
 def test_upgrade_num_command(self):
     # Test upgrade cmd with a step
     wd = WorkDirectory(self.work_dir)
     revisions = [
         Revision(gen_rev_id(),
                  "adding table foo",
                  datetime.now(),
                  upgrade_sql="create table test.foo (a string);",
                  downgrade_sql="drop table test.foo;"),
         Revision(gen_rev_id(),
                  "adding table bar",
                  datetime.now(),
                  upgrade_sql="create table test.bar (a string);",
                  downgrade_sql="drop table test.bar;")
     ]
     for rev in revisions:
         wd.add_revision(rev)
     self.assertTrue(len(wd.revisions) == 2)
     runner = CliRunner()
     res = runner.invoke(upgrade, ['-n', 1])
     self.assertTrue(res.exit_code == 0)
     migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
     self.assertIsNotNone(migr_ctx.head)
     self.assertTrue(len(migr_ctx.revisions) == 1)
Esempio n. 16
0
def upgrade(step):
    """
    Applies revisions in work dir not yet applied.
    """ 
    ensure_init()
    config = Config.from_file(MROLL_CONFIG_FILE)
    wd = WorkDirectory(config.work_dir)
    migr_ctx = create_migration_ctx(wd.get_migration_ctx_config())
    # create lookup
    lookup = {}
    for r in migr_ctx.revisions:
        lookup[r.id] = r
    working_set: List[Revision] = list(filter(lambda rev: lookup.get(rev.id, None) is None, wd.revisions))
    ptr = step or len(working_set)
    # adjust working set
    working_set = working_set[:ptr]
    # ensure idempotency
    for rev in working_set:
        if rev.upgrade_sql is None:
            msg="""
            Error: No upgrade sql script @{}!
            """.format(rev.id)
            if rev.downgrade_sql is not None:
                msg="""
                Error: No upgrade sql script @{}, while there is a
                downgrade sql:
                {}
                Scripts should be idempotent.
                """.format(rev.id, rev.downgrade_sql)
            raise SystemExit(msg)
    # execute
    try:
        migr_ctx.add_revisions(working_set)
    except RevisionOperationError as e:
        raise SystemExit(repr(e))
    print('Done')
 def test_create_migr_ctx(self):
     wd = WorkDirectory(path=self.work_dir)
     ctx = create_migration_ctx(wd.get_migration_ctx_config())
     self.assertIsNotNone(ctx)