コード例 #1
0
        private static void CreateTableWithId(
            MigrationBase migration, string table, string idField,
            Action <ICreateTableColumnOptionOrWithColumnSyntax> addColumns, string schema, int size, bool checkExists = false)
        {
            Func <ICreateTableColumnAsTypeSyntax, ICreateTableColumnOptionOrWithColumnSyntax> addAsType =
                col =>
            {
                if (size == 64)
                {
                    return(col.AsInt64());
                }
                else if (size == 16)
                {
                    return(col.AsInt16());
                }
                else
                {
                    return(col.AsInt32());
                }
            };

            Func <ICreateTableWithColumnOrSchemaOrDescriptionSyntax, ICreateTableWithColumnSyntax> addSchema =
                syntax =>
            {
                if (schema != null)
                {
                    return(syntax.InSchema(schema));
                }
                else
                {
                    return(syntax);
                }
            };

            if (checkExists)
            {
                if (schema != null && migration.Schema.Schema(schema).Table(table).Exists())
                {
                    return;
                }

                if (schema == null && migration.Schema.Table(table).Exists())
                {
                    return;
                }
            }

            addColumns(
                addAsType(
                    addSchema(migration.IfDatabase(Utils.AllExceptOracle)
                              .Create.Table(table))
                    .WithColumn(idField))
                .Identity().PrimaryKey().NotNullable());

            addColumns(
                addAsType(
                    addSchema(migration.IfDatabase("Oracle")
                              .Create.Table(table))
                    .WithColumn(idField))
                .PrimaryKey().NotNullable());

            AddOracleIdentity(migration, table, idField);
        }
コード例 #2
0
ファイル: MigrationUtils.cs プロジェクト: misafer/Serene
 public static void CreateTableWithId32(
     this MigrationBase migration, string table, string idField,
     Action <ICreateTableColumnOptionOrWithColumnSyntax> addColumns, string schema = null)
 {
     CreateTableWithId(migration, table, idField, addColumns, schema, 32);
 }
コード例 #3
0
 public static void CreateTableWithId64(
     this MigrationBase migration, string table, string idField,
     Action <ICreateTableColumnOptionOrWithColumnSyntax> addColumns, string schema = null, bool checkExists = false)
 {
     CreateTableWithId(migration, table, idField, addColumns, schema, 64, checkExists);
 }
コード例 #4
0
    /// <summary>
    ///     Executes the plan.
    /// </summary>
    /// <param name="scope">A scope.</param>
    /// <param name="fromState">The state to start execution at.</param>
    /// <param name="migrationBuilder">A migration builder.</param>
    /// <param name="logger">A logger.</param>
    /// <param name="loggerFactory"></param>
    /// <returns>The final state.</returns>
    /// <remarks>The plan executes within the scope, which must then be completed.</remarks>
    public string Execute(MigrationPlan plan, string fromState)
    {
        plan.Validate();

        _logger.LogInformation("Starting '{MigrationName}'...", plan.Name);

        fromState ??= string.Empty;
        var nextState = fromState;

        _logger.LogInformation("At {OrigState}", string.IsNullOrWhiteSpace(nextState) ? "origin" : nextState);

        if (!plan.Transitions.TryGetValue(nextState, out MigrationPlan.Transition? transition))
        {
            plan.ThrowOnUnknownInitialState(nextState);
        }

        using (ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true))
        {
            // We want to suppress scope (service, etc...) notifications during a migration plan
            // execution. This is because if a package that doesn't have their migration plan
            // executed is listening to service notifications to perform some persistence logic,
            // that packages notification handlers may explode because that package isn't fully installed yet.
            using (scope.Notifications.Suppress())
            {
                var context = new MigrationContext(plan, _scopeAccessor.AmbientScope?.Database,
                                                   _loggerFactory.CreateLogger <MigrationContext>());

                while (transition != null)
                {
                    _logger.LogInformation("Execute {MigrationType}", transition.MigrationType.Name);

                    MigrationBase migration = _migrationBuilder.Build(transition.MigrationType, context);
                    migration.Run();

                    nextState = transition.TargetState;

                    _logger.LogInformation("At {OrigState}", nextState);

                    // throw a raw exception here: this should never happen as the plan has
                    // been validated - this is just a paranoid safety test
                    if (!plan.Transitions.TryGetValue(nextState, out transition))
                    {
                        throw new InvalidOperationException($"Unknown state \"{nextState}\".");
                    }
                }

                // prepare and de-duplicate post-migrations, only keeping the 1st occurence
                var temp = new HashSet <Type>();
                IEnumerable <Type> postMigrationTypes = context.PostMigrations
                                                        .Where(x => !temp.Contains(x))
                                                        .Select(x =>
                {
                    temp.Add(x);
                    return(x);
                });

                // run post-migrations
                foreach (Type postMigrationType in postMigrationTypes)
                {
                    _logger.LogInformation($"PostMigration: {postMigrationType.FullName}.");
                    MigrationBase postMigration = _migrationBuilder.Build(postMigrationType, context);
                    postMigration.Run();
                }
            }
        }

        _logger.LogInformation("Done (pending scope completion).");

        // safety check - again, this should never happen as the plan has been validated,
        // and this is just a paranoid safety test
        var finalState = plan.FinalState;

        if (nextState != finalState)
        {
            throw new InvalidOperationException(
                      $"Internal error, reached state {nextState} which is not final state {finalState}");
        }

        return(nextState);
    }