示例#1
0
        private static void DoScript(
            string pathOrNull,
            bool naive,
            ConnectionStringSettings connectionStringSettings,
            DashingSettings dashingSettings,
            ReverseEngineerSettings reverseEngineerSettings)
        {
            DisplayMigrationHeader(naive, dashingSettings);

            // fetch the to state
            var config = (IConfiguration)configObject;

            IEnumerable <string> warnings, errors;
            var migrationScript = GenerateMigrationScript(connectionStringSettings, reverseEngineerSettings, config, naive, out warnings, out errors);

            // report errors
            DisplayMigrationWarningsAndErrors(errors, warnings);

            if (string.IsNullOrWhiteSpace(migrationScript))
            {
                migrationScript = "-- Nothing to be migrated";
            }

            // write it
            using (var writer = string.IsNullOrEmpty(pathOrNull) ? Console.Out : new StreamWriter(File.OpenWrite(pathOrNull))) {
                writer.WriteLine(migrationScript);
            }
        }
示例#2
0
        private static void DoSeed(ConnectionStringSettings connectionStringSettings)
        {
            // fetch the to state
            var config = (IConfiguration)configObject;

            var factory = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName);

            using (var connection = factory.CreateConnection()) {
                if (connection == null)
                {
                    throw new Exception("Could not connect to database");
                }

                connection.ConnectionString = connectionStringSettings.ConnectionString;
                connection.Open();

                // now let's call Seed
                var seederConfig = config as ISeeder;
                if (seederConfig != null)
                {
                    using (new TimedOperation("-- Executing seeds")) {
                        using (var session = config.BeginSession(connection)) {
                            seederConfig.Seed(session);
                            session.Complete();
                        }
                    }
                }
            }
        }
示例#3
0
        private static object LoadConfiguration(
            Assembly configAssembly,
            DashingSettings dashingSettings,
            ConnectionStringSettings connectionStringSettings)
        {
            // fetch the to state
            var configType = configAssembly.GetLoadableTypes().SingleOrDefault(t => t.FullName == dashingSettings.ConfigurationName);

            if (configType == null)
            {
                using (Color(ConsoleColor.Red)) {
                    var candidates = configAssembly.GetLoadableTypes().Where(t => t.GetInterface(typeof(IConfiguration).FullName) != null).ToArray();
                    if (candidates.Any())
                    {
                        throw new CatchyException(
                                  "Could not locate {0}, but found candidates: {1}",
                                  dashingSettings.ConfigurationName,
                                  string.Join(", ", candidates.Select(c => c.FullName)));
                    }

                    throw new CatchyException("Could not locate {0}, and found no candidate configurations", dashingSettings.ConfigurationName);
                }
            }

            // attempt to find the call to ConfigurationManager and overwrite the connection string
            InjectConnectionString(dashingSettings, connectionStringSettings);

            // TODO add in a factory way of generating the config for cases where constructor not empty
            return(Activator.CreateInstance(configType));
        }
示例#4
0
        private static void InjectConnectionString(DashingSettings dashingSettings, ConnectionStringSettings connectionStringSettings)
        {
            var assemblyDefinition = AssemblyDefinition.ReadAssembly(dashingSettings.PathToDll);
            var cecilConfigType    = assemblyDefinition.MainModule.Types.Single(t => t.FullName == dashingSettings.ConfigurationName);
            var constructor        = cecilConfigType.Methods.FirstOrDefault(m => m.IsConstructor && !m.HasParameters); // default constructor

            if (constructor == null)
            {
                using (Color(ConsoleColor.Red)) {
                    throw new CatchyException("Unable to find a Default Constructor on the Configuration");
                }
            }

            var getConnectionStringCall =
                constructor.Body.Instructions.FirstOrDefault(
                    i =>
                    i.OpCode.Code == Code.Call &&
                    i.Operand.ToString()
                    == "System.Configuration.ConnectionStringSettingsCollection System.Configuration.ConfigurationManager::get_ConnectionStrings()");

            if (getConnectionStringCall == null)
            {
                using (Color(ConsoleColor.Red)) {
                    throw new CatchyException("Unable to find the ConnectionStrings call in the constructor");
                }
            }

            var connectionStringKey = getConnectionStringCall.Next.Operand.ToString();

            // override readonly property of connectionstrings
            var readOnlyField = typeof(ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);

            if (readOnlyField != null)
            {
                readOnlyField.SetValue(ConfigurationManager.ConnectionStrings, false);
            }

            // remove any existing
            if (ConfigurationManager.ConnectionStrings[connectionStringKey] != null)
            {
                ConfigurationManager.ConnectionStrings.Remove(connectionStringKey);
            }

            // and add in the one from our ini
            ConfigurationManager.ConnectionStrings.Add(
                new System.Configuration.ConnectionStringSettings(
                    connectionStringKey,
                    connectionStringSettings.ConnectionString,
                    connectionStringSettings.ProviderName));
        }
