public void Execute(IDbPlatform platform, IRefactorNode refactorNode, Environment environment) { string auditTableName = AstNodePropertyUtil.AsString(refactorNode.Properties["audit-table"].Value); string tableName = AstNodePropertyUtil.AsString(refactorNode.Properties["table"].Value); // // We only need columns here ITableDefinition tableDefinition = environment.Schema.GetTable(tableName); ITableDefinition auditTable = new TableDefinition(auditTableName); foreach(ColumnDefinition column in tableDefinition.Columns) { // // Keep name and type only. IColumnDefinition auditColumn = new ColumnDefinition(column.Name); // // Special handling for rowversion if(column.Type == DbType.Time) { auditColumn.Length = 8; auditColumn.Type = DbType.Binary; } // if else { auditColumn.Length = column.Length; auditColumn.Type = column.Type; } // else auditColumn.Nullable = true; auditTable.AddColumn(auditColumn); } // foreach environment.Schema.AddTable(auditTable); // // Now build an AST IAddTableNode addAuditTableNode = new AddTableNode(refactorNode.Parent, auditTableName); foreach(IColumnDefinition auditColumn in auditTable.Columns) { IAddColumnNode addAuditColumnNode = new AddColumnNode(addAuditTableNode, auditColumn.Name); addAuditColumnNode.Type = auditColumn.Type; addAuditColumnNode.Length = auditColumn.Length; addAuditColumnNode.Nullable = auditColumn.Nullable; addAuditTableNode.ChildNodes.Add(addAuditColumnNode); } // foreach addAuditTableNode.Parent.ChildNodes.Add(addAuditTableNode); }
public MigrationScriptCollection CompileMigrationScripts(TextReader migrationDefinition) { Environment environment = new Environment(); MigrationScriptsCodeGenerator migrationScriptsCodeGenerator = new MigrationScriptsCodeGenerator(dbPlatform, nativeSqlResourceProvider, migrationMode); //migrationScriptsCodeGenerator.SetEnvironment(environment); IMdlCompiler mdlCompiler = new MdlCompiler(migrationScriptsCodeGenerator, environment); mdlCompiler.AddCompilerStageAfter<AstFlattenerCompilerStage>(new DbNamingCompilerStage(dbPlatform.NamingStrategy)); mdlCompiler.AddCompilerStageBefore<AstFlattenerCompilerStage>(new RefactoringStage(dbPlatform)); mdlCompiler.Compile(migrationDefinition, MdlCompilationOptions.All); return migrationScriptsCodeGenerator.MigrationScripts; }
private Schema GetSchema() { Environment environment = new Environment(); using (Stream resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("octalforty.Wizardby.Tests.Resources.Blog.mdl")) { IMdlParser mdlParser = new MdlParser(MdlParserTestFixture.CreateScanner( new StreamReader(resourceStream, Encoding.UTF8))); IMdlCompiler mdlCompiler = new MdlCompiler(new NullCodeGenerator(), environment); mdlCompiler.Compile(mdlParser.Parse(), MdlCompilationOptions.All); } // using return environment.Schema; }
public void GenerateScript() { IAstNode astNode; using (Stream resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("octalforty.Wizardby.Tests.Resources.Blog.mdl")) { IMdlParser mdlParser = new MdlParser(MdlParserTestFixture.CreateScanner(new StreamReader(resourceStream, Encoding.UTF8))); astNode = mdlParser.Parse(); } // using IDbPlatform platform = new SqlServer2000Platform(); Environment environment = new Environment(); IMdlCompiler compiler = new MdlCompiler(new NullCodeGenerator(), environment); compiler.RemoveCompilerStage<DowngradeGenerationStage>(); compiler.RemoveCompilerStage<UpgradeGenerationStage>(); compiler.AddCompilerStageAfter<AstFlattenerCompilerStage>(new DbNamingCompilerStage(platform.NamingStrategy)); compiler.Compile(astNode, MdlCompilationOptions.All); DbStatementBatchWriter batchWriter = new DbStatementBatchWriter(); IDbScriptGenerator scriptGenerator = platform.Dialect.CreateScriptGenerator(batchWriter); //scriptGenerator.SetEnvironment(environment); foreach(IVersionNode versionNode in Algorithms.Filter<IAstNode, IVersionNode>(astNode.ChildNodes)) versionNode.Accept(scriptGenerator); System.Console.WriteLine(batchWriter.GetStatementBatches()[0].Clean()); Assert.AreEqual(@"create table [SchemaInfo] ( [Version] bigint not null ); create table [Author] ( [ID] int not null identity , [FirstName] nvarchar(200) not null , [LastName] nvarchar(200) not null , [EmailAddress] nvarchar(200) not null , [Login] nvarchar(200) not null , [Password] varbinary(64) null , primary key (ID) ); create table [Tag] ( [ID] int not null identity , [Name] nvarchar(200) not null , primary key (ID) ); create table [Blog] ( [ID] int not null identity , [Name] nvarchar(200) not null , [Description] nvarchar(max) not null , primary key (ID) ); create table [BlogPost] ( [ID] int not null identity , [Title] nvarchar(200) not null , [Slug] nvarchar(200) not null , [BlogID] int not null , [AuthorID] int not null , primary key (ID) ); create table [BlogPostTagJunction] ( [BlogPostID] int not null, [TagID] int not null, ); create unique nonclustered index [UQ_Version] on [SchemaInfo] ([Version]); create unique nonclustered index [IX_EmailAddress] on [Author] ([EmailAddress]); create unique nonclustered index [IX_Login] on [Author] ([Login]); alter table [BlogPost] add constraint [FK1] foreign key ([BlogID]) references [Blog] ([ID]); alter table [BlogPost] add constraint [FK2] foreign key ([AuthorID]) references [Author] ([ID]); alter table [BlogPostTagJunction] add constraint [FK3] foreign key ([BlogPostID]) references [BlogPost] ([ID]); alter table [BlogPostTagJunction] add constraint [FK4] foreign key ([TagID]) references [Tag] ([ID]); create table [BlogPostComment] ( [ID] int not null identity primary key, [BlogPostID] int not null, [AuthorEmailAddress] nvarchar(200) not null, [Content] nvarchar(max) not null, ); alter table [BlogPostComment] add constraint [FK5] foreign key ([BlogPostID]) references [BlogPost] ([ID]); create table [Media] ( [ID] int not null identity primary key, [TypeID] int , [Name] nvarchar(200) not null, [MimeType] nvarchar(200) not null, [Length] int , [BlogPostID] int null, [BlogPostCommentID] int null, ); create table [User] ( [ID] int not null identity primary key, [Login] nvarchar(200) not null, [Password] varbinary(64) not null, ); alter table [Media] add constraint [DF_MimeType] default ('text/xml') for [MimeType]; alter table [Media] add constraint [FK10] foreign key ([BlogPostID]) references [BlogPost] ([ID]); alter table [Media] add constraint [FK11] foreign key ([BlogPostCommentID]) references [BlogPostComment] ([ID]); create unique nonclustered index [IX_Login] on [User] ([ID], [Login] desc); create table [Forum] ( [ID] int not null identity primary key, [Name] nvarchar(200) not null, [ModeratorUserID] int not null, ); alter table [Forum] add constraint [FK_FOO] foreign key ([ModeratorUserID]) references [User] ([ID]); drop index [IX_Login] on [User]; create unique nonclustered index [IX_Login] on [User] ([ID], [Login] desc); create table [BlogAuthorJunction] ( [BlogID] int not null, [AuthorID] int not null, ); alter table [BlogAuthorJunction] add constraint [FK12] foreign key ([BlogID]) references [Blog] ([ID]); alter table [BlogAuthorJunction] add constraint [FK13] foreign key ([AuthorID]) references [Author] ([ID]); alter table [Forum] add [Slug] nvarchar(200) not null; alter table [Forum] drop column [Slug]; alter table [Forum] add [Slug] nvarchar(200) not null; alter table [Forum] alter column [Slug] nvarchar(200) null; alter table [Forum] drop constraint [FK_FOO]; drop table [Forum]; alter table [BlogPostTagJunction] drop constraint [FK4]; drop table [Tag]; ".Clean(), batchWriter.GetStatementBatches()[0].Clean()); }
public void BindReferences() { Environment environment = new Environment(); NamingCompilerStage namingCompilerStage = new NamingCompilerStage(); namingCompilerStage.SetEnvironment(environment); IMdlCompilerStage bindingStage = new BindingCompilerStage(); bindingStage.SetEnvironment(environment); IAstNode astNode = new MdlParser(MdlParserTestFixture.CreateScanner( @"migration ""Waffle"" revision => 1: templates: table template Foo version 1: add table ""BlogPost"": ID type => Int32, primary-key => true version 2: remove table BlogPost version 3: add table BlogPost: Version type => Int32 ID type => Int32, primary-key => true alter table BlogPost: add column PublishedOn type => DateTime add table ""BlogPostApproval"": BlogPostID type => Int32: reference ""FK0"" pk-table => BlogPost ApprovedOn type => DateTime add reference FK1 fk-columns => [BlogPostID, ApprovedOn], pk-table => BlogPost, pk-column => Version add reference FK2 fk-table => BlogPostApproval, fk-columns => [ApprovedOn,BlogPostID], pk-table => BlogPost alter table BlogPostApproval: remove reference FK2 add column Bar: reference pk-table => BlogPost, pk-column => ID, fk-table => BlogPost, fk-column => ID remove reference FK1 fk-table => BlogPostApproval add reference FK3 fk-table => BlogPostApproval, fk-column => BlogPostID, pk-table => BlogPost, pk-column => ID")).Parse(); astNode.Accept(namingCompilerStage); astNode.Accept(bindingStage); IVersionNode version3Node = (IVersionNode)astNode.ChildNodes[3]; IAddTableNode addTableBlogPostApprovalNode = (IAddTableNode)version3Node.ChildNodes[2]; IAddReferenceNode addReferenceBlogPostNode = (IAddReferenceNode)addTableBlogPostApprovalNode.ChildNodes[0].ChildNodes[0]; Assert.AreEqual("BlogPostApproval", addReferenceBlogPostNode.FkTable); Assert.AreEqual("BlogPostID", addReferenceBlogPostNode.FkColumns[0]); Assert.AreEqual("BlogPost", addReferenceBlogPostNode.PkTable); Assert.AreEqual("ID", addReferenceBlogPostNode.PkColumns[0]); IAddReferenceNode addReferenceFk1Node = (IAddReferenceNode)addTableBlogPostApprovalNode.ChildNodes[2]; Assert.AreEqual("FK1", addReferenceFk1Node.Name); Assert.AreEqual("BlogPostApproval", addReferenceFk1Node.FkTable); Assert.AreEqual("BlogPostID", addReferenceFk1Node.FkColumns[0]); Assert.AreEqual("ApprovedOn", addReferenceFk1Node.FkColumns[1]); Assert.AreEqual("BlogPost", addReferenceFk1Node.PkTable); Assert.AreEqual("Version", addReferenceFk1Node.PkColumns[0]); IAddReferenceNode addReferenceFk2Node = (IAddReferenceNode)version3Node.ChildNodes[3]; Assert.AreEqual("FK2", addReferenceFk2Node.Name); Assert.AreEqual("BlogPostApproval", addReferenceFk2Node.FkTable); Assert.AreEqual("ApprovedOn", addReferenceFk2Node.FkColumns[0]); Assert.AreEqual("BlogPostID", addReferenceFk2Node.FkColumns[1]); Assert.AreEqual("BlogPost", addReferenceFk2Node.PkTable); Assert.AreEqual("ID", addReferenceFk2Node.PkColumns[0]); IAlterTableNode alterTableBlogPostApprovalNode = (IAlterTableNode)version3Node.ChildNodes[4]; IRemoveReferenceNode removeReferenceFk2Node = (IRemoveReferenceNode)alterTableBlogPostApprovalNode.ChildNodes[0]; Assert.AreEqual("FK2", removeReferenceFk2Node.Name); Assert.AreEqual("BlogPostApproval", removeReferenceFk2Node.Table); IRemoveReferenceNode removeReferenceFk1Node = (IRemoveReferenceNode)version3Node.ChildNodes[5]; Assert.AreEqual("FK1", removeReferenceFk1Node.Name); Assert.AreEqual("BlogPostApproval", removeReferenceFk1Node.Table); ITableDefinition blogPostTable = environment.Schema.GetTable("BlogPost"); Assert.IsNotNull(blogPostTable); Assert.IsNotNull(blogPostTable.GetColumn("ID")); Assert.IsNotNull(blogPostTable.GetColumn("Version")); Assert.IsNotNull(blogPostTable.GetColumn("PublishedOn")); ITableDefinition blogPostApprovalTable = environment.Schema.GetTable("BlogPostApproval"); Assert.IsNotNull(blogPostApprovalTable); Assert.IsNotNull(blogPostApprovalTable.GetColumn("BlogPostID")); Assert.IsNotNull(blogPostApprovalTable.GetColumn("ApprovedOn")); Assert.IsNotNull(blogPostApprovalTable.GetColumn("Bar")); Assert.AreEqual(3, blogPostApprovalTable.References.Count); IReferenceDefinition referenceFk0 = blogPostApprovalTable.GetReference("FK0"); Assert.IsNotNull(referenceFk0); IReferenceDefinition referenceAnonymous = null; foreach (IReferenceDefinition r in blogPostApprovalTable.References) if(environment.IsAnonymousIdentifier(r.Name)) { referenceAnonymous = r; break; } Assert.IsNotNull(referenceAnonymous); }
public void BindConstraints() { Environment environment = new Environment(); NamingCompilerStage namingStage = new NamingCompilerStage(); namingStage.SetEnvironment(environment); IMdlCompilerStage bindingStage = new BindingCompilerStage(); bindingStage.SetEnvironment(environment); IAstNode astNode = new MdlParser(MdlParserTestFixture.CreateScanner( @"migration ""Waffle"" revision => 1: version 1: add table BlogPost: ID type => Int32, primary-key => true: constraint ""DF_ID"" default => 0 constraint default => 1 add constraint ""DFID2"" column => ID, default => 2 remove constraint ""DFID3"" table => BlogPost alter table BlogPost: remove constraint ""DFID2""")).Parse(); astNode.Accept(namingStage); astNode.Accept(bindingStage); IVersionNode version1Node = (IVersionNode)astNode.ChildNodes[0]; IAddTableNode addBlogPostTableNode = (IAddTableNode)version1Node.ChildNodes[0]; IAddConstraintNode addDfIdConstraintNode = (IAddConstraintNode)addBlogPostTableNode.ChildNodes[0].ChildNodes[0]; Assert.AreEqual("DF_ID", addDfIdConstraintNode.Name); Assert.AreEqual("BlogPost", addDfIdConstraintNode.Table); Assert.AreEqual("ID", addDfIdConstraintNode.Columns[0]); Assert.AreEqual(0, AstNodePropertyUtil.AsInteger(addDfIdConstraintNode.Properties, "default")); IDefaultConstraintDefinition dfIDConstraintDefinition = (IDefaultConstraintDefinition) environment.Schema.GetTable(addDfIdConstraintNode.Table).GetConstraint(addDfIdConstraintNode.Name); Assert.IsNotNull(dfIDConstraintDefinition); IAddConstraintNode addDbID2ConstraintNode = (IAddConstraintNode)addBlogPostTableNode.ChildNodes[1]; Assert.AreEqual("DFID2", addDbID2ConstraintNode.Name); Assert.AreEqual("ID", AstNodePropertyUtil.AsString(addDbID2ConstraintNode.Properties, "column")); Assert.AreEqual(2, AstNodePropertyUtil.AsInteger(addDbID2ConstraintNode.Properties, "default")); IRemoveConstraintNode removeDfId3ConstraintNode = (IRemoveConstraintNode)version1Node.ChildNodes[1]; Assert.AreEqual("DFID3", removeDfId3ConstraintNode.Name); Assert.AreEqual("BlogPost", AstNodePropertyUtil.AsString(removeDfId3ConstraintNode.Properties, "table")); IRemoveConstraintNode removeDfId2ConstraintNode = (IRemoveConstraintNode)version1Node.ChildNodes[2].ChildNodes[0]; Assert.AreEqual("DFID2", removeDfId2ConstraintNode.Name); Assert.AreEqual("BlogPost", removeDfId2ConstraintNode.Table); }
public void BindIndexes() { Environment environment = new Environment(); NamingCompilerStage namingStage = new NamingCompilerStage(); namingStage.SetEnvironment(environment); IMdlCompilerStage bindingStage = new BindingCompilerStage(); bindingStage.SetEnvironment(environment); IAstNode astNode = new MdlParser(MdlParserTestFixture.CreateScanner( @"migration ""Waffle"" revision => 1: version 1: add table BlogPost: ID type => Int32, primary-key => true: index ""IX_ID"" unique => true, clustered => true Version type => Int32 alter table BlogPost: add column PublishedOn type => DateTime: index ""IX_PublishedOn"" index add index ""IX_Pub"" column => PublishedOn add index IX_Foo table => BlogPost, columns => [[ID, descending], PublishedOn] remove index IX_Foo table => BlogPost alter table BlogPost: remove index IX_Pub add index IX_Foo2 table => BlogPost, column => [ID, descending]")).Parse(); astNode.Accept(namingStage); astNode.Accept(bindingStage); IVersionNode version1Node = (IVersionNode)astNode.ChildNodes[0]; IAddIndexNode addIxIdIndexNode = (IAddIndexNode)version1Node.ChildNodes[0].ChildNodes[0].ChildNodes[0]; Assert.AreEqual("IX_ID", addIxIdIndexNode.Name); Assert.AreEqual("ID", addIxIdIndexNode.Columns[0].Name); Assert.IsFalse(addIxIdIndexNode.Columns[0].SortDirection.HasValue); Assert.IsTrue(addIxIdIndexNode.Unique.Value); Assert.IsTrue(addIxIdIndexNode.Clustered.Value); IAddIndexNode addIxPubIndexNode = (IAddIndexNode)version1Node.ChildNodes[1].ChildNodes[1]; Assert.AreEqual("IX_Pub", addIxPubIndexNode.Name); Assert.AreEqual("BlogPost", addIxPubIndexNode.Table); IAddIndexNode addIxFooIndexNode = (IAddIndexNode)version1Node.ChildNodes[2]; Assert.AreEqual("IX_Foo", addIxFooIndexNode.Name); Assert.AreEqual("BlogPost", addIxFooIndexNode.Table); Assert.AreEqual("PublishedOn", addIxPubIndexNode.Columns[0].Name); Assert.IsFalse(addIxPubIndexNode.Columns[0].SortDirection.HasValue); Assert.AreEqual(2, addIxFooIndexNode.Columns.Count); Assert.AreEqual("ID", addIxFooIndexNode.Columns[0].Name); Assert.AreEqual(SortDirection.Descending, addIxFooIndexNode.Columns[0].SortDirection.Value); Assert.AreEqual("PublishedOn", addIxFooIndexNode.Columns[1].Name); IRemoveIndexNode removeIndexIxFooNode = (IRemoveIndexNode)version1Node.ChildNodes[3]; Assert.AreEqual("IX_Foo", removeIndexIxFooNode.Name); Assert.AreEqual("BlogPost", removeIndexIxFooNode.Table); IRemoveIndexNode removeIndexIxPubNode = (IRemoveIndexNode)version1Node.ChildNodes[4].ChildNodes[0]; Assert.AreEqual("IX_Pub", removeIndexIxPubNode.Name); Assert.AreEqual("BlogPost", removeIndexIxPubNode.Table); ITableDefinition blogPostTable = environment.Schema.GetTable("BlogPost"); Assert.IsNotNull(blogPostTable); Assert.AreEqual(3, blogPostTable.Columns.Count); Assert.IsNotNull(blogPostTable.GetColumn("ID")); Assert.IsNotNull(blogPostTable.GetColumn("Version")); Assert.IsNotNull(blogPostTable.GetColumn("PublishedOn")); Assert.AreEqual(4, blogPostTable.Indexes.Count); Assert.AreEqual("IX_ID", blogPostTable.Indexes[0].Name); Assert.AreEqual("IX_PublishedOn", blogPostTable.Indexes[1].Name); Assert.IsTrue(environment.IsAnonymousIdentifier(blogPostTable.Indexes[2].Name)); IAddIndexNode addIxFoo2IndexNode = (IAddIndexNode)version1Node.ChildNodes[5]; Assert.AreEqual("IX_Foo2", addIxFoo2IndexNode.Name); Assert.AreEqual("BlogPost", addIxFoo2IndexNode.Table); Assert.AreEqual("ID", addIxFoo2IndexNode.Columns[0].Name); Assert.IsTrue(addIxFoo2IndexNode.Columns[0].SortDirection.HasValue); Assert.AreEqual(SortDirection.Descending, addIxFoo2IndexNode.Columns[0].SortDirection); }