/// <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")); }