示例#5
0
        private static void DoReverseEngineer(
            CommandLineOptions options,
            DashingSettings dashingSettings,
            ReverseEngineerSettings reverseEngineerSettings,
            ConnectionStringSettings connectionString)
        {
            // overwrite the path with the default if necessary
            if (string.IsNullOrEmpty(options.Location))
            {
                options.Location = dashingSettings.DefaultSavePath;
            }

            // if it is still empty, ...
            if (string.IsNullOrEmpty(options.Location) && options.ReverseEngineer)
            {
                throw new CatchyException("You must specify a location for generated files to be saved");
            }

            // require a generated namespace
            if (string.IsNullOrEmpty(reverseEngineerSettings.GeneratedNamespace))
            {
                throw new CatchyException("You must specify a GeneratedNamespace in the Project ini file");
            }

            DatabaseSchema schema;
            var            engineer = new Engineer(reverseEngineerSettings.ExtraPluralizationWords);

            var databaseReader = new DatabaseReader(connectionString.ConnectionString, connectionString.ProviderName);

            schema = databaseReader.ReadAll();
            var maps = engineer.ReverseEngineer(
                schema,
                new DialectFactory().Create(connectionString.ToSystem()),
                reverseEngineerSettings.GetTablesToIgnore(),
                consoleAnswerProvider,
                true);
            var reverseEngineer = new ModelGenerator();
            var sources         = reverseEngineer.GenerateFiles(maps, schema, reverseEngineerSettings.GeneratedNamespace, consoleAnswerProvider);

            foreach (var source in sources)
            {
                File.WriteAllText(options.Location + "\\" + source.Key + ".cs", source.Value);
            }
        }
示例#6
0
        private static void ParseIni(
            CommandLineOptions options,
            out ConnectionStringSettings connectionStringSettings,
            out DashingSettings dashingSettings,
            out ReverseEngineerSettings reverseEngineerSettings)
        {
            var config = IniParser.Parse(options.ConfigPath);

            connectionStringSettings = new ConnectionStringSettings();
            connectionStringSettings = IniParser.AssignTo(config["Database"], connectionStringSettings);

            dashingSettings = new DashingSettings();
            dashingSettings = IniParser.AssignTo(config["Dashing"], dashingSettings);

            // fix path to dll to be avsolute path
            if (!Path.IsPathRooted(dashingSettings.PathToDll))
            {
                dashingSettings.PathToDll = Path.Combine(Path.GetDirectoryName(options.ConfigPath), dashingSettings.PathToDll);
            }

            reverseEngineerSettings = new ReverseEngineerSettings();
            reverseEngineerSettings = IniParser.AssignTo(config["ReverseEngineer"], reverseEngineerSettings);
        }
示例#7
0
 private static void CreateDatabaseIfNotExists(ConnectionStringSettings connectionStringSettings, DbProviderFactory factory, ISqlDialect dialect)
 {
     using (new TimedOperation("-- Checking for Existence of Database...")) {
         var connectionStringManipulator = new ConnectionStringManipulator(connectionStringSettings.ToSystem());
         using (var connection = factory.CreateConnection()) {
             connection.ConnectionString = connectionStringManipulator.GetRootConnectionString().ConnectionString;
             connection.Open();
             var databaseName = connectionStringManipulator.GetDatabaseName();
             Trace("Looking for {0}", databaseName);
             if (!connection.Query(dialect.CheckDatabaseExists(databaseName)).Any())
             {
                 Trace("Not Found");
                 Trace("Creating");
                 connection.Execute(dialect.CreateDatabase(databaseName));
                 Trace("Created");
             }
             else
             {
                 Trace("Found!");
             }
         }
     }
 }
