예제 #1
0
        public bool GenerateScripts(XmlDocument xmlConfig)
        {
            const string header =
                @"-- DDL Scripts generated by VITA DB Tool. 
-- Generated on: {0}
-- Target database: {1}
-- Executed by user {2} on machine {3}.
";

            _config = new DbUpdateConfig(xmlConfig);
            Util.Check(File.Exists(_config.AssemblyPath), "Assembly file '{0}' not found.", _config.AssemblyPath);
            var asm     = Assembly.LoadFrom(_config.AssemblyPath);
            var appType = asm.GetType(_config.AppClassName);

            Util.Check(appType != null, "Type {0} not found in target assembly.");
            // Using NonPublic flag to allow internal constructor;
            // EntityApp must have a parameterless constructor, but it may be made internal, to hide from regular code
            var flags  = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
            var appObj = Activator.CreateInstance(appType, flags, null, null, null);

            Util.Check(appObj != null, "Failed to create instance of class {0}.", _config.AppClassName);
            var entApp = appObj as EntityApp;

            Util.Check(entApp != null, "The target instance of class {0} is not an EntityApp instance.", _config.AppClassName);
            entApp.Init();
            var dbSettings = new DbSettings(_config.Driver, _config.DbOptions, _config.ConnectionString,
                                            upgradeMode: DbUpgradeMode.Always, upgradeOptions: _config.ModelUpdateOptions);

            /*
             * var schemas = entApp.Areas.Select(a => a.Name).ToList();
             * dbSettings.SetSchemas(schemas);
             */

            var log            = new BufferedLog(LogContext.SystemLogContext);
            var dbModelBuilder = new DbModelBuilder(entApp.Model, dbSettings.ModelConfig, log);
            var dbModel        = dbModelBuilder.Build();
            var db             = new Database(dbModel, dbSettings);
            var updateMgr      = new DbUpgradeManager(db, log);
            var upgrades       = updateMgr.BuildUpgradeInfo();
            var ddlSep         = dbModel.Driver.SqlDialect.DDLSeparator;
            var ddl            = string.Join(ddlSep, upgrades.AllScripts.Select(scr => scr.Sql));

            if (string.IsNullOrEmpty(ddl))
            {
                ddl = "-- (No changes detected)";
            }
            var text = string.Format(header, DateTime.Now.ToString("s"), _config.ConnectionString, "(unknown)", Environment.MachineName) + ddl;

            File.WriteAllText(_config.OutputPath, text);
            _feedback.WriteLine(" Generated {0} scripts.", upgrades.AllScripts.Count);
            _feedback.WriteLine(" DDL scripts are saved to '{0}'", _config.OutputPath);
            return(true);
        }
예제 #2
0
        public bool GenerateEntityModelSources(DbFirstConfig config)
        {
            _feedback.WriteLine("  Provider: " + config.ProviderType);
            _feedback.WriteLine("  Connection string: " + config.ConnectionString);
            _feedback.WriteLine();

            // create driver and check connection
            string error;

            if (!DataUtility.TestConnection(config.Driver, config.ConnectionString, out error))
            {
                _feedback.WriteError(error);
                return(false);
            }

            _feedback.WriteLine("Generating entity definitions...");
            var appBuilder = new DbFirstAppBuilder(_feedback);
            var entAppInfo = appBuilder.Build(config);
            var srcWriter  = new DbFirstSourceWriter(_feedback);

            srcWriter.WriteCsSources(entAppInfo, config);
            // check errors
            if (srcWriter.HasErrors)
            {
                return(false);
            }
            //Everything is ok
            _feedback.WriteLine("The source code is saved to: " + config.OutputPath);
            // Do test compile
            _feedback.WriteLine("Verifying generated code - compiling...");
            var genSource       = File.ReadAllText(config.OutputPath);
            var compilerResults = CompilerHelper.CompileSources(config.Driver.GetType(), genSource);

            if (!compilerResults.Success)
            {
                HasErrors = true;
                _feedback.WriteError("Compile errors detected.");
                foreach (var err in compilerResults.Messages)
                {
                    _feedback.WriteError(err);
                }
                return(false);
            }
            else
            {
                //Compare schema
                _feedback.WriteLine("Verifying generated entities. Running schema comparison ...");
            }

            var    nonProcActions = DbFirstProcessor.CompareDatabaseSchemas(config, compilerResults.Assembly);
            string schemaMessage;

            if (nonProcActions.Count == 0)
            {
                schemaMessage = "Schema verification completed, schemas are identical.";
            }
            else
            {
                HasErrors     = true;
                schemaMessage = Util.SafeFormat("Schema verification: detected {0} differences (schema update actions).\r\n",
                                                nonProcActions.Count);
                schemaMessage += "Schema update actions:\r\n  ";
                schemaMessage += string.Join("\r\n  ", nonProcActions);

                schemaMessage += @"

Note: Non-empty update action list represents the delta between the original database schema and 
      the schema from the generated entities. Ideally this list should be empty. If it is not, 
      then probably some features in your database are not currently supported by VITA. 
";
            }
            //Dump the message to the source file as comment:
            System.IO.File.AppendAllText(config.OutputPath, "\r\n/*\r\n" + schemaMessage + "\r\n*/");
            _feedback.WriteLine();
            _feedback.WriteLine(schemaMessage);
            return(!HasErrors);
        }