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;
        }
        protected override void InternalExecute(MigrationParameters parameters)
        {
            IAstNode astNode;
            using(var streamReader = new StreamReader(parameters.MdlFileName))
                astNode = new MdlCompiler(null, new Core.Compiler.Environment()).Compile(streamReader,
                    MdlCompilationOptions.InferTypes | MdlCompilationOptions.ResolvePrimaryKeys | 
                    MdlCompilationOptions.ResolvePropertyValues | MdlCompilationOptions.ResolveTypeAliases);

            System.Console.WriteLine();

            var migrationNode = (IMigrationNode)astNode;
            if(migrationNode.Revision == 2)
            {
                using(new ConsoleStylingScope(ConsoleColor.Green))
                    System.Console.WriteLine(Resources.MigrationDefinitionIsUpToDate);

                return;
            } // if

            using(new ConsoleStylingScope(ConsoleColor.Yellow))
                System.Console.WriteLine(Resources.UpdatingMigrationDefinition, migrationNode.Revision, 2);

            string migrationDefinition;
            using(var streamReader = new StreamReader(parameters.MdlFileName))
                migrationDefinition = streamReader.ReadToEnd();

            migrationDefinition = migrationDefinition.Replace("revision => 1", "revision => 2");

            var updateMigration =
                @"migration ""__wizardby"" revision => 2:
    version 1:
        alter table SchemaInfo:
            add column Module type => String, length => 200, nullable => true";

            using(var streamWriter = new StreamWriter(parameters.MdlFileName, false))
                streamWriter.WriteLine(migrationDefinition);

        }
        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 ReverseEngineer()
        {
            IReverseEngineeringService reverseEngineeringService = new ReverseEngineeringService();
            IAstNode astNode = reverseEngineeringService.ReverseEngineer(dbPlatform, connectionString);

            Assert.IsInstanceOfType(typeof(IBaselineNode), astNode);

            IAddTableNode addBlogAuthorJunctionTableNode = 
                (IAddTableNode)Algorithms.FindFirst<IAstNode>(astNode.ChildNodes,
                    delegate(IAstNode an) 
                        { return an is IAddTableNode && ((IAddTableNode)an).Name == "BlogAuthorJunction"; });
            
            Assert.IsNotNull(addBlogAuthorJunctionTableNode);

            AssertAddReference(Algorithms.FindFirst(astNode.ChildNodes,
                delegate(IAstNode an)
                    { return an is IAddReferenceNode && ((IAddReferenceNode)an).Name == "FK12"; }),
                    "FK12", 
                    "Blog", new string[] { "ID" },
                    "BlogAuthorJunction", new string[] { "BlogID" });
            /*Assert.IsNotNull(Algorithms.FindFirst<IAstNode>(addBlogAuthorJunctionTableNode.ChildNodes,
                delegate(IAstNode an)
                    { return an is IAddReferenceNode && ((IAddReferenceNode)an).Name == "FK13"; }));*/

            //
            // Assert that all "add tables" go first, and indexes and references
            // go afterwards
            int lastAddTable = Algorithms.LastIndexOf(astNode.ChildNodes, 
                delegate(IAstNode node) { return node is IAddTableNode; });
            int firstAddReference = Algorithms.FirstIndexOf(astNode.ChildNodes,
                delegate(IAstNode node) { return node is IAddReferenceNode; });

            Assert.IsTrue(lastAddTable < firstAddReference);

            //
            // Ensure that the AST produced by the RES can be compiled
            MdlCompiler mdlCompiler = new MdlCompiler(new NullCodeGenerator(), new Wizardby.Core.Compiler.Environment());
            mdlCompiler.Compile(astNode, MdlCompilationOptions.All);
        }