示例#8
0
        private static string GenerateMigrationScript(
            ConnectionStringSettings connectionStringSettings,
            ReverseEngineerSettings reverseEngineerSettings,
            IConfiguration configuration,
            bool naive,
            out IEnumerable <string> warnings,
            out IEnumerable <string> errors)
        {
            // fetch the from state
            var dialectFactory = new DialectFactory();
            var dialect        = dialectFactory.Create(connectionStringSettings.ToSystem());
            var factory        = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName);

            // create database if not exists
            CreateDatabaseIfNotExists(connectionStringSettings, factory, dialect);

            DatabaseSchema schema;

            using (new TimedOperation("-- Reading database contents...")) {
                var databaseReader = new DatabaseReader(connectionStringSettings.ConnectionString, connectionStringSettings.ProviderName);
                schema = databaseReader.ReadAll();
            }

            IEnumerable <IMap> fromMaps;

            using (new TimedOperation("-- Reverse engineering...")) {
                Console.WriteLine();
                var engineer = new Engineer(reverseEngineerSettings.ExtraPluralizationWords);
                fromMaps = engineer.ReverseEngineer(schema, dialect, reverseEngineerSettings.GetTablesToIgnore(), consoleAnswerProvider, false);
                Console.Write("-- ");
            }

            using (var connection = factory.CreateConnection()) {
                connection.ConnectionString = connectionStringSettings.ConnectionString;
                // set up migrator
                IMigrator migrator;
                if (naive)
                {
                    throw new NotSupportedException("The Naive Migrator is no longer supported");
                }
                migrator = new Migrator(
                    dialect,
                    new CreateTableWriter(dialect),
                    new AlterTableWriter(dialect),
                    new DropTableWriter(dialect),
                    new StatisticsProvider(connection, dialect));

                // run the migrator
                string script;
                using (new TimedOperation("-- Generating diff...")) {
                    script = migrator.GenerateSqlDiff(
                        fromMaps,
                        configuration.Maps,
                        consoleAnswerProvider,
                        new ConsoleLogger(isVerbose),
                        reverseEngineerSettings.GetIndexesToIgnore(),
                        out warnings,
                        out errors);

                    // TODO: do things with warnings and errors
                    return(script);
                }
            }
        }
示例#9
0
        private static void ParseIni(
            CommandLineOptions options,
            out ConnectionStringSettings connectionStringSettings,
            out DashingSettings dashingSettings,
            out ReverseEngineerSettings reverseEngineerSettings) {
            var config = IniParser.Parse(options.ConfigPath);

            connectionStringSettings = new ConnectionStringSettings();
            connectionStringSettings = IniParser.AssignTo(config["Database"], connectionStringSettings);

            dashingSettings = new DashingSettings();
            dashingSettings = IniParser.AssignTo(config["Dashing"], dashingSettings);

            // fix path to dll to be avsolute path
            if (!Path.IsPathRooted(dashingSettings.PathToDll)) {
                dashingSettings.PathToDll = Path.Combine(Path.GetDirectoryName(options.ConfigPath), dashingSettings.PathToDll);
            }

            reverseEngineerSettings = new ReverseEngineerSettings();
            reverseEngineerSettings = IniParser.AssignTo(config["ReverseEngineer"], reverseEngineerSettings);
        }
示例#10
0
        private static void DoScript(
            string pathOrNull,
            bool naive,
            ConnectionStringSettings connectionStringSettings,
            DashingSettings dashingSettings,
            ReverseEngineerSettings reverseEngineerSettings) {
            DisplayMigrationHeader(naive, dashingSettings);

            // fetch the to state
            var config = (IConfiguration)configObject;

            IEnumerable<string> warnings, errors;
            var migrationScript = GenerateMigrationScript(connectionStringSettings, reverseEngineerSettings, config, naive, out warnings, out errors);

            // report errors
            DisplayMigrationWarningsAndErrors(errors, warnings);

            if (string.IsNullOrWhiteSpace(migrationScript)) {
                migrationScript = "-- Nothing to be migrated";
            }

            // write it
            using (var writer = string.IsNullOrEmpty(pathOrNull) ? Console.Out : new StreamWriter(File.OpenWrite(pathOrNull))) {
                writer.WriteLine(migrationScript);
            }
        }
