/// <summary>
        /// Generates FluentMigration C# files based on the procedures found in <see cref="schemaDumper"/>
        /// </summary>
        /// <param name="context">Defines how, what and where the migrations will be generated</param>
        /// <param name="schemaDumper">The platform specific schema dumper instance to get procedure information from</param>
        public void GenerateMigrations(SchemaMigrationContext context, ISchemaDumper schemaDumper)
        {
            _announcer.Say("Reading procedures");
             var defs = schemaDumper.ReadProcedures();

             SetupMigrationsDirectory(context);

             var migrations = 0;
             foreach (var procedure in defs)
             {
            if ( context.ExcludeProcedures.Contains(procedure.Name))
            {
               _announcer.Say("Excluding procedure " + procedure.Name);
               continue;
            }

            if (context.IncludeProcedures.Count != 0 && !context.IncludeProcedures.Contains(procedure.Name)) continue;

            migrations++;

            var migrationsFolder = Path.Combine(context.WorkingDirectory, context.MigrationsDirectory);
            var csFilename = Path.Combine(migrationsFolder, context.MigrationProcedureClassNamer(context.MigrationIndex + migrations, procedure) + ".cs");

            _announcer.Say("Creating migration " + Path.GetFileName(csFilename));
            using (var writer = new StreamWriter(csFilename))
            {
               WriteToStream(context, procedure, context.MigrationIndex + migrations, writer);
            }
             }

             context.MigrationIndex += migrations;
        }
 /// <summary>
 /// Writes the Migration Up() and Down()
 /// </summary>
 /// <param name="context">The context that controls how the column should be generated</param>
 /// <param name="function">the Function to generate the migration for</param>
 /// <param name="migration">The migration index to apply</param>
 /// <param name="output">The output stream to append the C# code to</param>
 private void WriteToStream(SchemaMigrationContext context, FunctionDefinition function, int migration, StreamWriter output)
 {
     WriteMigration(output, context, migration
     , () => context.MigrationFunctionClassNamer(migration, function)
     , () => WriteView(context, function, output)
     , () => WriteDeleteView(context, function, output));
 }
 private static void WriteDeleteView(SchemaMigrationContext context, ProcedureDefinition procedure, StreamWriter output)
 {
     if ( context.FromDatabaseType == DatabaseType.SqlServer)
     output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.SqlServer).Sql(\"DROP PROCEDURE [{0}].[{1}]\");", procedure.SchemaName, procedure.Name);
      else
     output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.{0}).Sql(\"DROP PROCEDURE {1}\");", context.FromDatabaseType, procedure.Name);
 }
 /// <summary>
 /// Writes the Migration Up() and Down()
 /// </summary>
 /// <param name="context">The context that controls how the column should be generated</param>
 /// <param name="procedure">the procedure to generate the migration for</param>
 /// <param name="migration">The migration index to apply</param>
 /// <param name="output">The output stream to append the C# code to</param>
 private void WriteToStream(SchemaMigrationContext context, ProcedureDefinition procedure, int migration, StreamWriter output)
 {
     WriteMigration(output, context, migration
     , () => context.MigrationProcedureClassNamer(migration, procedure)
     , () => WriteView(context, procedure, output)
     , () => WriteDeleteView(context, procedure, output));
 }
        protected void WriteMigration(StreamWriter output, SchemaMigrationContext context, int migration, Func<string> generateName, Action upStatement, Action downStatement)
        {
            //start writing a migration file
             output.WriteLine("using System;");
             output.WriteLine("using FluentMigrator;");
             output.WriteLine(String.Empty);
             output.WriteLine("namespace {0}", context.DefaultMigrationNamespace);
             output.WriteLine("{");
             output.WriteLine("\t[Migration({0})]", migration);
             output.WriteLine("\tpublic class {0} : Migration", generateName());
             output.WriteLine("\t{");
             output.WriteLine("\t\tpublic override void Up()");
             output.WriteLine("\t\t{");

             upStatement();

             output.WriteLine("\t\t}"); //end Up method

             output.WriteLine("\t\tpublic override void Down()");
             output.WriteLine("\t\t{");

             downStatement();

             output.WriteLine("\t\t}"); //end Down method
             output.WriteLine("\t}"); //end class
             output.WriteLine(String.Empty);
             output.WriteLine("}"); //end namespace
        }
 private static void WriteDeleteView(SchemaMigrationContext context, FunctionDefinition function, StreamWriter output)
 {
     if ( context.FromDatabaseType == DatabaseType.SqlServer)
     output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.SqlServer).Sql(\"DROP FUNCTION [{0}].[{1}]\");", function.SchemaName, function.Name);
      else
     output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.{0}).Sql(\"DROP FUNCTION {1}\");", context.FromDatabaseType, function.Name);
 }
        private static void WriteDeleteView(SchemaMigrationContext context, ViewDefinition view, StreamWriter output)
        {
            if ( context.FromDatabaseType == DatabaseType.SqlServer)
            output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.SqlServer).Sql(\"DROP VIEW [{0}].[{1}]\");", view.SchemaName, view.Name);
             else
            output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.{0}).Sql(\"DROP VIEW {1}\");", context.FromDatabaseType, view.Name);

             foreach (var databaseType in context.GenerateAlternateMigrationsFor)
             {
            output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.{0}).Sql(\"DROP VIEW {1}\");", databaseType, view.Name);
             }
        }
 private void WriteView(SchemaMigrationContext context, ProcedureDefinition procedure, StreamWriter output)
 {
     var scriptsDirectory = Path.Combine(context.WorkingDirectory, context.ScriptsDirectory);
      var scriptFile = Path.Combine(scriptsDirectory, string.Format("CreateProcedure{0}_{1}.sql", procedure.Name, context.FromDatabaseType));
      if ( !File.Exists(scriptFile))
      {
     if (!Directory.Exists(scriptsDirectory))
        Directory.CreateDirectory(scriptsDirectory);
     File.WriteAllText(scriptFile, procedure.Sql);
      }
      output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.{0}).Script(@\"{1}\");", context.FromDatabaseType, Path.Combine(context.ScriptsDirectory, Path.GetFileName(scriptFile)));
 }
        protected void SetupMigrationsDirectory(SchemaMigrationContext context)
        {
            if (string.IsNullOrEmpty(context.WorkingDirectory))
            context.WorkingDirectory = Path.GetTempPath() + Guid.NewGuid();

             context.MigrationsDirectory = string.IsNullOrEmpty(context.MigrationsDirectory)
                                          ? @".\Migrations"
                                          : context.MigrationsDirectory;

             var migrationsPath = Path.Combine(context.WorkingDirectory, context.MigrationsDirectory);
             if (!Directory.Exists(migrationsPath))
            Directory.CreateDirectory(migrationsPath);

             _announcer.Say("Writing migrations to " + migrationsPath);

             Directory.CreateDirectory(context.MigrationsDirectory);
        }
        /// <summary>
        /// Generates FluentMigration C# files based on the views found in <see cref="schemaDumper"/>
        /// </summary>
        /// <param name="context">Defines how, what and where the migrations will be generated</param>
        /// <param name="schemaDumper">The platform specific schema dumper instance to get view information from</param>
        public void GenerateMigrations(SchemaMigrationContext context, ISchemaDumper schemaDumper)
        {
            _announcer.Say("Reading views");
             var defs = schemaDumper.ReadViews();

             SetupMigrationsDirectory(context);

             //TODO: Think about adding custom sort order for view definitions as there may be
             // dependancies between views.
             // if ( context.CustomViewSorter != null )
             //   defs = context.CustomViewSorter(defs);

             var migrations = 0;
             foreach (var view in defs)
             {
            if ( context.ExcludeViews.Contains(view.Name))
            {
               _announcer.Say("Excluding view " + view.Name);
               continue;
            }

            if (context.IncludeViews.Count != 0 && !context.IncludeViews.Contains(view.Name)) continue;

            migrations++;

            var migrationsFolder = Path.Combine(context.WorkingDirectory, context.MigrationsDirectory);
            var csFilename = Path.Combine(migrationsFolder, context.MigrationViewClassNamer(context.MigrationIndex + migrations, view) + ".cs");

            _announcer.Say("Creating migration " + Path.GetFileName(csFilename));
            using (var writer = new StreamWriter(csFilename))
            {
               WriteToStream(context, view, context.MigrationIndex + migrations, writer);
            }
             }

             context.MigrationIndex += migrations;
        }
        /// <summary>
        /// Generates schema migrations from the datasource as C# source code
        /// </summary>
        /// <param name="context">Define data required to generate the C# migrations</param>
        public void Generate(SchemaMigrationContext context)
        {
            Announcer.AnnounceTime = context.AnnounceTime;
             Announcer.Say(string.Format("Generating schema {0} migrations from {1}", context.Type, context.FromConnectionString));
             using (var connection = GetConnection(context))
             {

            var processor = GetProcessor(connection);
            var schemaDumper = GetSchemaDumper(processor);

            if (context.MigrationRequired(MigrationType.Tables) || context.MigrationRequired(MigrationType.Indexes) || context.MigrationRequired(MigrationType.Data) || context.MigrationRequired(MigrationType.ForeignKeys))
            {
               var tables = new CSharpTableMigrationsWriter(Announcer);
               tables.GenerateMigrations(context, schemaDumper);
            }

            if (context.MigrationRequired(MigrationType.Procedures))
            {
               var procedures = new CSharpProcedureMigrationsWriter(Announcer);
               procedures.GenerateMigrations(context, schemaDumper);
            }

            if (context.MigrationRequired(MigrationType.Functions))
            {
               var functions = new CSharpFunctionMigrationsWriter(Announcer);
               functions.GenerateMigrations(context, schemaDumper);
            }

            // Migrate the views last as procedures or functions may be included in them
            if (context.MigrationRequired(MigrationType.Views))
            {
               var views = new CSharpViewMigrationsWriter(Announcer);
               views.GenerateMigrations(context, schemaDumper);
            }
             }
        }
 protected override IDbConnection GetConnection(SchemaMigrationContext context)
 {
     return OracleFactory.GetOpenConnection(context.FromConnectionString);
 }
        /// <summary>
        /// Generates C# files from the supplied procedure definitions
        /// </summary>
        /// <param name="context">The context that defines how the migrations should be created</param>
        /// <param name="procedureDefinitions">The procedure definitions that are the source for thr migration</param>
        private string GenerateProcedureMigrations(SchemaMigrationContext context, params ProcedureDefinition[] procedureDefinitions)
        {
            var mockDumper = new Mock<ISchemaDumper>();
             var writer = new CSharpProcedureMigrationsWriter(new DebugAnnouncer());

             mockDumper.Setup(m => m.ReadProcedures()).Returns(procedureDefinitions);

             writer.GenerateMigrations(context, mockDumper.Object);

             var migrationsFile = Path.Combine(_tempDirectory, @"Migrations\Test.cs");
             return File.Exists(migrationsFile) ? File.ReadAllText(migrationsFile) : string.Empty;
        }
 /// <summary>
 /// Writes the Migration Up() and Down()
 /// </summary>
 /// <param name="context">The context that controls how the column should be generated</param>
 /// <param name="table">the table to generate the migration for</param>
 /// <param name="migration">The migration index to apply</param>
 /// <param name="output">The output stream to append the C# code to</param>
 private void WriteToStream(SchemaMigrationContext context, TableDefinition table, int migration, StreamWriter output)
 {
     WriteMigration(output, context, migration
     , () => context.MigrationClassNamer(migration, table)
     ,() => WriteTable(context, table, output)
     , () => WriteDeleteTable(context, table, output));
 }
        /// <summary>
        /// Creates a table and optionally inserts data into the table if <see cref="SchemaMigrationContext.MigrateData"/> is <c>True</c>
        /// </summary>
        /// <param name="context">The context that controls how the column should be generated</param>
        /// <param name="table">the table to generate the migration for</param>
        /// <param name="output">The output stream to append the C# code to</param>
        private void WriteTable(SchemaMigrationContext context, TableDefinition table, StreamWriter output)
        {
            if ( context.MigrationRequired(MigrationType.Tables) )
              {
              output.WriteLine("\t\t\tif (Schema.Table(\"{0}\").Exists()) return;", table.Name);
              output.WriteLine("");

              output.WriteLine("\t\t\tCreate.Table(\"" + table.Name + "\")");
              foreach (var column in table.Columns)
              {
                  WriteColumn(context, column, output, column == table.Columns.Last());
              }
              if (context.MigrationRequired(MigrationType.Data))
              {
                  WriteInsertData(output, table, context);
              }
              }

              if ( context.MigrationRequired(MigrationType.Indexes) && table.Indexes.Count > 0 )
             {
             var primaryKey = table.Columns.Where(c => c.IsPrimaryKey);
             var primaryKeyName = string.Empty;
             if ( primaryKey.Count() > 0 )
             {
                 primaryKeyName = primaryKey.First().PrimaryKeyName;
             }

            foreach (var index in table.Indexes.Where(i => i.Name != primaryKeyName))
               WriteIndex(output, index, context);

             }
        }
 protected override IDbConnection GetConnection(SchemaMigrationContext context)
 {
     return new SqlConnection(context.FromConnectionString);
 }
 /// <summary>
 /// Writes the Migration Up() and Down()
 /// </summary>
 /// <param name="context">The context that controls how the column should be generated</param>
 /// <param name="view">the view to generate the migration for</param>
 /// <param name="migration">The migration index to apply</param>
 /// <param name="output">The output stream to append the C# code to</param>
 private void WriteToStream(SchemaMigrationContext context, ViewDefinition view, int migration, StreamWriter output)
 {
     WriteMigration(output, context, migration
     , () => context.MigrationViewClassNamer(migration, view)
     , () => WriteView(context, view, output)
     , () => WriteDeleteView(context, view, output));
 }
        /// <summary>
        /// Convert the column definition into a fluent WithColumn.AsXXXX() syntax
        /// </summary>
        /// <param name="context">The context that controls how the column should be generated</param>
        /// <param name="column">The column to generate</param>
        /// <param name="output">The stream to write the C# to</param>
        /// <param name="isLastColumn">If <c>True</c> indicates that this is the last column and a ; should be appened</param>
        private void WriteColumn(SchemaMigrationContext context, ColumnDefinition column, StreamWriter output, bool isLastColumn)
        {
            var columnSyntax = new StringBuilder();
             columnSyntax.AppendFormat(".WithColumn(\"{0}\")", column.Name);

             if (column.Type.HasValue)
             {
            var columnType = column.Type.Value;
            if (MapDatabaseTypes.ContainsKey(columnType))
            {
               columnType = MapDatabaseTypes[columnType];
            }

            switch (columnType)
            {
               case DbType.AnsiString:
                  if (column.Size > 0)
                     columnSyntax.AppendFormat(".AsAnsiString({0})", column.Size);
                  else
                     columnSyntax.Append(".AsAnsiString()");
                  break;
               case DbType.AnsiStringFixedLength:
                  columnSyntax.AppendFormat(".AsFixedLengthAnsiString({0})", column.Size);
                  break;
               case DbType.Binary:
                  columnSyntax.AppendFormat(".AsBinary({0})", column.Size);
                  break;
               case DbType.Byte:
                  columnSyntax.Append(".AsByte()");
                  break;
               case DbType.Boolean:
                  columnSyntax.Append(".AsBoolean()");
                  break;
               case DbType.Currency:
                  columnSyntax.Append(".AsCurrency()");
                  break;
               case DbType.Date:
                  columnSyntax.Append(".AsDate()");
                  break;
               case DbType.DateTime:
                  columnSyntax.Append(".AsDateTime()");
                  break;
               case DbType.Decimal:
                  columnSyntax.AppendFormat(".AsDecimal({0},{1})", column.Precision, column.Scale);
                  break;
               case DbType.Double:
                  columnSyntax.Append(".AsDouble()");
                  break;
               case DbType.Guid:
                  columnSyntax.Append(".AsGuid()");
                  break;
               case DbType.Int16:
                  columnSyntax.Append(".AsInt16()");
                  break;
               case DbType.Int32:
                  columnSyntax.Append(".AsInt32()");
                  break;
               case DbType.Int64:
                  columnSyntax.Append(".AsInt64()");
                  break;
               case DbType.String:
                  if (column.Size > 0)
                     columnSyntax.AppendFormat(".AsString({0})", column.Size);
                  else
                     columnSyntax.Append(".AsString()");
                  break;

               case DbType.StringFixedLength:
                  columnSyntax.AppendFormat(".AsFixedLengthString({0})", column.Size);
                  break;
               case DbType.Xml:
                  columnSyntax.Append(".AsXml()");
                  break;
               default:
                  _announcer.Error(string.Format("Unsupported type {0} for column {1}", column.Type, column.Name));
                  columnSyntax.Append(".AsString()");
                  break;
            }
             }

             if (column.IsIdentity)
            columnSyntax.Append(".Identity()");

             ApplyDefaultValue(columnSyntax, column, context);

             if (!column.IsNullable)
            columnSyntax.Append(".NotNullable()");

             if (column.IsNullable)
            columnSyntax.Append(".Nullable()");

             if (column.IsPrimaryKey)
             columnSyntax.Append(".PrimaryKey()");

             if (isLastColumn) columnSyntax.Append(";");
             output.WriteLine("\t\t\t\t" + columnSyntax);
        }
        private void WriteView(SchemaMigrationContext context, ViewDefinition view, StreamWriter output)
        {
            var scriptsDirectory = Path.Combine(context.WorkingDirectory, context.ScriptsDirectory);
             var scriptFile = Path.Combine(scriptsDirectory, string.Format("CreateView{0}_{1}.sql", view.Name, context.FromDatabaseType));
             if ( !File.Exists(scriptFile))
             {
            if (!Directory.Exists(scriptsDirectory))
               Directory.CreateDirectory(scriptsDirectory);
            File.WriteAllText(scriptFile, view.CreateViewSql);
             }
             output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.{0}).Script(@\"{1}\");", context.FromDatabaseType, Path.Combine(context.ScriptsDirectory, Path.GetFileName(scriptFile)));

             foreach (var databaseType in context.GenerateAlternateMigrationsFor)
             {
            if (!context.ViewConvertor.ContainsKey(databaseType)) continue;

            var alterternateScriptFile = Path.Combine(scriptsDirectory, string.Format("CreateView{0}_{1}.sql", view.Name, databaseType));
            if (!File.Exists(alterternateScriptFile))
            {
               File.WriteAllText(alterternateScriptFile, context.ViewConvertor[databaseType](view));
            }
            output.WriteLine("\t\t\tExecute.WithDatabaseType(DatabaseType.{0}).Script(@\"{1}\");", databaseType, Path.Combine(context.ScriptsDirectory, Path.GetFileName(alterternateScriptFile)));
             }
        }
        private static void WriteDeleteTable(SchemaMigrationContext context, TableDefinition table, StreamWriter output)
        {
            if (context.MigrationRequired(MigrationType.Indexes) && table.Indexes.Count > 0)
              {
              var primaryKey = table.Columns.Where(c => c.IsPrimaryKey);
              var primaryKeyName = string.Empty;
              if (primaryKey.Count() > 0)
              {
                  primaryKeyName = primaryKey.First().PrimaryKeyName;
              }

              foreach (var index in table.Indexes.Where(i => i.Name != primaryKeyName))
                  WriteDeleteIndex(output, index);
              }

              if (context.MigrationRequired(MigrationType.Tables))
              {
              output.WriteLine("\t\t\tDelete.Table(\"" + table.Name + "\");");
              }
        }
        /// <summary>
        /// Conditioanlly appends a default value clause is the column has a default value
        /// </summary>
        /// <param name="fluentColumnCode">The current fluent column being constructed</param>
        /// <param name="column">The column to check if it has a default value</param>
        /// <param name="context">The context that controls how the column should be generated</param>
        private static void ApplyDefaultValue(StringBuilder fluentColumnCode, ColumnDefinition column, SchemaMigrationContext context)
        {
            if (column.DefaultValue is ColumnDefinition.UndefinedDefaultValue)
            return;

             // Special case handle system methods
             if (column.DefaultValue != null && column.DefaultValue.ToString().ToLower().Equals("(newid())") || column.DefaultValue.ToString().ToLower().Equals("newguid"))
             {
            // Append the enum value
            fluentColumnCode.AppendFormat(".WithDefaultValue(SystemMethods.{0})", SystemMethods.NewGuid);
            return;
             }

             if (column.DefaultValue != null && column.DefaultValue.ToString().ToLower().Equals("(getdate())") || column.DefaultValue.ToString().ToLower().Equals("currentdatetime"))
             {
            // Append the enum value
            fluentColumnCode.AppendFormat(".WithDefaultValue(SystemMethods.{0})", SystemMethods.CurrentDateTime);
            return;
             }

             // Check if we have a value
             if (column.DefaultValue == null || string.IsNullOrEmpty(column.DefaultValue.ToString()))
            return; // No return

             // Convert to string and remove any enclosing ( and )
             var defaultValue = column.DefaultValue.ToString()
            .Replace("(", "")
            .Replace(")", ""); // HACK - What if default is string and includes ( ?

             // Check if it is a string value
             if (defaultValue.StartsWith("'") && defaultValue.EndsWith("'"))
             {
            defaultValue = defaultValue.Replace("'", "\"");

            if (column.Type == DbType.DateTime || column.Type == DbType.Date)
            {
               defaultValue = context.DateTimeDefaultValueFormatter(column, defaultValue);
            }

            fluentColumnCode.AppendFormat(".WithDefaultValue({0})", defaultValue);
            return;
             }

             if (!defaultValue.StartsWith("\""))
            defaultValue = "\"" + defaultValue;

             if (!defaultValue.EndsWith("\""))
            defaultValue = defaultValue + "\"";

             fluentColumnCode.AppendFormat(".WithDefaultValue({0})", defaultValue);
        }
        /// <summary>
        /// Migrates a set of tables using the provided context
        /// </summary>
        /// <param name="context">The migration context that controls how items are migrated between SQL Server and Oracle</param>
        /// <param name="createTables">The tables to be created in SQL Server and migrated to Oracle</param>
        private void MigrateTable(SchemaMigrationContext context, params CreateTableExpression[] createTables)
        {
            CreateTables(createTables);

             var migrator = new SqlServerSchemaMigrator(new DebugAnnouncer());

             migrator.Generate(context);
             migrator.Migrate(context);

             AssertOracleTablesExist(createTables);
        }
        /// <summary>
        /// Generates C# files from the supplied view definitions
        /// </summary>
        /// <param name="context">The context that defines how the migrations should be created</param>
        /// <param name="viewDefinitions">The view definitions that are the source for thr migration</param>
        private static void GenerateViewMigrations(SchemaMigrationContext context, IList<ViewDefinition> viewDefinitions)
        {
            var mockDumper = new Mock<ISchemaDumper>();
             var writer = new CSharpViewMigrationsWriter(new DebugAnnouncer());

             mockDumper.Setup(m => m.ReadViews()).Returns(viewDefinitions);

             writer.GenerateMigrations(context, mockDumper.Object);
        }
        private SqlServerSchemaMigrator GenerateMigrations(SchemaMigrationContext context, params IMigrationExpression[] createTables)
        {
            ExecuteMigrations(createTables);

               var migrator = new SqlServerSchemaMigrator(new DebugAnnouncer());

               migrator.Generate(context);
               return migrator;
        }
        /// <summary>
        /// Migrates a set of tables using the provided context
        /// </summary>
        /// <param name="context">The migration context that controls how items are migrated between SQL Server and SqlServer</param>
        /// <param name="createTables">The tables to be created in source SqlServer and migrated to SqlServer</param>
        private void MigrateTable(SchemaMigrationContext context, params IMigrationExpression[] createTables)
        {
            var migrator = GenerateMigrations(context, createTables);

              if (Directory.Exists(Path.Combine(_tempDirectory, "Scripts")))
             {
            // Replace Schema from source to destintion
            foreach (var filename in Directory.GetFiles(Path.Combine(_tempDirectory, "Scripts"), "CreateView*.sql"))
            {
               var text = File.ReadAllText(filename);
               File.Delete(filename);
               File.WriteAllText(filename, text.Replace(_source.TestDb.ToUpper(), _destination.TestDb.ToUpper()));
            }
             }

             migrator.Migrate(context);
        }
        private void WriteIndex(StreamWriter output, IndexDefinition index, SchemaMigrationContext context)
        {
            output.WriteLine("\t\t\tCreate.Index(\"" + index.Name + "\").OnTable(\"" + index.TableName + "\")");
             foreach (var column in index.Columns)
             {
            output.Write("\t\t\t\t.OnColumn(\"" + column.Name + "\")");
            if ( column.Direction == Direction.Ascending)
               output.Write(".Ascending()");
            if (column.Direction == Direction.Descending)
               output.Write(".Descending()");
             }

             if ( index.IsUnique || index.IsClustered )
             {
            output.Write(".WithOptions()");

            if ( index.IsUnique )
               output.Write(".Unique()");

            if (index.IsClustered)
               output.Write(".Clustered()");
             }

             output.WriteLine(";");
        }
        private void WriteInsertData(StreamWriter output, TableDefinition table, SchemaMigrationContext context)
        {
            output.Write(string.Format("\t\t\tInsert.IntoTable(\"{0}\").DataTable(@\"{1}\\{0}.xml\")",table.Name, context.DataDirectory));

             // Check if the column contains an identity column
              var identityColumn = ColumnWithIdentitySpecified(table);
              if (!string.IsNullOrEmpty(identityColumn))
             {
            // It does lets add on extra handling for inserting the identity value into the destination database
            output.Write(".WithIdentity().OnColumn(\"");
            output.Write(identityColumn);
            output.Write("\")");
             }

             // Add any replacement values
             foreach (var replacement in MatchingReplacements(context.InsertColumnReplacements, table))
             {
            output.Write(string.Format(".WithReplacementValue({0}, {1})", FormatValue(replacement.OldValue), FormatValue(replacement.NewValue)));
             }

             // Check if we need to honour case senstive column names
             if ( context.CaseSenstiveColumnNames && context.CaseSenstiveColumns.Count() == 0)
             {
            // We do update insert statement
            output.Write(".WithCaseSensitiveColumnNames()");
             }

             if ( context.CaseSenstiveColumns.Count() > 0 )
             {
            foreach (var column in context.CaseSenstiveColumns)
            {
               // We do update insert statement
               output.Write(string.Format(".WithCaseSensitiveColumn(\"{0}\")",column));
            }

             }

             output.Write(";");
        }
        /// <summary>
        /// Generates C# Migrations that Create tables Migrations
        /// </summary>
        /// <param name="context">The context that define how parts of the C# will be formatted</param>
        /// <param name="schemaDumper">The schema dump to use as the source of the schema migration</param>
        public void GenerateMigrations(SchemaMigrationContext context, ISchemaDumper schemaDumper)
        {
            _announcer.Say("Reading database schema");
             var defs = schemaDumper.ReadDbSchema();

             if (context.PreMigrationTableUpdate != null)
            context.PreMigrationTableUpdate(defs);

             SetupMigrationsDirectory(context);

             var migrations = 0;

             var foreignkeyTables = new List<TableDefinition>();

             foreach (var table in defs)
             {
            // Check if we want to exclude this table
            if ( context.ExcludeTables.Contains(table.Name))
            {
               _announcer.Say("Exluding table " + table.Name);
               continue;
            }

            if (context.MigrationRequired(MigrationType.Tables) || (context.MigrationRequired(MigrationType.Indexes) && table.Indexes.Count > 0))
            {
               migrations++;

               var migrationsFolder = Path.Combine(context.WorkingDirectory, context.MigrationsDirectory);
               var csFilename = Path.Combine(migrationsFolder, context.MigrationClassNamer(context.MigrationIndex + migrations, table) + ".cs");
               _announcer.Say("Creating migration " + Path.GetFileName(csFilename));
               using (var writer = new StreamWriter(csFilename))
               {
                  WriteToStream(context, table, context.MigrationIndex + migrations, writer);
               }
            }

            if (context.MigrationRequired(MigrationType.Data))
            {
               var data = schemaDumper.ReadTableData(table.SchemaName, table.Name);

               if (data != null && data.Tables.Count > 0 && data.Tables[0].Rows.Count > 0)
               {
                  var dataDirectory = Path.Combine(context.WorkingDirectory, context.DataDirectory);
                  if (!Directory.Exists(dataDirectory))
                     Directory.CreateDirectory(dataDirectory);
                  data.Tables[0].WriteXmlSchema(Path.Combine(dataDirectory, table.Name + ".xsd"));

                  using (var writer = new XmlTextWriter(Path.Combine(dataDirectory, table.Name + ".xml"), context.MigrationEncoding))
                  {
                     data.Tables[0].WriteXml(writer);
                  }

               }
            }

            if (context.MigrationRequired(MigrationType.ForeignKeys) && table.ForeignKeys.Count > 0)
            {
               // Add to list of tables to apply foreign key
               // ... done as two part process as may me interdepdancies between tables
               foreignkeyTables.Add(table);
            }

             }

             context.MigrationIndex += migrations;

             if (context.MigrationRequired(MigrationType.ForeignKeys))
            GenerateForeignKeyMigrations(context, foreignkeyTables);
        }
        private void GenerateForeignKeyMigrations(SchemaMigrationContext context, List<TableDefinition> tables)
        {
            if (!context.MigrationRequired(MigrationType.ForeignKeys) || tables.Count <= 0)
             {
            return;
             }

             _announcer.Say(string.Format("Found {0} tables with foreign keys", tables.Count));

             var migrations = 0;

             foreach (var foreignkeyTable in tables)
             {
            var migrationsFolder = Path.Combine(context.WorkingDirectory, context.MigrationsDirectory);

            migrations++;

            var migrationIndex = context.MigrationIndex+ migrations;
            var table = foreignkeyTable;

            var csFilename = Path.Combine(migrationsFolder,
                                          context.MigrationClassNamer(migrationIndex, table) + "ForeignKey.cs");
            _announcer.Say("Creating migration " + Path.GetFileName(csFilename));
            using (var writer = new StreamWriter(csFilename))
            {
               WriteMigration(writer, context, migrationIndex
                              , () => context.MigrationClassNamer(migrationIndex, table) + "ForeignKey"
                              , () => WriteForeignKey(table, writer)
                              , () => WriteDeleteForeignKey(table, writer));
            }
             }

             context.MigrationIndex +=  migrations;
        }
        private string GetTestMigration(SchemaMigrationContext context, params ViewDefinition[] views)
        {
            GenerateViewMigrations(context, views);

             return File.ReadAllText(Path.Combine(Path.Combine( _tempDirectory, "Migrations"), "Test.cs"));
        }