static void ApplyChangeScript(NpgsqlConnection connection, ChangeScriptFile script, IReadOnlyDictionary <string, string> variables) { var content = File.ReadAllText(script.FullPath); var directives = ChangeScriptDirectiveParser.Parse(content); var commandText = new StringBuilder(); if (directives.IsTransacted) { commandText.AppendLine("START TRANSACTION ISOLATION LEVEL REPEATABLE READ;"); } commandText.AppendLine(ChangeScriptVariableProcessor.InsertVariables(content, variables)); commandText.AppendLine(";"); commandText.AppendLine(AppliedChangeScriptLog.CreateApplyLogScriptFor(script)); if (directives.IsTransacted) { commandText.AppendLine("COMMIT TRANSACTION;"); } using (var command = new NpgsqlCommand(commandText.ToString(), connection)) { command.ExecuteNonQuery(); } }
protected override int Run() { _loggingFeature.Configure(); if (!(Require(_databaseFeature.Host, "host") && Require(_databaseFeature.Database, "database") && Require("username", _usernamePasswordFeature.Username) && Require("password", _usernamePasswordFeature.Password))) { return(-1); } try { using (var connection = DatabaseConnector.Connect(_databaseFeature.Host, _databaseFeature.Database, _usernamePasswordFeature.Username, _usernamePasswordFeature.Password, false)) { foreach (var applied in AppliedChangeScriptLog.GetAppliedChangeScripts(connection)) { Console.WriteLine($"{applied.AppliedAt:o} {applied.AppliedBy} {applied.ScriptFile}"); } } return(0); } catch (Exception ex) { Log.Fatal(ex, "Could not apply change scripts"); return(-1); } }
public static void BaselineDatabase(string host, string database, string username, string password, string scriptRoot) { using (var connection = DatabaseConnector.Connect(host, database, username, password, false)) { var scripts = DatabaseStatus.GetPendingScripts(connection, scriptRoot); Log.Information("Found {Count} script files without change log records", scripts.Length); if (scripts.Length != 0) { var commandText = new StringBuilder(); commandText.AppendLine("START TRANSACTION ISOLATION LEVEL REPEATABLE READ;"); commandText.AppendLine(AppliedChangeScriptLog.ChangesTableCreateScript); foreach (var script in scripts) { Log.Information("Recording {FullPath} as {ScriptFile}", script.FullPath, script.RelativeName); commandText.AppendLine(AppliedChangeScriptLog.CreateApplyLogScriptFor(script)); } commandText.AppendLine("COMMIT TRANSACTION;"); Log.Information("Writing change log"); using (var command = new NpgsqlCommand(commandText.ToString(), connection)) { command.ExecuteNonQuery(); } } Log.Information("Done"); } }
public static ChangeScriptFile[] GetPendingScripts(NpgsqlConnection connection, string scriptRoot) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (scriptRoot == null) { throw new ArgumentNullException(nameof(scriptRoot)); } var changes = AppliedChangeScriptLog.GetAppliedChangeScripts(connection); var applied = new HashSet <string>(changes.Select(m => m.ScriptFile)); return(ChangeScriptFileEnumerator.EnumerateInOrder(scriptRoot) .Where(s => !applied.Contains(s.RelativeName)) .ToArray()); }
public static void ApplyChangeScripts(string host, string database, string username, string password, bool createIfMissing, string scriptRoot, IReadOnlyDictionary <string, string> variables) { Log.Information("Connecting to database {Database} on {Host}", database, host); using (var connection = DatabaseConnector.Connect(host, database, username, password, createIfMissing)) { Log.Information("Connected"); Log.Information("Loading applied change scripts from the database"); var changes = AppliedChangeScriptLog.GetAppliedChangeScripts(connection); Log.Information("Database history contains {AppliedCount} applied changes", changes.Length); Log.Information("Searching for *.sql change script files in {ScriptRoot}", scriptRoot); var applied = new HashSet <string>(changes.Select(m => m.ScriptFile)); var scripts = ChangeScriptFileEnumerator.EnumerateInOrder(scriptRoot) .Where(s => !applied.Contains(s.RelativeName)) .ToArray(); Log.Information("Found {Count} new script files to apply", scripts.Length); if (scripts.Length != 0) { Log.Information("Ensuring the change log table exists"); using (var command = new NpgsqlCommand(AppliedChangeScriptLog.ChangesTableCreateScript, connection)) command.ExecuteNonQuery(); } foreach (var script in scripts) { Log.Information("Applying {FullPath} as {ScriptFile}", script.FullPath, script.RelativeName); ApplyChangeScript(connection, script, variables); } Log.Information("Done"); } }