示例#11
0
        private static void InjectConnectionString(DashingSettings dashingSettings, ConnectionStringSettings connectionStringSettings) {
            var assemblyDefinition = AssemblyDefinition.ReadAssembly(dashingSettings.PathToDll);
            var cecilConfigType = assemblyDefinition.MainModule.Types.Single(t => t.FullName == dashingSettings.ConfigurationName);
            var constructor = cecilConfigType.Methods.FirstOrDefault(m => m.IsConstructor && !m.HasParameters); // default constructor
            if (constructor == null) {
                using (Color(ConsoleColor.Red)) {
                    throw new CatchyException("Unable to find a Default Constructor on the Configuration");
                }
            }

            var getConnectionStringCall =
                constructor.Body.Instructions.FirstOrDefault(
                    i =>
                    i.OpCode.Code == Code.Call
                    && i.Operand.ToString()
                    == "System.Configuration.ConnectionStringSettingsCollection System.Configuration.ConfigurationManager::get_ConnectionStrings()");
            if (getConnectionStringCall == null) {
                using (Color(ConsoleColor.Red)) {
                    throw new CatchyException("Unable to find the ConnectionStrings call in the constructor");
                }
            }

            var connectionStringKey = getConnectionStringCall.Next.Operand.ToString();

            // override readonly property of connectionstrings
            var readOnlyField = typeof(ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
            if (readOnlyField != null) {
                readOnlyField.SetValue(ConfigurationManager.ConnectionStrings, false);
            }

            // remove any existing
            if (ConfigurationManager.ConnectionStrings[connectionStringKey] != null) {
                ConfigurationManager.ConnectionStrings.Remove(connectionStringKey);
            }

            // and add in the one from our ini
            ConfigurationManager.ConnectionStrings.Add(
                new System.Configuration.ConnectionStringSettings(
                    connectionStringKey,
                    connectionStringSettings.ConnectionString,
                    connectionStringSettings.ProviderName));
        }
示例#12
0
        private static void DoMigrate(
            bool naive,
            ConnectionStringSettings connectionStringSettings,
            DashingSettings dashingSettings,
            ReverseEngineerSettings reverseEngineerSettings) {
            DisplayMigrationHeader(naive, dashingSettings);

            // fetch the to state
            var config = (IConfiguration)configObject;

            IEnumerable<string> warnings, errors;
            var script = GenerateMigrationScript(connectionStringSettings, reverseEngineerSettings, config, naive, out warnings, out errors);

            if (DisplayMigrationWarningsAndErrors(errors, warnings)) {
                using (Color(ConsoleColor.Red)) {
                    Console.WriteLine("-- Fatal errors encountered: aborting migration. Please review the output.");
                }
            }
            else {
                // migrate it
                var factory = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName);
                using (var connection = factory.CreateConnection()) {
                    if (connection == null) {
                        throw new Exception("Could not connect to database");
                    }

                    connection.ConnectionString = connectionStringSettings.ConnectionString;
                    connection.Open();

                    if (string.IsNullOrWhiteSpace(script)) {
                        using (Color(ConsoleColor.Green)) {
                            Console.WriteLine("-- No migration script to run");
                        }
                    }
                    else {
                        using (new TimedOperation("-- Executing migration script on {0}", connection.ConnectionString)) {
                            using (var command = connection.CreateCommand()) {
                                using (Color(ConsoleColor.DarkGray)) {
                                    Console.WriteLine();
                                    Console.WriteLine(script);
                                    Console.WriteLine();
                                }

                                command.CommandText = script;
                                command.ExecuteNonQuery();
                            }
                        }
                    }

                    // now let's call Seed
                    var seederConfig = config as ISeeder;
                    if (seederConfig != null) {
                        using (new TimedOperation("-- Executing seeds")) {
                            using (var session = config.BeginSession(connection)) {
                                seederConfig.Seed(session);
                                session.Complete();
                            }
                        }
                    }
                }
            }
        }
