0

I have a lot (around a thousand) of FluentMigrator Migration classes that started timing out on our build server.

For those who haven't worked with FluentMigrator - Migrations are working in such way that all your migrations inherit from Migration class that has Up() and Down() methods that run SQL scripts for db migrations - simple and easy.

Now being lazy I have introduced a LoggingMigration class that logs the time when migration starts running (and simply replaced : Migration to : LoggingMigration in VS for that project).

public class LoggingMigration : Migration
{
    public DateTime StartTime { get; private set; }

    public LoggingMigration()
    {
        this.StartTime = DateTime.Now;
        Console.WriteLine("Start {0} - TIME: {1:yyyy-MM-dd HH:mm:ss.fff}", this.GetType().Name, StartTime);
    }

    public override void Up()
    {
    }

    public override void Down()
    {
    }
}

I want to also do a time on how long migration was running to make it easier to see which migrations take long.

I was thinking of using destructor like:

    ~LoggingMigration()
    {
        Console.WriteLine("End(?) {0} - TIME: {1}", this.GetType().Name, DateTime.Now.Subtract(StartTime));
    }

but thing is just to volatile and unpredictable

How to add mechanism that would run after Up() method in child class finishes? Or some other way that does the job?

Community
  • 1
  • 1
Matas Vaitkevicius
  • 58,075
  • 31
  • 238
  • 265

2 Answers2

1

How about overriding a protected method instead of the public one:

public abstract class Migration
{
    // ...

    protected DateTime StartTime { get; private set; }

    public Migration()
    {
        this.StartTime = DateTime.Now;
        Console.WriteLine("Start {0} - TIME: {1:yyyy-MM-dd HH:mm:ss.fff}", this.GetType().Name, StartTime);
    }

    public void Up()
    {
        OverrideUp();
        Console.WriteLine("End(?) {0} - TIME: {1}", this.GetType().Name, DateTime.Now.Substracts(StartTime));
    }

    public void Down()
    {
        // ...
        OverrideDown();
    }

    protected abstract void OverrideUp();
    protected abstract void OverrideDown();
}
Matias Cicero
  • 25,439
  • 13
  • 82
  • 154
  • Hi Matt, I can't modify Migration class it comes from FluentMigrator but I could introduce class that is inheriting from Migrator (like LoggingMigrator). You are suggesting to replace `Up()` in all current Migrations with `OverrideUp()` correct? – Matas Vaitkevicius Aug 17 '16 at 12:27
  • @MatasVaitkevicius That's right. Either that or you could use custom attributes, but I'd stick to the object oriented way. – Matias Cicero Aug 17 '16 at 13:28
-1

Create decorator for migration class. It's will look something like:

public class LoggingMigrationDecorator : Migration {
        private Migration _migrationClass;
        public DateTime StartTime { get; private set; }

        public LoggingMigrationDecorator (Migration toDecorate)
                {
                     _migrationClass = toDecorate;
                    this.StartTime = DateTime.Now;
                    Console.WriteLine("Start {0} - TIME: {1:yyyy-MM-dd HH:mm:ss.fff}", this.GetType().Name, StartTime);
                }

                public override void Up()
                {
                 toDecorate.Up();
                 stopTimerFunction(); // your function that will stop timer and do something with result

                }



      public override void Down()
            {
            }
        }
    }

Example of decorator pattern : http://www.dofactory.com/net/decorator-design-pattern

Ridikk12
  • 406
  • 1
  • 4
  • 13