protected virtual void Generate(
            Action <ModelBuilder> buildAction,
            MigrationOperation[] operation,
            MigrationsSqlGenerationOptions options)
        {
            var services = ContextOptions != null
                ? TestHelpers.CreateContextServices(CustomServices, ContextOptions)
                : TestHelpers.CreateContextServices(CustomServices);

            IModel model = null;

            if (buildAction != null)
            {
                var modelBuilder = TestHelpers.CreateConventionBuilder();
                modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion);
                buildAction(modelBuilder);

                model = modelBuilder.Model;
                var conventionSet = services.GetRequiredService <IConventionSetBuilder>().CreateConventionSet();

                var typeMappingConvention = conventionSet.ModelFinalizingConventions.OfType <TypeMappingConvention>().FirstOrDefault();
                typeMappingConvention.ProcessModelFinalizing(((IConventionModel)model).Builder, null);

                var relationalModelConvention = conventionSet.ModelFinalizedConventions.OfType <RelationalModelConvention>().First();
                model = relationalModelConvention.ProcessModelFinalized((IConventionModel)model);
            }

            var batch = services.GetRequiredService <IMigrationsSqlGenerator>().Generate(operation, model, options);

            Sql = string.Join(
                "GO" + EOL + EOL,
                batch.Select(b => b.CommandText));
        }
