예제 #1
0
        /// <summary>
        /// Produces a script to update the database.
        /// </summary>
        /// <param name="sourceMigration">
        /// The migration to update from. If null is supplied, a script to update the
        /// current database will be produced.
        /// </param>
        /// <param name="targetMigration">
        /// The migration to update to. If null is supplied,
        /// a script to update to the latest migration will be produced.
        /// </param>
        /// <returns> The generated SQL script. </returns>
        public string ScriptUpdate(string sourceMigration, string targetMigration)
        {
            _sqlBuilder.Clear();

            if (string.IsNullOrWhiteSpace(sourceMigration))
            {
                Update(targetMigration);
            }
            else
            {
                if (sourceMigration.IsAutomaticMigration())
                {
                    throw Error.AutoNotValidForScriptWindows(sourceMigration);
                }

                var sourceMigrationId = GetMigrationId(sourceMigration);
                var pendingMigrations = GetLocalMigrations().Where(m => string.CompareOrdinal(m, sourceMigrationId) > 0);

                string targetMigrationId = null;

                if (!string.IsNullOrWhiteSpace(targetMigration))
                {
                    if (targetMigration.IsAutomaticMigration())
                    {
                        throw Error.AutoNotValidForScriptWindows(targetMigration);
                    }

                    targetMigrationId = GetMigrationId(targetMigration);

                    if (string.CompareOrdinal(sourceMigrationId, targetMigrationId) > 0)
                    {
                        throw Error.DownScriptWindowsNotSupported();
                    }

                    pendingMigrations = pendingMigrations.Where(m => string.CompareOrdinal(m, targetMigrationId) <= 0);
                }

                _updateDatabaseOperation
                    = sourceMigration == DbMigrator.InitialDatabase
                          ? new UpdateDatabaseOperation(base.CreateDiscoveryQueryTrees().ToList())
                          : null;

                Upgrade(pendingMigrations, targetMigrationId, sourceMigrationId);

                if (_updateDatabaseOperation != null)
                {
                    ExecuteStatements(base.GenerateStatements(new[] { _updateDatabaseOperation }, null));
                }
            }

            return(_sqlBuilder.ToString());
        }
예제 #2
0
        private void Generate(UpdateDatabaseOperation updateDatabaseOperation)
        {
            CheckNotNull(updateDatabaseOperation, "updateDatabaseOperation");

            if (updateDatabaseOperation.Migrations.Any() == false)
            {
                return;
            }

            // call Generate(IEnumerable<MigrationOperation>) recursively
            Generate(updateDatabaseOperation.Migrations
                     as IEnumerable <MigrationOperation>);
        }
예제 #3
0
 /// <summary>Produces a script to update the database.</summary>
 /// <param name="sourceMigration">
 /// The migration to update from. If null is supplied, a script to update the
 /// current database will be produced.
 /// </param>
 /// <param name="targetMigration">
 /// The migration to update to. If null is supplied,
 /// a script to update to the latest migration will be produced.
 /// </param>
 /// <returns> The generated SQL script. </returns>
 public string ScriptUpdate(string sourceMigration, string targetMigration)
 {
     this._sqlBuilder.Clear();
     if (string.IsNullOrWhiteSpace(sourceMigration))
     {
         this.Update(targetMigration);
     }
     else
     {
         if (sourceMigration.IsAutomaticMigration())
         {
             throw Error.AutoNotValidForScriptWindows((object)sourceMigration);
         }
         string sourceMigrationId     = this.GetMigrationId(sourceMigration);
         IEnumerable <string> strings = this.GetLocalMigrations().Where <string>((Func <string, bool>)(m => string.CompareOrdinal(m, sourceMigrationId) > 0));
         string targetMigrationId     = (string)null;
         if (!string.IsNullOrWhiteSpace(targetMigration))
         {
             if (targetMigration.IsAutomaticMigration())
             {
                 throw Error.AutoNotValidForScriptWindows((object)targetMigration);
             }
             targetMigrationId = this.GetMigrationId(targetMigration);
             if (string.CompareOrdinal(sourceMigrationId, targetMigrationId) > 0)
             {
                 throw Error.DownScriptWindowsNotSupported();
             }
             strings = strings.Where <string>((Func <string, bool>)(m => string.CompareOrdinal(m, targetMigrationId) <= 0));
         }
         this._updateDatabaseOperation = sourceMigration == "0" ? new UpdateDatabaseOperation((IList <DbQueryCommandTree>) this.CreateDiscoveryQueryTrees().ToList <DbQueryCommandTree>()) : (UpdateDatabaseOperation)null;
         this.Upgrade(strings, targetMigrationId, sourceMigrationId);
         if (this._updateDatabaseOperation != null)
         {
             this.ExecuteStatements(base.GenerateStatements((IList <MigrationOperation>) new UpdateDatabaseOperation[1]
             {
                 this._updateDatabaseOperation
             }, (string)null));
         }
     }
     return(this._sqlBuilder.ToString());
 }