示例#13
0
        private static void DoMigrate(
            bool naive,
            ConnectionStringSettings connectionStringSettings,
            DashingSettings dashingSettings,
            ReverseEngineerSettings reverseEngineerSettings)
        {
            DisplayMigrationHeader(naive, dashingSettings);

            // fetch the to state
            var config = (IConfiguration)configObject;

            IEnumerable <string> warnings, errors;
            var script = GenerateMigrationScript(connectionStringSettings, reverseEngineerSettings, config, naive, out warnings, out errors);

            if (DisplayMigrationWarningsAndErrors(errors, warnings))
            {
                using (Color(ConsoleColor.Red)) {
                    Console.WriteLine("-- Fatal errors encountered: aborting migration. Please review the output.");
                }
            }
            else
            {
                // migrate it
                var factory = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName);
                using (var connection = factory.CreateConnection()) {
                    if (connection == null)
                    {
                        throw new Exception("Could not connect to database");
                    }

                    connection.ConnectionString = connectionStringSettings.ConnectionString;
                    connection.Open();

                    if (string.IsNullOrWhiteSpace(script))
                    {
                        using (Color(ConsoleColor.Green)) {
                            Console.WriteLine("-- No migration script to run");
                        }
                    }
                    else
                    {
                        using (new TimedOperation("-- Executing migration script on {0}", connection.ConnectionString)) {
                            using (var command = connection.CreateCommand()) {
                                using (Color(ConsoleColor.DarkGray)) {
                                    Console.WriteLine();
                                    Console.WriteLine(script);
                                    Console.WriteLine();
                                }

                                command.CommandText = script;
                                command.ExecuteNonQuery();
                            }
                        }
                    }

                    // now let's call Seed
                    var seederConfig = config as ISeeder;
                    if (seederConfig != null)
                    {
                        using (new TimedOperation("-- Executing seeds")) {
                            using (var session = config.BeginSession(connection)) {
                                seederConfig.Seed(session);
                                session.Complete();
                            }
                        }
                    }
                }
            }
        }
示例#14
0
        private static void DoSeed(ConnectionStringSettings connectionStringSettings) {
            // fetch the to state
            var config = (IConfiguration)configObject;

            var factory = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName);
            using (var connection = factory.CreateConnection()) {
                if (connection == null) {
                    throw new Exception("Could not connect to database");
                }

                connection.ConnectionString = connectionStringSettings.ConnectionString;
                connection.Open();

                // now let's call Seed
                var seederConfig = config as ISeeder;
                if (seederConfig != null) {
                    using (new TimedOperation("-- Executing seeds")) {
                        using (var session = config.BeginSession(connection)) {
                            seederConfig.Seed(session);
                            session.Complete();
                        }
                    }
                }
            }
        }
示例#15
0
        private static void DoReverseEngineer(
            CommandLineOptions options,
            DashingSettings dashingSettings,
            ReverseEngineerSettings reverseEngineerSettings,
            ConnectionStringSettings connectionString) {
            // overwrite the path with the default if necessary
            if (string.IsNullOrEmpty(options.Location)) {
                options.Location = dashingSettings.DefaultSavePath;
            }

            // if it is still empty, ...
            if (string.IsNullOrEmpty(options.Location) && options.ReverseEngineer) {
                throw new CatchyException("You must specify a location for generated files to be saved");
            }

            // require a generated namespace
            if (string.IsNullOrEmpty(reverseEngineerSettings.GeneratedNamespace)) {
                throw new CatchyException("You must specify a GeneratedNamespace in the Project ini file");
            }

            DatabaseSchema schema;
            var engineer = new Engineer(reverseEngineerSettings.ExtraPluralizationWords);

            var databaseReader = new DatabaseReader(connectionString.ConnectionString, connectionString.ProviderName);
            schema = databaseReader.ReadAll();
            var maps = engineer.ReverseEngineer(
                schema,
                new DialectFactory().Create(connectionString.ToSystem()),
                reverseEngineerSettings.GetTablesToIgnore(),
                consoleAnswerProvider,
                true);
            var reverseEngineer = new ModelGenerator();
            var sources = reverseEngineer.GenerateFiles(maps, schema, reverseEngineerSettings.GeneratedNamespace, consoleAnswerProvider);

            foreach (var source in sources) {
                File.WriteAllText(options.Location + "\\" + source.Key + ".cs", source.Value);
            }
        }