Ejemplo n.º 2
0
 public IReadOnlyList <MigrationCommand> Generate(
     IReadOnlyList <MigrationOperation> operations,
     IModel?model = null,
     MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
 {
     throw new();
 }
 private string[] GetMigrationCommandTexts(
     IReadOnlyList <MigrationOperation> migrationOperations,
     bool beginTexts,
     MigrationsSqlGenerationOptions options)
 => GetCustomCommands(migrationOperations)
 .Select(t => PrepareString(beginTexts ? t.Item1 : t.Item2, options))
 .ToArray();
        public override string GenerateScript(
            string fromMigration = null,
            string toMigration   = null,
            MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
        {
            var script = base.GenerateScript(fromMigration, toMigration, options);

            if (!options.HasFlag(MigrationsSqlGenerationOptions.Idempotent))
            {
                return(script);
            }

            // Add helper stored procedures after database creation, but before applying migrations.
            // Remove them after all migrations have been apllied.
            var createScript = new StringBuilder(_historyRepository.GetCreateIfNotExistsScript())
                               .Append(_sqlGenerationHelper.BatchTerminator)
                               .ToString();

            var operations = GetIdempotentScriptMigrationOperations(fromMigration, toMigration);
            var builder    = new StringBuilder();

            if (script.StartsWith(createScript))
            {
                script = script.Remove(0, createScript.Length);
                builder.Append(createScript);
            }

            builder.AppendJoin(string.Empty, GetMigrationCommandTexts(operations, true, options));
            builder.Append(script);
            builder.AppendJoin(string.Empty, GetMigrationCommandTexts(operations, false, options));

            return(builder.ToString());
        }
        protected virtual void Generate(
            Action <ModelBuilder> buildAction,
            MigrationOperation[] operation,
            MigrationsSqlGenerationOptions options,
            CharSetBehavior?charSetBehavior,
            [CanBeNull] CharSet charSet,
            MySqlSchemaNameTranslator schemaNameTranslator = null)
        {
            var optionsBuilder      = new DbContextOptionsBuilder(ContextOptions);
            var mySqlOptionsBuilder = new MySqlDbContextOptionsBuilder(optionsBuilder);

            if (charSetBehavior != null)
            {
                mySqlOptionsBuilder.CharSetBehavior(charSetBehavior.Value);
            }

            if (charSet != null)
            {
                mySqlOptionsBuilder.CharSet(charSet);
            }

            if (schemaNameTranslator != null)
            {
                mySqlOptionsBuilder.SchemaBehavior(MySqlSchemaBehavior.Translate, schemaNameTranslator);
            }

            var contextOptions = optionsBuilder.Options;

            var services = ContextOptions != null
                ? TestHelpers.CreateContextServices(CustomServices, contextOptions)
                : TestHelpers.CreateContextServices(CustomServices);

            IModel model = null;

            if (buildAction != null)
            {
                var modelBuilder = TestHelpers.CreateConventionBuilder();
                modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion);
                buildAction(modelBuilder);

                model = modelBuilder.Model;
                var conventionSet = services.GetRequiredService <IConventionSetBuilder>().CreateConventionSet();

                var typeMappingConvention = conventionSet.ModelFinalizingConventions.OfType <TypeMappingConvention>().FirstOrDefault();
                typeMappingConvention.ProcessModelFinalizing(((IConventionModel)model).Builder, null);

                var relationalModelConvention = conventionSet.ModelFinalizedConventions.OfType <RelationalModelConvention>().First();
                model = relationalModelConvention.ProcessModelFinalized((IConventionModel)model);
            }

            var batch = services.GetRequiredService <IMigrationsSqlGenerator>().Generate(operation, model, options);

            Sql = string.Join(
                EOL,
                batch.Select(b => b.CommandText));
        }
Ejemplo n.º 6
0
        /// <summary>
        ///     Gets the commands that will create all tables from the model.
        /// </summary>
        /// <param name="options">The options to use when generating commands.</param>
        /// <returns>The generated commands.</returns>
        protected virtual IReadOnlyList <MigrationCommand> GetCreateTablesCommands(
            MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
        {
            var model = Dependencies.CurrentContext.Context.GetService <IDesignTimeModel>().Model;

            return(Dependencies.MigrationsSqlGenerator.Generate(
                       Dependencies.ModelDiffer.GetDifferences(null, model.GetRelationalModel()),
                       model,
                       options));
        }
        protected virtual void Generate(
            Action <ModelBuilder> buildAction,
            Action <MigrationBuilder> migrateAction,
            MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
        {
            var migrationBuilder = new MigrationBuilder(activeProvider: null);

            migrateAction(migrationBuilder);

            Generate(buildAction, migrationBuilder.Operations.ToArray(), options);
        }
Ejemplo n.º 8
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    protected virtual IReadOnlyList <MigrationCommand> GenerateUpSql(
        Migration migration,
        MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
    {
        var insertCommand = _rawSqlCommandBuilder.Build(
            _historyRepository.GetInsertScript(new HistoryRow(migration.GetId(), ProductInfo.GetVersion())));

        return(_migrationsSqlGenerator
               .Generate(migration.UpOperations, FinalizeModel(migration.TargetModel), options)
               .Concat(new[] { new MigrationCommand(insertCommand, _currentContext.Context, _commandLogger) })
               .ToList());
    }
        protected override IReadOnlyList <MigrationCommand> GenerateUpSql(
            Migration migration,
            MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
        {
            var commands = base.GenerateUpSql(migration, options);

            return(options.HasFlag(MigrationsSqlGenerationOptions.Script) &&
                   options.HasFlag(MigrationsSqlGenerationOptions.Idempotent)
                ? commands
                : WrapWithCustomCommands(
                       migration.UpOperations,
                       commands.ToList(),
                       options));
        }
Ejemplo n.º 10
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    protected virtual IReadOnlyList <MigrationCommand> GenerateDownSql(
        Migration migration,
        Migration?previousMigration,
        MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
    {
        var deleteCommand = _rawSqlCommandBuilder.Build(
            _historyRepository.GetDeleteScript(migration.GetId()));

        return(_migrationsSqlGenerator
               .Generate(
                   migration.DownOperations, previousMigration == null ? null : FinalizeModel(previousMigration.TargetModel), options)
               .Concat(new[] { new MigrationCommand(deleteCommand, _currentContext.Context, _commandLogger) })
               .ToList());
    }
Ejemplo n.º 11
0
 /// <summary>
 ///     Generates commands from a list of operations.
 /// </summary>
 /// <param name="operations"> The operations. </param>
 /// <param name="model"> The target model which may be <see langword="null" /> if the operations exist without a model. </param>
 /// <param name="options"> The options to use when generating commands. </param>
 /// <returns> The list of commands to be executed or scripted. </returns>
 public override IReadOnlyList <MigrationCommand> Generate(
     IReadOnlyList <MigrationOperation> operations,
     IModel model = null,
     MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
 {
     _operations = operations;
     try
     {
         return(base.Generate(operations, model, options));
     }
     finally
     {
         _operations = null;
     }
 }
Ejemplo n.º 12
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual string ScriptMigration(
            [CanBeNull] string fromMigration,
            [CanBeNull] string toMigration,
            MigrationsSqlGenerationOptions options,
            [CanBeNull] string contextType)
        {
            using var context = _contextOperations.CreateContext(contextType);
            var services = _servicesBuilder.Build(context);

            EnsureServices(services);

            var migrator = services.GetRequiredService <IMigrator>();

            return(migrator.GenerateScript(fromMigration, toMigration, options));
        }
        private string PrepareString(string str, MigrationsSqlGenerationOptions options)
        {
            str = options.HasFlag(MigrationsSqlGenerationOptions.Script)
                ? str
                : CleanUpScriptSpecificPseudoStatements(str);

            str = str
                  .Replace("\r", string.Empty)
                  .Replace("\n", Environment.NewLine);

            str += options.HasFlag(MigrationsSqlGenerationOptions.Script)
                ? Environment.NewLine + (
                options.HasFlag(MigrationsSqlGenerationOptions.Idempotent)
                          ? Environment.NewLine
                          : string.Empty)
                : string.Empty;

            return(str);
        }
        private IReadOnlyList <MigrationCommand> WrapWithCustomCommands(
            IReadOnlyList <MigrationOperation> migrationOperations,
            List <MigrationCommand> migrationCommands,
            MigrationsSqlGenerationOptions options)
        {
            var beginCommandTexts = GetMigrationCommandTexts(migrationOperations, true, options);
            var endCommandTexts   = GetMigrationCommandTexts(migrationOperations, false, options);

            migrationCommands.InsertRange(0, beginCommandTexts.Select(t => new MigrationCommand(
                                                                          _rawSqlCommandBuilder.Build(t),
                                                                          _currentContext.Context,
                                                                          _commandLogger)));

            migrationCommands.AddRange(endCommandTexts.Select(t => new MigrationCommand(
                                                                  _rawSqlCommandBuilder.Build(t),
                                                                  _currentContext.Context,
                                                                  _commandLogger)));

            return(migrationCommands);
        }
    public void Alter_column_change_serial_to_identity_idempotent(MigrationsSqlGenerationOptions options)
    {
        Generate(
            modelBuilder =>
        {
            modelBuilder.HasAnnotation(CoreAnnotationNames.ProductVersion, "3.1.0");
            modelBuilder.Entity <Person>().Property <int>("Id").UseSerialColumn();
        },
            new[]
        {
            new AlterColumnOperation
            {
                Table   = "Person",
                Name    = "Id",
                ClrType = typeof(int),
                [NpgsqlAnnotationNames.ValueGenerationStrategy] =
                    NpgsqlValueGenerationStrategy.IdentityByDefaultColumn,

                OldColumn = new AddColumnOperation
                {
                    Table   = "Person",
                    Name    = "Id",
                    ClrType = typeof(int),
                    [NpgsqlAnnotationNames.ValueGenerationStrategy] =
                        NpgsqlValueGenerationStrategy.SerialColumn,
                }
            }
        },
            options);

        AssertSql(
            $@"ALTER SEQUENCE ""Person_Id_seq"" RENAME TO ""Person_Id_old_seq"";
ALTER TABLE ""Person"" ALTER COLUMN ""Id"" DROP DEFAULT;
ALTER TABLE ""Person"" ALTER COLUMN ""Id"" ADD GENERATED BY DEFAULT AS IDENTITY;
{(options == MigrationsSqlGenerationOptions.Idempotent ? "PERFORM" : "SELECT")} * FROM setval('""Person_Id_seq""', nextval('""Person_Id_old_seq""'), false);
DROP SEQUENCE ""Person_Id_old_seq"";
");
    }
 public string GenerateScript(string fromMigration = null, string toMigration = null,
                              MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
 {
     return(_context.Database.GenerateCreateScript());
 }
    public virtual void CreateSequenceTriggerForColumn(string columnName, string tableName, string schemaName, MigrationsSqlGenerationOptions options, MigrationCommandListBuilder builder)
    {
        var identitySequenceName = CreateSequenceTriggerSequenceName(columnName, tableName, schemaName);

        if (options.HasFlag(MigrationsSqlGenerationOptions.Script))
        {
            builder.Append("SET TERM ");
            builder.Append(((IFbSqlGenerationHelper)_sqlGenerationHelper).AlternativeStatementTerminator);
            builder.AppendLine(_sqlGenerationHelper.StatementTerminator);
            builder.EndCommand();
        }

        builder.AppendLine("EXECUTE BLOCK");
        builder.AppendLine("AS");
        builder.AppendLine("BEGIN");
        builder.IncrementIndent();
        builder.Append("if (not exists(select 1 from rdb$generators where rdb$generator_name = '");
        builder.Append(identitySequenceName);
        builder.Append("')) then");
        builder.AppendLine();
        builder.AppendLine("begin");
        builder.IncrementIndent();
        builder.Append("execute statement 'create sequence ");
        builder.Append(identitySequenceName);
        builder.Append("'");
        builder.Append(_sqlGenerationHelper.StatementTerminator);
        builder.AppendLine();
        builder.DecrementIndent();
        builder.AppendLine("end");
        builder.DecrementIndent();
        builder.Append("END");
        builder.AppendLine();
        if (options.HasFlag(MigrationsSqlGenerationOptions.Script))
        {
            builder.AppendLine(((IFbSqlGenerationHelper)_sqlGenerationHelper).AlternativeStatementTerminator);
        }
        else
        {
            builder.AppendLine(_sqlGenerationHelper.StatementTerminator);
        }
        builder.EndCommand();

        builder.Append("CREATE TRIGGER ");
        builder.Append(_sqlGenerationHelper.DelimitIdentifier(CreateSequenceTriggerName(columnName, tableName, schemaName)));
        builder.Append(" ACTIVE BEFORE INSERT ON ");
        builder.Append(_sqlGenerationHelper.DelimitIdentifier(tableName, schemaName));
        builder.AppendLine();
        builder.AppendLine("AS");
        builder.AppendLine("BEGIN");
        builder.IncrementIndent();
        builder.Append("if (new.");
        builder.Append(_sqlGenerationHelper.DelimitIdentifier(columnName));
        builder.Append(" is null) then");
        builder.AppendLine();
        builder.AppendLine("begin");
        builder.IncrementIndent();
        builder.Append("new.");
        builder.Append(_sqlGenerationHelper.DelimitIdentifier(columnName));
        builder.Append(" = next value for ");
        builder.Append(identitySequenceName);
        builder.Append(_sqlGenerationHelper.StatementTerminator);
        builder.AppendLine();
        builder.DecrementIndent();
        builder.AppendLine("end");
        builder.DecrementIndent();
        builder.Append("END");
        builder.AppendLine();
        if (options.HasFlag(MigrationsSqlGenerationOptions.Script))
        {
            builder.AppendLine(((IFbSqlGenerationHelper)_sqlGenerationHelper).AlternativeStatementTerminator);
        }
        else
        {
            builder.AppendLine(_sqlGenerationHelper.StatementTerminator);
        }
        builder.EndCommand();

        if (options.HasFlag(MigrationsSqlGenerationOptions.Script))
        {
            builder.Append("SET TERM ");
            builder.Append(_sqlGenerationHelper.StatementTerminator);
            builder.AppendLine(((IFbSqlGenerationHelper)_sqlGenerationHelper).AlternativeStatementTerminator);
            builder.EndCommand();
        }
    }
Ejemplo n.º 18
0
 /// <summary>
 ///     Generates commands from a list of operations.
 /// </summary>
 /// <param name="operations">The operations.</param>
 /// <param name="model">The target model which may be <see langword="null" /> if the operations exist without a model.</param>
 /// <param name="options">The options to use when generating commands.</param>
 /// <returns>The list of commands to be executed or scripted.</returns>
 public override IReadOnlyList <MigrationCommand> Generate(
     IReadOnlyList <MigrationOperation> operations,
     IModel?model = null,
     MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
 => base.Generate(RewriteOperations(operations, model), model, options);
Ejemplo n.º 19
0
 /// <summary>
 ///     Gets the commands that will create all tables from the model.
 /// </summary>
 /// <param name="options"> The options to use when generating commands. </param>
 /// <returns> The generated commands. </returns>
 protected virtual IReadOnlyList <MigrationCommand> GetCreateTablesCommands(
     MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
 => Dependencies.MigrationsSqlGenerator.Generate(
     Dependencies.ModelDiffer.GetDifferences(null, Dependencies.Model.GetRelationalModel()), Dependencies.Model, options);
 protected override void Generate(
     Action <ModelBuilder> buildAction,
     MigrationOperation[] operation,
     MigrationsSqlGenerationOptions options)
 => Generate(buildAction, operation, options, null, null);
 async Task <IReadOnlyList <MigrationCommand> > Generate(IReadOnlyList <MigrationOperation> operations, MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
 {
     await using (var db = await GetDbContext <FbTestDbContext>())
     {
         var generator = db.GetService <IMigrationsSqlGenerator>();
         return(generator.Generate(operations, db.Model, options));
     }
 }
Ejemplo n.º 22
0
 public string GenerateScript(
     string fromMigration = null,
     string toMigration   = null,
     MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
 => throw new NotImplementedException();
    public virtual void DropSequenceTriggerForColumn(string columnName, string tableName, string schemaName, MigrationsSqlGenerationOptions options, MigrationCommandListBuilder builder)
    {
        var triggerName = CreateSequenceTriggerName(columnName, tableName, schemaName);

        if (options.HasFlag(MigrationsSqlGenerationOptions.Script))
        {
            builder.Append("SET TERM ");
            builder.Append(((IFbSqlGenerationHelper)_sqlGenerationHelper).AlternativeStatementTerminator);
            builder.AppendLine(_sqlGenerationHelper.StatementTerminator);
            builder.EndCommand();
        }

        builder.AppendLine("EXECUTE BLOCK");
        builder.AppendLine("AS");
        builder.AppendLine("BEGIN");
        builder.IncrementIndent();
        builder.Append("if (exists(select 1 from rdb$triggers where rdb$trigger_name = '");
        builder.Append(triggerName);
        builder.Append("')) then");
        builder.AppendLine();
        builder.AppendLine("begin");
        builder.IncrementIndent();
        builder.Append("execute statement 'drop trigger ");
        builder.Append(_sqlGenerationHelper.DelimitIdentifier(triggerName));
        builder.Append("'");
        builder.Append(_sqlGenerationHelper.StatementTerminator);
        builder.AppendLine();
        builder.DecrementIndent();
        builder.AppendLine("end");
        builder.DecrementIndent();
        builder.Append("END");
        builder.AppendLine();
        if (options.HasFlag(MigrationsSqlGenerationOptions.Script))
        {
            builder.AppendLine(((IFbSqlGenerationHelper)_sqlGenerationHelper).AlternativeStatementTerminator);
        }
        else
        {
            builder.AppendLine(_sqlGenerationHelper.StatementTerminator);
        }
        builder.EndCommand();

        if (options.HasFlag(MigrationsSqlGenerationOptions.Script))
        {
            builder.Append("SET TERM ");
            builder.Append(_sqlGenerationHelper.StatementTerminator);
            builder.AppendLine(((IFbSqlGenerationHelper)_sqlGenerationHelper).AlternativeStatementTerminator);
            builder.EndCommand();
        }
    }
Ejemplo n.º 24
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual string GenerateScript(
            string fromMigration = null,
            string toMigration   = null,
            MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
        {
            options |= MigrationsSqlGenerationOptions.Script;

            var idempotent     = options.HasFlag(MigrationsSqlGenerationOptions.Idempotent);
            var noTransactions = options.HasFlag(MigrationsSqlGenerationOptions.NoTransactions);

            IEnumerable <string> appliedMigrations;

            if (string.IsNullOrEmpty(fromMigration) ||
                fromMigration == Migration.InitialDatabase)
            {
                appliedMigrations = Enumerable.Empty <string>();
            }
            else
            {
                var fromMigrationId = _migrationsAssembly.GetMigrationId(fromMigration);
                appliedMigrations = _migrationsAssembly.Migrations
                                    .Where(t => string.Compare(t.Key, fromMigrationId, StringComparison.OrdinalIgnoreCase) <= 0)
                                    .Select(t => t.Key);
            }

            PopulateMigrations(
                appliedMigrations,
                toMigration,
                out var migrationsToApply,
                out var migrationsToRevert,
                out var actualTargetMigration);

            var builder = new IndentedStringBuilder();

            if (fromMigration == Migration.InitialDatabase ||
                string.IsNullOrEmpty(fromMigration))
            {
                builder
                .Append(_historyRepository.GetCreateIfNotExistsScript())
                .Append(_sqlGenerationHelper.BatchTerminator);
            }

            var transactionStarted = false;

            for (var i = 0; i < migrationsToRevert.Count; i++)
            {
                var migration         = migrationsToRevert[i];
                var previousMigration = i != migrationsToRevert.Count - 1
                    ? migrationsToRevert[i + 1]
                    : actualTargetMigration;

                _logger.MigrationGeneratingDownScript(this, migration, fromMigration, toMigration, idempotent);

                foreach (var command in GenerateDownSql(migration, previousMigration, options))
                {
                    if (!noTransactions)
                    {
                        if (!transactionStarted && !command.TransactionSuppressed)
                        {
                            builder
                            .AppendLine(_sqlGenerationHelper.StartTransactionStatement)
                            .Append(_sqlGenerationHelper.BatchTerminator);
                            transactionStarted = true;
                        }

                        if (transactionStarted && command.TransactionSuppressed)
                        {
                            builder
                            .AppendLine(_sqlGenerationHelper.CommitTransactionStatement)
                            .Append(_sqlGenerationHelper.BatchTerminator);
                            transactionStarted = false;
                        }
                    }

                    if (idempotent)
                    {
                        builder.AppendLine(_historyRepository.GetBeginIfExistsScript(migration.GetId()));
                        using (builder.Indent())
                        {
                            builder.AppendLines(command.CommandText);
                        }

                        builder.Append(_historyRepository.GetEndIfScript());
                    }
                    else
                    {
                        builder.Append(command.CommandText);
                    }

                    builder.Append(_sqlGenerationHelper.BatchTerminator);
                }

                if (!noTransactions && transactionStarted)
                {
                    builder
                    .AppendLine(_sqlGenerationHelper.CommitTransactionStatement)
                    .Append(_sqlGenerationHelper.BatchTerminator);
                    transactionStarted = false;
                }
            }

            foreach (var migration in migrationsToApply)
            {
                _logger.MigrationGeneratingUpScript(this, migration, fromMigration, toMigration, idempotent);

                foreach (var command in GenerateUpSql(migration, options))
                {
                    if (!noTransactions)
                    {
                        if (!transactionStarted && !command.TransactionSuppressed)
                        {
                            builder
                            .AppendLine(_sqlGenerationHelper.StartTransactionStatement)
                            .Append(_sqlGenerationHelper.BatchTerminator);
                            transactionStarted = true;
                        }

                        if (transactionStarted && command.TransactionSuppressed)
                        {
                            builder
                            .AppendLine(_sqlGenerationHelper.CommitTransactionStatement)
                            .Append(_sqlGenerationHelper.BatchTerminator);
                            transactionStarted = false;
                        }
                    }

                    if (idempotent)
                    {
                        builder.AppendLine(_historyRepository.GetBeginIfNotExistsScript(migration.GetId()));
                        using (builder.Indent())
                        {
                            builder.AppendLines(command.CommandText);
                        }

                        builder.Append(_historyRepository.GetEndIfScript());
                    }
                    else
                    {
                        builder.Append(command.CommandText);
                    }

                    builder.Append(_sqlGenerationHelper.BatchTerminator);
                }

                if (!noTransactions && transactionStarted)
                {
                    builder
                    .AppendLine(_sqlGenerationHelper.CommitTransactionStatement)
                    .Append(_sqlGenerationHelper.BatchTerminator);
                    transactionStarted = false;
                }
            }

            return(builder.ToString());
        }
 public string GenerateScript(string fromMigration = null, string toMigration = null, MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
 {
     return(CurrentTemporalTableMigrator.GenerateScript(fromMigration, toMigration, options));
 }