예제 #4
0
        public void Generate_can_handle_update_database_operations()
        {
            var migrationSqlGenerator = new SqlCeMigrationSqlGenerator();
            var providerInvariantName = ProviderRegistry.SqlCe4_ProviderInfo.ProviderInvariantName;

            var historyRepository
                = new HistoryRepository(
                      new SqlCeConnectionFactory(providerInvariantName)
                      .CreateConnection("Foo").ConnectionString,
                      DbProviderFactories.GetFactory(providerInvariantName),
                      "MyKey",
                      null);

            var updateDatabaseOperation
                = new UpdateDatabaseOperation(historyRepository.CreateDiscoveryQueryTrees().ToList());

            updateDatabaseOperation.AddMigration("M1", new [] { new DropColumnOperation("Customers", "Foo") });

            var sql = migrationSqlGenerator.Generate(new[] { updateDatabaseOperation }, "2008").Join(s => s.Sql, Environment.NewLine);

            Assert.Equal(@"ALTER TABLE [Customers] DROP COLUMN [Foo]", sql);
        }
 protected virtual IEnumerable <MigrationStatement> Generate(UpdateDatabaseOperation operation)
 {
     return(GenerateStatements(operation.Migrations.SelectMany(x => x.Operations)));
 }
        /// <summary>
        /// Generates the specified update database operation which represents applying a series of migrations.
        /// The generated script is idempotent, meaning it contains conditional logic to check if individual migrations 
        /// have already been applied and only apply the pending ones.
        /// </summary>
        /// <param name="updateDatabaseOperation">The update database operation.</param>
        protected virtual void Generate(UpdateDatabaseOperation updateDatabaseOperation)
        {
            Check.NotNull(updateDatabaseOperation, "updateDatabaseOperation");

            GenerateStatements(updateDatabaseOperation.Migrations.SelectMany(m => m.Operations));
        }
예제 #7
0
        private MigrationStatement Generate(UpdateDatabaseOperation updateDatabaseOperation)
        {
            if (updateDatabaseOperation == null)
            {
                throw new ArgumentNullException("UpdateDatabaseOperation");
            }

            MigrationStatement statement            = new MigrationStatement();
            StringBuilder      sql                  = new StringBuilder();
            const string       idempotentScriptName = "_idempotent_script";
            SelectGenerator    generator            = new SelectGenerator();

            if (!updateDatabaseOperation.Migrations.Any())
            {
                return(statement);
            }

            sql.AppendFormat("DROP PROCEDURE IF EXISTS `{0}`;", idempotentScriptName);
            sql.AppendLine();
            sql.AppendLine();

            sql.AppendLine("DELIMITER //");
            sql.AppendLine();

            sql.AppendFormat("CREATE PROCEDURE `{0}`()", idempotentScriptName);
            sql.AppendLine();
            sql.AppendLine("BEGIN");
            sql.AppendLine("  DECLARE CurrentMigration TEXT;");
            sql.AppendLine();
            sql.AppendLine("  IF EXISTS(SELECT 1 FROM information_schema.tables ");
            sql.AppendLine("  WHERE table_name = '__MigrationHistory' ");
            sql.AppendLine("  AND table_schema = DATABASE()) THEN ");

            foreach (var historyQueryTree in updateDatabaseOperation.HistoryQueryTrees)
            {
                string historyQuery = generator.GenerateSQL(historyQueryTree);
                ReplaceParemeters(ref historyQuery, generator.Parameters);
                sql.AppendLine(@"    SET CurrentMigration = (" + historyQuery + ");");
                sql.AppendLine("  END IF;");
                sql.AppendLine();
            }

            sql.AppendLine("  IF CurrentMigration IS NULL THEN");
            sql.AppendLine("    SET CurrentMigration = '0';");
            sql.AppendLine("  END IF;");
            sql.AppendLine();

            // Migrations
            foreach (var migration in updateDatabaseOperation.Migrations)
            {
                if (migration.Operations.Count == 0)
                {
                    continue;
                }

                sql.AppendLine("  IF CurrentMigration < '" + migration.MigrationId + "' THEN ");
                var statements = Generate(migration.Operations, _providerManifestToken);
                foreach (var migrationStatement in statements)
                {
                    string sqlStatement = migrationStatement.Sql;
                    if (!sqlStatement.EndsWith(";"))
                    {
                        sqlStatement += ";";
                    }
                    sql.AppendLine(sqlStatement);
                }
                sql.AppendLine("  END IF;");
                sql.AppendLine();
            }

            sql.AppendLine("END //");
            sql.AppendLine();
            sql.AppendLine("DELIMITER ;");
            sql.AppendLine();
            sql.AppendFormat("CALL `{0}`();", idempotentScriptName);
            sql.AppendLine();
            sql.AppendLine();
            sql.AppendFormat("DROP PROCEDURE IF EXISTS `{0}`;", idempotentScriptName);
            sql.AppendLine();

            statement.Sql = sql.ToString();

            return(statement);
        }
 protected override void Generate(UpdateDatabaseOperation updateDatabaseOperation)
 {
     base.Generate(updateDatabaseOperation);
 }