/// <summary>
/// Executes the a database deployment with the specified config.
/// </summary>
/// <param name="config">The config.</param>
/// <param name="infoWriter">The info writer.</param>
/// <exception cref="System.InvalidOperationException">SQLCMD mode can only be applied against an mssql database.</exception>
public void Execute(DbDeployConfig config, TextWriter infoWriter)
{
this.Validate(config, infoWriter);
infoWriter.WriteLine();
infoWriter.WriteLine("==========================================================");
infoWriter.WriteLine(this.GenerateWelcomeString());
var factory = new DbmsFactory(config.Dbms, config.ConnectionString);
var dbmsSyntax = factory.CreateDbmsSyntax();
var queryExecuter = new QueryExecuter(factory);
var databaseSchemaVersionManager = new DatabaseSchemaVersionManager(queryExecuter, dbmsSyntax, config.ChangeLogTableName, config.AutoCreateChangeLogTable);
var scanner = new DirectoryScanner(infoWriter, config.Encoding);
var changeScriptRepository = new ChangeScriptRepository(scanner.GetChangeScriptsForDirectory(config.ScriptDirectory));
IChangeScriptApplier doScriptApplier;
TextWriter doWriter = null;
QueryExecuter applierExecutor = null;
if (config.OutputFile != null)
{
doWriter = new StreamWriter(config.OutputFile.OpenWrite(), config.Encoding);
doScriptApplier = new TemplateBasedApplier(
doWriter,
config.Dbms,
config.ChangeLogTableName,
config.Delimiter,
config.DelimiterType,
config.TemplateDirectory);
}
else if (config.UseSqlCmd)
{
// Verify database is MSSQL.
if (!string.Equals(config.Dbms, "mssql", StringComparison.InvariantCultureIgnoreCase))
{
throw new InvalidOperationException("SQLCMD mode can only be applied against an mssql database.");
}
doScriptApplier = new SqlCmdApplier(config.ConnectionString, databaseSchemaVersionManager, infoWriter);
}
else
{
var splitter = new QueryStatementSplitter
{
Delimiter = config.Delimiter,
DelimiterType = config.DelimiterType,
LineEnding = config.LineEnding,
};
// Do not share query executor between schema manager and applier, since a failure in one will effect the other.
applierExecutor = new QueryExecuter(factory);
doScriptApplier = new DirectToDbApplier(
applierExecutor,
databaseSchemaVersionManager,
splitter,
infoWriter);
}
IChangeScriptApplier undoScriptApplier = null;
TextWriter undoWriter = null;
if (config.UndoOutputFile != null)
{
undoWriter = new StreamWriter(config.UndoOutputFile.OpenWrite(), config.Encoding);
undoScriptApplier = new UndoTemplateBasedApplier(
undoWriter,
config.Dbms,
config.ChangeLogTableName,
config.Delimiter,
config.DelimiterType,
config.TemplateDirectory);
}
try
{
var controller = new Controller(
changeScriptRepository,
databaseSchemaVersionManager,
doScriptApplier,
undoScriptApplier,
infoWriter);
controller.ProcessChangeScripts(config.LastChangeToApply, config.ForceUpdate);
queryExecuter.Close();
if (applierExecutor != null)
{
applierExecutor.Close();
}
}
finally
{
if (doWriter != null)
{
doWriter.Dispose();
}
if (undoWriter != null)
{
undoWriter.Dispose();
}
}
}