public static void Main(string[] args) { var arguments = new PgDiffArguments(); if (arguments.Parse(Console.In, Console.Out, args)) { PgDiff.CreateDiff(Console.Out, arguments); } }
private static void AddModifyTableColumns(List <string> statements, PgDiffArguments arguments, PgTable oldTable, PgTable newTable, List <PgColumn> dropDefaultsColumns) { foreach (var newColumn in newTable.Columns) { if (!oldTable.ContainsColumn(newColumn.Name)) { continue; } var oldColumn = oldTable.GetColumn(newColumn.Name); var newColumnName = PgDiffUtils.GetQuotedName(newColumn.Name); if (!oldColumn.Type.Equals(newColumn.Type)) { statements.Add("\tALTER COLUMN " + newColumnName + " TYPE " + newColumn.Type + " /* " + string.Format(Resources.TypeParameterChange, newTable.Name, oldColumn.Type, newColumn.Type) + " */"); } var oldDefault = oldColumn.DefaultValue ?? ""; var newDefault = newColumn.DefaultValue ?? ""; if (!oldDefault.Equals(newDefault)) { statements.Add(newDefault.Length == 0 ? $"\tALTER COLUMN {newColumnName} DROP DEFAULT" : $"\tALTER COLUMN {newColumnName} SET DEFAULT {newDefault}"); } if (oldColumn.NullValue == newColumn.NullValue) { continue; } if (newColumn.NullValue) { statements.Add($"\tALTER COLUMN {newColumnName} DROP NOT NULL"); } else { if (arguments.AddDefaults) { var defaultValue = PgColumnUtils.GetDefaultValue(newColumn.Type); if (defaultValue != null) { statements.Add($"\tALTER COLUMN {newColumnName} SET DEFAULT {defaultValue}"); dropDefaultsColumns.Add(newColumn); } } statements.Add($"\tALTER COLUMN {newColumnName} SET NOT NULL"); } } }
public static void CreateFunctions(TextWriter writer, PgDiffArguments arguments, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { // Add new functions and replace modified functions foreach (var newFunction in newSchema.GetFunctions()) { var oldFunction = oldSchema?.GetFunction(newFunction.GetSignature()); if (oldFunction == null || !newFunction.Equals(oldFunction, arguments.IgnoreFunctionWhitespace)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(newFunction.GetCreationSql()); } } }
public static void CreateDiff(TextWriter writer, PgDiffArguments arguments, TextReader oldInputStream, TextReader newInputStream) { var oldDatabase = PgDumpLoader.LoadDatabaseSchema( oldInputStream, arguments.InCharsetName, arguments.OutputIgnoredStatements, arguments.IgnoreSlonyTriggers); var newDatabase = PgDumpLoader.LoadDatabaseSchema( newInputStream, arguments.InCharsetName, arguments.OutputIgnoredStatements, arguments.IgnoreSlonyTriggers); DiffDatabaseSchemas(writer, arguments, oldDatabase, newDatabase); }
public static void CreateDiff(TextWriter writer, PgDiffArguments arguments) { var oldDatabase = PgDumpLoader.LoadDatabaseSchema( arguments.OldDumpFile, arguments.InCharsetName, arguments.OutputIgnoredStatements, arguments.IgnoreSlonyTriggers); var newDatabase = PgDumpLoader.LoadDatabaseSchema( arguments.NewDumpFile, arguments.InCharsetName, arguments.OutputIgnoredStatements, arguments.IgnoreSlonyTriggers); DiffDatabaseSchemas(writer, arguments, oldDatabase, newDatabase); }
private static void AddCreateTableColumns(List <string> statements, PgDiffArguments arguments, PgTable oldTable, PgTable newTable, List <PgColumn> dropDefaultsColumns) { foreach (var column in newTable.Columns) { if (!oldTable.ContainsColumn(column.Name)) { statements.Add("\tADD COLUMN " + column.GetFullDefinition(arguments.AddDefaults)); if (arguments.AddDefaults && !column.NullValue && string.IsNullOrEmpty(column.DefaultValue)) { dropDefaultsColumns.Add(column); } } } }
public static void DropFunctions(TextWriter writer, PgDiffArguments arguments, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { if (oldSchema == null) { return; } // Drop functions that exist no more foreach (var oldFunction in oldSchema.GetFunctions()) { if (!newSchema.ContainsFunction(oldFunction.GetSignature())) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(oldFunction.GetDropSql()); } } }
private static void UpdateTableColumns(TextWriter writer, PgDiffArguments arguments, PgTable oldTable, PgTable newTable, SearchPathHelper searchPathHelper) { var statements = new List <string>(); var dropDefaultsColumns = new List <PgColumn>(); AddDropTableColumns(statements, oldTable, newTable); AddCreateTableColumns( statements, arguments, oldTable, newTable, dropDefaultsColumns); AddModifyTableColumns( statements, arguments, oldTable, newTable, dropDefaultsColumns); if (statements.Count > 0) { var quotedTableName = PgDiffUtils.GetQuotedName(newTable.Name); searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine("ALTER TABLE " + quotedTableName); for (var i = 0; i < statements.Count; i++) { writer.Write(statements[i]); writer.WriteLine(i + 1 < statements.Count ? "," : ";"); } if (dropDefaultsColumns.Count > 0) { writer.WriteLine(); writer.WriteLine("ALTER TABLE " + quotedTableName); for (var i = 0; i < dropDefaultsColumns.Count; i++) { writer.Write("\tALTER COLUMN "); writer.Write(PgDiffUtils.GetQuotedName(dropDefaultsColumns[i].Name)); writer.Write(" DROP DEFAULT"); writer.WriteLine(i + 1 < dropDefaultsColumns.Count ? "," : ";"); } } } }
public static void AlterTables(TextWriter writer, PgDiffArguments arguments, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { foreach (var newTable in newSchema.GetTables()) { if (oldSchema == null || !oldSchema.ContainsTable(newTable.Name)) { continue; } var oldTable = oldSchema.GetTable(newTable.Name); UpdateTableColumns(writer, arguments, oldTable, newTable, searchPathHelper); CheckWithOids(writer, oldTable, newTable, searchPathHelper); CheckInherits(writer, oldTable, newTable, searchPathHelper); CheckTablespace(writer, oldTable, newTable, searchPathHelper); AddAlterStatistics(writer, oldTable, newTable, searchPathHelper); AddAlterStorage(writer, oldTable, newTable, searchPathHelper); AlterComments(writer, oldTable, newTable, searchPathHelper); } }
public static void AlterSequences(TextWriter writer, PgDiffArguments arguments, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { if (oldSchema == null) { return; } var sbSql = new StringBuilder(100); foreach (var newSequence in newSchema.GetSequences()) { var oldSequence = oldSchema.GetSequence(newSequence.Name); if (oldSequence == null) { continue; } sbSql.Length = 0; var oldIncrement = oldSequence.Increment; var newIncrement = newSequence.Increment; if (newIncrement != null && !newIncrement.Equals(oldIncrement)) { sbSql.Append("\n\tINCREMENT BY "); sbSql.Append(newIncrement); } var oldMinValue = oldSequence.MinValue; var newMinValue = newSequence.MinValue; if (newMinValue == null && oldMinValue != null) { sbSql.Append("\n\tNO MINVALUE"); } else if (newMinValue != null && !newMinValue.Equals(oldMinValue)) { sbSql.Append("\n\tMINVALUE "); sbSql.Append(newMinValue); } var oldMaxValue = oldSequence.MaxValue; var newMaxValue = newSequence.MaxValue; if (newMaxValue == null && oldMaxValue != null) { sbSql.Append("\n\tNO MAXVALUE"); } else if (newMaxValue != null && !newMaxValue.Equals(oldMaxValue)) { sbSql.Append("\n\tMAXVALUE "); sbSql.Append(newMaxValue); } if (!arguments.IgnoreStartWith) { var oldStart = oldSequence.StartWith; var newStart = newSequence.StartWith; if (newStart != null && !newStart.Equals(oldStart)) { sbSql.Append("\n\tRESTART WITH "); sbSql.Append(newStart); } } var oldCache = oldSequence.Cache; var newCache = newSequence.Cache; if (newCache != null && !newCache.Equals(oldCache)) { sbSql.Append("\n\tCACHE "); sbSql.Append(newCache); } var oldCycle = oldSequence.Cycle; var newCycle = newSequence.Cycle; if (oldCycle && !newCycle) { sbSql.Append("\n\tNO CYCLE"); } else if (!oldCycle && newCycle) { sbSql.Append("\n\tCYCLE"); } var oldOwnedBy = oldSequence.OwnedBy; var newOwnedBy = newSequence.OwnedBy; if (newOwnedBy != null && !newOwnedBy.Equals(oldOwnedBy)) { sbSql.Append("\n\tOWNED BY "); sbSql.Append(newOwnedBy); } if (sbSql.Length > 0) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("ALTER SEQUENCE " + PgDiffUtils.GetQuotedName(newSequence.Name)); writer.Write(sbSql.ToString()); writer.WriteLine(';'); } if (oldSequence.Comment == null && newSequence.Comment != null || oldSequence.Comment != null && newSequence.Comment != null && !oldSequence.Comment.Equals( newSequence.Comment)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON SEQUENCE "); writer.Write(PgDiffUtils.GetQuotedName(newSequence.Name)); writer.Write(" IS "); writer.Write(newSequence.Comment); writer.WriteLine(';'); } else if (oldSequence.Comment != null && newSequence.Comment == null) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON SEQUENCE "); writer.Write(newSequence.Name); writer.WriteLine(" IS NULL;"); } } }
private static void DiffDatabaseSchemas(TextWriter writer, PgDiffArguments arguments, PgDatabase oldDatabase, PgDatabase newDatabase) { if (arguments.AddTransaction) { writer.WriteLine("START TRANSACTION;"); } if (oldDatabase.Comment == null && newDatabase.Comment != null || oldDatabase.Comment != null && newDatabase.Comment != null && !oldDatabase.Comment.Equals(newDatabase.Comment)) { writer.WriteLine(); writer.Write("COMMENT ON DATABASE current_database() IS "); writer.Write(newDatabase.Comment); writer.WriteLine(';'); } else if (oldDatabase.Comment != null && newDatabase.Comment == null) { writer.WriteLine(); writer.WriteLine("COMMENT ON DATABASE current_database() IS NULL;"); } DropOldSchemas(writer, oldDatabase, newDatabase); CreateNewSchemas(writer, oldDatabase, newDatabase); UpdateSchemas(writer, arguments, oldDatabase, newDatabase); if (arguments.AddTransaction) { writer.WriteLine(); writer.WriteLine("COMMIT TRANSACTION;"); } if (arguments.OutputIgnoredStatements) { if (oldDatabase.IgnoredStatements.Count > 0) { writer.WriteLine(); writer.Write("/* "); writer.WriteLine(Resources.OriginalDatabaseIgnoredStatements); foreach (var statement in oldDatabase.IgnoredStatements) { writer.WriteLine(); writer.WriteLine(statement); } writer.WriteLine("*/"); } if (newDatabase.IgnoredStatements.Count > 0) { writer.WriteLine(); writer.Write("/* "); writer.WriteLine(Resources.NewDatabaseIgnoredStatements); foreach (var statement in newDatabase.IgnoredStatements) { writer.WriteLine(); writer.WriteLine(statement); } writer.WriteLine("*/"); } } }
private static void UpdateSchemas(TextWriter writer, PgDiffArguments arguments, PgDatabase oldDatabase, PgDatabase newDatabase) { var setSearchPath = newDatabase.Schemas.Count > 1 || !newDatabase.Schemas[0].Name.Equals("public"); foreach (var newSchema in newDatabase.Schemas) { var searchPathHelper = setSearchPath ? new SearchPathHelper($"SET search_path = {PgDiffUtils.GetQuotedName(newSchema.Name, true)}, pg_catalog;") : new SearchPathHelper(null); var oldSchema = oldDatabase.GetSchema(newSchema.Name); if (oldSchema != null) { if (oldSchema.Comment == null && newSchema.Comment != null || oldSchema.Comment != null && newSchema.Comment != null && !oldSchema.Comment.Equals( newSchema.Comment)) { writer.WriteLine(); writer.Write("COMMENT ON SCHEMA "); writer.Write(PgDiffUtils.GetQuotedName(newSchema.Name)); writer.Write(" IS "); writer.Write(newSchema.Comment); writer.WriteLine(';'); } else if (oldSchema.Comment != null && newSchema.Comment == null) { writer.WriteLine(); writer.Write("COMMENT ON SCHEMA "); writer.Write(PgDiffUtils.GetQuotedName(newSchema.Name)); writer.WriteLine(" IS NULL;"); } } PgDiffTriggers.DropTriggers(writer, oldSchema, newSchema, searchPathHelper); PgDiffFunctions.DropFunctions(writer, arguments, oldSchema, newSchema, searchPathHelper); PgDiffViews.DropViews(writer, oldSchema, newSchema, searchPathHelper); PgDiffConstraints.DropConstraints(writer, oldSchema, newSchema, true, searchPathHelper); PgDiffConstraints.DropConstraints(writer, oldSchema, newSchema, false, searchPathHelper); PgDiffIndexes.DropIndexes(writer, oldSchema, newSchema, searchPathHelper); PgDiffTables.DropClusters(writer, oldSchema, newSchema, searchPathHelper); PgDiffTables.DropTables(writer, oldSchema, newSchema, searchPathHelper); PgDiffSequences.DropSequences(writer, oldSchema, newSchema, searchPathHelper); PgDiffSequences.CreateSequences(writer, oldSchema, newSchema, searchPathHelper); PgDiffSequences.AlterSequences(writer, arguments, oldSchema, newSchema, searchPathHelper); PgDiffTables.CreateTables(writer, oldSchema, newSchema, searchPathHelper); PgDiffTables.AlterTables(writer, arguments, oldSchema, newSchema, searchPathHelper); PgDiffSequences.AlterCreatedSequences(writer, oldSchema, newSchema, searchPathHelper); PgDiffFunctions.CreateFunctions(writer, arguments, oldSchema, newSchema, searchPathHelper); PgDiffConstraints.CreateConstraints(writer, oldSchema, newSchema, true, searchPathHelper); PgDiffConstraints.CreateConstraints(writer, oldSchema, newSchema, false, searchPathHelper); PgDiffIndexes.CreateIndexes(writer, oldSchema, newSchema, searchPathHelper); PgDiffTables.CreateClusters(writer, oldSchema, newSchema, searchPathHelper); PgDiffTriggers.CreateTriggers(writer, oldSchema, newSchema, searchPathHelper); PgDiffViews.CreateViews(writer, oldSchema, newSchema, searchPathHelper); PgDiffViews.AlterViews(writer, oldSchema, newSchema, searchPathHelper); PgDiffFunctions.AlterComments(writer, oldSchema, newSchema, searchPathHelper); PgDiffConstraints.AlterComments(writer, oldSchema, newSchema, searchPathHelper); PgDiffIndexes.AlterComments(writer, oldSchema, newSchema, searchPathHelper); PgDiffTriggers.AlterComments(writer, oldSchema, newSchema, searchPathHelper); } }