예제 #1
0
파일: Main.cs 프로젝트: hryz/apgdiff.net
        public static void Main(string[] args)
        {
            var arguments = new PgDiffArguments();

            if (arguments.Parse(Console.In, Console.Out, args))
            {
                PgDiff.CreateDiff(Console.Out, arguments);
            }
        }
예제 #2
0
        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");
                }
            }
        }
예제 #3
0
        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());
                }
            }
        }
예제 #4
0
파일: PgDiff.cs 프로젝트: hryz/apgdiff.net
        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);
        }
예제 #5
0
파일: PgDiff.cs 프로젝트: hryz/apgdiff.net
        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);
        }
예제 #6
0
        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);
                    }
                }
            }
        }
예제 #7
0
        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());
                }
            }
        }
예제 #8
0
        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 ? "," : ";");
                    }
                }
            }
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
        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;");
                }
            }
        }
예제 #11
0
파일: PgDiff.cs 프로젝트: hryz/apgdiff.net
        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("*/");
                }
            }
        }
예제 #12
0
파일: PgDiff.cs 프로젝트: hryz/apgdiff.net
        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);
            }
        }