示例#16
0
        private static object LoadConfiguration(
            Assembly configAssembly,
            DashingSettings dashingSettings,
            ConnectionStringSettings connectionStringSettings) {
            // fetch the to state
            var configType = configAssembly.GetLoadableTypes().SingleOrDefault(t => t.FullName == dashingSettings.ConfigurationName);

            if (configType == null) {
                using (Color(ConsoleColor.Red)) {
                    var candidates = configAssembly.GetLoadableTypes().Where(t => t.GetInterface(typeof(IConfiguration).FullName) != null).ToArray();
                    if (candidates.Any()) {
                        throw new CatchyException(
                            "Could not locate {0}, but found candidates: {1}",
                            dashingSettings.ConfigurationName,
                            string.Join(", ", candidates.Select(c => c.FullName)));
                    }

                    throw new CatchyException("Could not locate {0}, and found no candidate configurations", dashingSettings.ConfigurationName);
                }
            }

            // attempt to find the call to ConfigurationManager and overwrite the connection string
            InjectConnectionString(dashingSettings, connectionStringSettings);

            // TODO add in a factory way of generating the config for cases where constructor not empty
            return Activator.CreateInstance(configType);
        }
示例#17
0
 private static void CreateDatabaseIfNotExists(ConnectionStringSettings connectionStringSettings, DbProviderFactory factory, ISqlDialect dialect) {
     using (new TimedOperation("-- Checking for Existence of Database...")) {
         var connectionStringManipulator = new ConnectionStringManipulator(connectionStringSettings.ToSystem());
         using (var connection = factory.CreateConnection()) {
             connection.ConnectionString = connectionStringManipulator.GetRootConnectionString().ConnectionString;
             connection.Open();
             var databaseName = connectionStringManipulator.GetDatabaseName();
             Trace("Looking for {0}", databaseName);
             if (!connection.Query(dialect.CheckDatabaseExists(databaseName)).Any()) {
                 Trace("Not Found");
                 Trace("Creating");
                 connection.Execute(dialect.CreateDatabase(databaseName));
                 Trace("Created");
             }
             else {
                 Trace("Found!");
             }
         }
     }
 }
示例#18
0
        private static string GenerateMigrationScript(
            ConnectionStringSettings connectionStringSettings,
            ReverseEngineerSettings reverseEngineerSettings,
            IConfiguration configuration,
            bool naive,
            out IEnumerable<string> warnings,
            out IEnumerable<string> errors) {
            // fetch the from state
            var dialectFactory = new DialectFactory();
            var dialect = dialectFactory.Create(connectionStringSettings.ToSystem());
            var factory = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName);

            // create database if not exists
            CreateDatabaseIfNotExists(connectionStringSettings, factory, dialect);

            DatabaseSchema schema;
            using (new TimedOperation("-- Reading database contents...")) {
                var databaseReader = new DatabaseReader(connectionStringSettings.ConnectionString, connectionStringSettings.ProviderName);
                schema = databaseReader.ReadAll();
            }

            IEnumerable<IMap> fromMaps;
            using (new TimedOperation("-- Reverse engineering...")) {
                Console.WriteLine();
                var engineer = new Engineer(reverseEngineerSettings.ExtraPluralizationWords);
                fromMaps = engineer.ReverseEngineer(schema, dialect, reverseEngineerSettings.GetTablesToIgnore(), consoleAnswerProvider, false);
                Console.Write("-- ");
            }

            using (var connection = factory.CreateConnection()) {
                connection.ConnectionString = connectionStringSettings.ConnectionString;
                // set up migrator
                IMigrator migrator;
                if (naive) {
                    throw new NotSupportedException("The Naive Migrator is no longer supported");
                }
                migrator = new Migrator(
                    dialect,
                    new CreateTableWriter(dialect),
                    new AlterTableWriter(dialect),
                    new DropTableWriter(dialect),
                    new StatisticsProvider(connection, dialect));

                // run the migrator
                string script;
                using (new TimedOperation("-- Generating diff...")) {
                    script = migrator.GenerateSqlDiff(
                        fromMaps,
                        configuration.Maps,
                        consoleAnswerProvider,
                        new ConsoleLogger(isVerbose),
                        reverseEngineerSettings.GetIndexesToIgnore(),
                        out warnings,
                        out errors);

                    // TODO: do things with warnings and errors
                    return script;
                }
            }
        }