Пример #1
0
    public AppTaskResult Revert(string?migrationName, bool throwIfError)
    {
        using var db = DbFactory.Open();
        Init(db);

        var allMigrationTypes = MigrationTypes.ToList();

        allMigrationTypes.Reverse();

        LogMigrationsFound(allMigrationTypes);

        var startAt       = DateTime.UtcNow;
        var migrationsRun = new List <IAppTask>();

        Log.Info($"Reverting {migrationName}...");

        migrationName = migrationName switch
        {
            All => allMigrationTypes.LastOrDefault()?.Name,
            Last => allMigrationTypes.FirstOrDefault()?.Name,
            _ => migrationName
        };

        if (migrationName != null)
        {
            while (true)
            {
                Type?nextRun;
                try
                {
                    nextRun = GetNextMigrationRevertToRun(db, allMigrationTypes);
                    if (nextRun == null)
                    {
                        break;
                    }
                }
                catch (Exception e)
                {
                    Log.Error(e.Message);
                    if (throwIfError)
                    {
                        throw;
                    }
                    return(new AppTaskResult(migrationsRun)
                    {
                        Error = e
                    });
                }

                var migrationStartAt = DateTime.UtcNow;

                var descFmt = AppTasks.GetDescFmt(nextRun);
                Log.Info($"Reverting {nextRun.Name}{descFmt}...");

                var instance = Run(DbFactory, nextRun, x => x.Down());
                migrationsRun.Add(instance);
                Log.Info(instance.Log);

                if (instance.Error == null)
                {
                    Log.Info($"Completed revert of {nextRun.Name}{descFmt} in {(DateTime.UtcNow - migrationStartAt).TotalSeconds:N3}s" +
                             Environment.NewLine);

                    // Remove completed migration revert from DB
                    db.Delete <Migration>(x => x.Name == nextRun.Name);
                }
                else
                {
                    Log.Error(instance.Error.Message, instance.Error);
                    if (throwIfError)
                    {
                        throw instance.Error;
                    }

                    return(new AppTaskResult(migrationsRun));
                }

                if (migrationName == nextRun.Name)
                {
                    break;
                }
            }
        }

        var migrationsCompleted = migrationsRun.Count(x => x.Error == null);

        if (migrationsCompleted == 0)
        {
            Log.Info("No migrations were reverted.");
        }
        else
        {
            var migration = migrationsCompleted > 1 ? "migrations" : "migration";
            Log.Info($"{Environment.NewLine}Reverted {migrationsCompleted} {migration} in {(DateTime.UtcNow - startAt).TotalSeconds:N3}s");
        }
        return(new AppTaskResult(migrationsRun));
    }
Пример #2
0
    public AppTaskResult Run(bool throwIfError)
    {
        using var db = DbFactory.Open();
        Init(db);
        var allLogs = new StringBuilder();

        var remainingMigrations = MigrationTypes.ToList();

        LogMigrationsFound(remainingMigrations);

        var startAt       = DateTime.UtcNow;
        var migrationsRun = new List <IAppTask>();

        while (true)
        {
            Type?nextRun;
            try
            {
                nextRun = GetNextMigrationToRun(db, remainingMigrations);
                if (nextRun == null)
                {
                    break;
                }
            }
            catch (Exception e)
            {
                Log.Error(e.Message);
                if (throwIfError)
                {
                    throw;
                }
                return(new AppTaskResult(migrationsRun)
                {
                    Error = e
                });
            }

            var migrationStartAt = DateTime.UtcNow;

            var descFmt = AppTasks.GetDescFmt(nextRun);
            Log.Info($"Running {nextRun.Name}{descFmt}...");

            var migration = new Migration
            {
                Name             = nextRun.Name,
                Description      = AppTasks.GetDesc(nextRun),
                CreatedDate      = DateTime.UtcNow,
                ConnectionString = ((OrmLiteConnectionFactory)DbFactory).ConnectionString,
                NamedConnection  = nextRun.FirstAttribute <NamedConnectionAttribute>()?.Name,
            };
            var id = db.Insert(migration, selectIdentity: true);

            var instance = Run(DbFactory, nextRun, x => x.Up());
            migrationsRun.Add(instance);
            Log.Info(instance.Log);

            if (instance.Error == null)
            {
                Log.Info($"Completed {nextRun.Name}{descFmt} in {(DateTime.UtcNow - migrationStartAt).TotalSeconds:N3}s" +
                         Environment.NewLine);

                // Record completed migration run in DB
                db.UpdateOnly(() => new Migration
                {
                    Log           = instance.Log,
                    CompletedDate = DateTime.UtcNow,
                }, where : x => x.Id == id);
                remainingMigrations.Remove(nextRun);
            }
            else
            {
                var e = instance.Error;
                Log.Error(e.Message, e);

                // Save Error in DB
                db.UpdateOnly(() => new Migration
                {
                    Log             = instance.Log,
                    ErrorCode       = e.GetType().Name,
                    ErrorMessage    = e.Message,
                    ErrorStackTrace = e.StackTrace,
                }, where : x => x.Id == id);

                if (throwIfError)
                {
                    throw instance.Error;
                }
                return(new AppTaskResult(migrationsRun));
            }
        }

        var migrationsCompleted = migrationsRun.Count(x => x.Error == null);

        if (migrationsCompleted == 0)
        {
            Log.Info("No migrations to run.");
        }
        else
        {
            var migration = migrationsCompleted > 1 ? "migrations" : "migration";
            Log.Info($"{Environment.NewLine}Ran {migrationsCompleted} {migration} in {(DateTime.UtcNow - startAt).TotalSeconds:N3}s");
        }
        return(new AppTaskResult(migrationsRun));
    }