예제 #1
0
        public static void CreateIndexes(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.GetTables())
            {
                var newTableName = newTable.Name;

                // Add new indexes
                if (oldSchema == null)
                {
                    foreach (var index in newTable.GetIndexes())
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.WriteLine(index.GetCreationSql());
                    }
                }
                else
                {
                    foreach (var index in GetNewIndexes(
                                 oldSchema.GetTable(newTableName), newTable))
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.WriteLine(index.GetCreationSql());
                    }
                }
            }
        }
 /// <summary>
 /// Outputs statements for creation of new indexes.
 /// </summary>
 public static void Create(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
 {
     foreach (PgTable newTable in newSchema.Tables)
     {
         // Add new indexes
         if (oldSchema == null)
         {
             foreach (PgIndex index in newTable.Indexes)
             {
                 searchPathHelper.OutputSearchPath(writer);
                 writer.WriteLine();
                 writer.WriteLine(index.CreationSQL);
             }
         }
         else
         {
             foreach (PgIndex index in GetNewIndexes(oldSchema.GetTable(newTable.Name), newTable))
             {
                 searchPathHelper.OutputSearchPath(writer);
                 writer.WriteLine();
                 writer.WriteLine(index.CreationSQL);
             }
         }
     }
 }
예제 #3
0
        public static void AlterComments(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            if (oldSchema == null)
            {
                return;
            }

            foreach (var oldTable in oldSchema.GetTables())
            {
                var newTable = newSchema.GetTable(oldTable.Name);

                if (newTable == null)
                {
                    continue;
                }

                foreach (var oldTrigger in oldTable.GetTriggers())
                {
                    var newTrigger =
                        newTable.GetTrigger(oldTrigger.Name);

                    if (newTrigger == null)
                    {
                        continue;
                    }

                    if (oldTrigger.Comment == null &&
                        newTrigger.Comment != null ||
                        oldTrigger.Comment != null &&
                        newTrigger.Comment != null &&
                        !oldTrigger.Comment.Equals(
                            newTrigger.Comment))
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.Write("COMMENT ON TRIGGER ");
                        writer.Write(PgDiffUtils.GetQuotedName(newTrigger.Name));
                        writer.Write(" ON ");
                        writer.Write(PgDiffUtils.GetQuotedName(newTrigger.TableName));
                        writer.Write(" IS ");
                        writer.Write(newTrigger.Comment);
                        writer.WriteLine(';');
                    }
                    else if (oldTrigger.Comment != null && newTrigger.Comment == null)
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.Write("COMMENT ON TRIGGER ");
                        writer.Write(PgDiffUtils.GetQuotedName(newTrigger.Name));
                        writer.Write(" ON ");
                        writer.Write(PgDiffUtils.GetQuotedName(newTrigger.TableName));
                        writer.WriteLine(" IS NULL;");
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Outputs statements for trigger comments that have changed.
        /// </summary>
        public static void AlterComments(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            if (oldSchema == null)
            {
                return;
            }

            foreach (PgTable oldTable in oldSchema.Tables)
            {
                PgTable newTable = newSchema.GetTable(oldTable.Name);

                if (newTable == null)
                {
                    continue;
                }

                foreach (PgTrigger oldTrigger in oldTable.Triggers)
                {
                    PgTrigger newTrigger = newTable.GetTrigger(oldTrigger.Name);

                    if (newTrigger == null)
                    {
                        continue;
                    }

                    if ((oldTrigger.Comment == null && newTrigger.Comment != null) ||
                        (oldTrigger.Comment != null &&
                         newTrigger.Comment != null &&
                         !oldTrigger.Comment.Equals(newTrigger.Comment)))
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.Write("COMMENT ON TRIGGER ");
                        writer.Write(PgDiffStringExtension.QuoteName(newTrigger.Name));
                        writer.Write(" ON ");
                        writer.Write(PgDiffStringExtension.QuoteName(newTrigger.TableName));
                        writer.Write(" IS ");
                        writer.Write(newTrigger.Comment);
                        writer.WriteLine(';');
                    }
                    else if (oldTrigger.Comment != null && newTrigger.Comment == null)
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.Write("COMMENT ON TRIGGER ");
                        writer.Write(PgDiffStringExtension.QuoteName(newTrigger.Name));
                        writer.Write(" ON ");
                        writer.Write(PgDiffStringExtension.QuoteName(newTrigger.TableName));
                        writer.WriteLine(" IS NULL;");
                    }
                }
            }
        }
        /// <summary>
        /// Parses COMMENT ON COLUMN.
        /// </summary>
        private static void ParseColumn(Parser parser, PgDatabase database)
        {
            var columnName = parser.ParseIdentifier();

            var objectName = ParserUtils.GetObjectName(columnName);

            var tableName = ParserUtils.GetSecondObjectName(columnName);

            var schemaName = ParserUtils.GetThirdObjectName(columnName);

            if (database.SchemaIsIgnored(schemaName))
            {
                return;
            }

            PgSchema schema = database.GetSchema(schemaName);

            PgTable table = schema.GetTable(tableName);

            if (table == null)
            {
                PgView view = schema.GetView(tableName);
                parser.Expect("IS");

                var comment = GetComment(parser);

                if (comment == null)
                {
                    view.RemoveColumnComment(objectName);
                }
                else
                {
                    view.AddColumnComment(objectName, comment);
                }

                parser.Expect(";");
            }
            else
            {
                PgColumn column = table.GetColumn(objectName);

                if (column == null)
                {
                    throw new TeamworkParserException($"CannotFindColumnInTable {columnName} from table {table.Name}");
                }

                parser.Expect("IS");
                column.Comment = GetComment(parser);
                parser.Expect(";");
            }
        }
예제 #6
0
        /// <summary>
        /// Parses CREATE INDEX statement.
        /// </summary>
        public static void Parse(PgDatabase database, string statement)
        {
            var parser = new Parser(statement);

            parser.Expect("CREATE");

            var unique = parser.ExpectOptional("UNIQUE");

            parser.Expect("INDEX");
            parser.ExpectOptional("CONCURRENTLY");

            var indexName = ParserUtils.GetObjectName(parser.ParseIdentifier());

            parser.Expect("ON");

            var tableName = parser.ParseIdentifier();

            var definition = parser.Rest();

            var schemaName = ParserUtils.GetSchemaName(tableName, database);

            if (database.SchemaIsIgnored(schemaName))
            {
                return;
            }

            PgSchema schema = database.GetSchema(schemaName);

            if (schema == null)
            {
                throw new TeamworkParserException($"CannotFindSchema {schemaName} from  {statement}");
            }

            var objectName = ParserUtils.GetObjectName(tableName);

            PgTable table = schema.GetTable(objectName);

            if (table == null)
            {
                throw new TeamworkParserException($"CannotFindTable {tableName} from {statement}");
            }

            var index = new PgIndex(indexName);

            table.AddIndex(index);
            schema.Add(index);
            index.Definition = definition.Trim();
            index.TableName  = table.Name;
            index.Unique     = unique;
        }
예제 #7
0
        public static void CreateTriggers(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.GetTables())
            {
                var oldTable = oldSchema?.GetTable(newTable.Name);

                // Add new triggers
                foreach (var trigger in GetNewTriggers(oldTable, newTable))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(trigger.GetCreationSql());
                }
            }
        }
예제 #8
0
        public static void DropTriggers(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.GetTables())
            {
                var oldTable = oldSchema?.GetTable(newTable.Name);

                // Drop triggers that no more exist or are modified
                foreach (var trigger in GetDropTriggers(oldTable, newTable))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(trigger.GetDropSql());
                }
            }
        }
예제 #9
0
        public static void CreateConstraints(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, bool primaryKey, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.GetTables())
            {
                var oldTable = oldSchema?.GetTable(newTable.Name);

                // Add new constraints
                foreach (var constraint in GetNewConstraints(oldTable, newTable, primaryKey))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(constraint.GetCreationSql());
                }
            }
        }
예제 #10
0
        public static void DropConstraints(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, bool primaryKey, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.GetTables())
            {
                var oldTable = oldSchema?.GetTable(newTable.Name);

                // Drop constraints that no more exist or are modified
                foreach (var constraint in GetDropConstraints(oldTable, newTable, primaryKey))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(constraint.GetDropSql());
                }
            }
        }
예제 #11
0
        public static void DropIndexes(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.GetTables())
            {
                var newTableName = newTable.Name;
                var oldTable     = oldSchema?.GetTable(newTableName);

                // Drop indexes that do not exist in new schema or are modified
                foreach (var index in GetDropIndexes(oldTable, newTable))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(index.GetDropSql());
                }
            }
        }
        /// <summary>
        /// Outputs statements for dropping indexes that exist no more.
        /// </summary>
        public static void Drop(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (PgTable newTable in newSchema.Tables)
            {
                PgTable oldTable = null;
                if (oldSchema != null)
                {
                    oldTable = oldSchema.GetTable(newTable.Name);
                }

                // Drop indexes that do not exist in new schema or are modified
                foreach (PgIndex index in GetDropIndexes(oldTable, newTable))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(index.DropSQL);
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Outputs statements for altering tables.
        /// </summary>
        public static void Alter(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (PgTable newTable in newSchema.Tables)
            {
                if (oldSchema == null || !oldSchema.ContainsTable(newTable.Name))
                {
                    continue;
                }

                PgTable oldTable = oldSchema.GetTable(newTable.Name);
                UpdateTableColumns(writer, 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);
            }
        }
        /// <summary>
        /// Outputs statements for dropping non-existent or modified constraints.
        /// </summary>
        /// <param name="writer">Writer the output should be written to.</param>
        /// <param name="primaryKey">Determines whether primary keys should be processed or any other constraints should be processed.</param>
        /// <param name="searchPathHelper">Search path helper.</param>
        /// <param name="newSchema">The schema of the new database.</param>
        /// <param name="oldSchema">The schema of the old database.</param>
        public static void Drop(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, bool primaryKey, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.Tables)
            {
                PgTable oldTable = null;
                if (oldSchema != null)
                {
                    oldTable = oldSchema.GetTable(newTable.Name);
                }

                // Drop constraints that no more exist or are modified
                foreach (var constraint in GetDropConstraints(oldTable, newTable, primaryKey))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(constraint.DropSQL);
                }
            }
        }
예제 #15
0
        public static void DropClusters(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.GetTables())
            {
                var oldTable = oldSchema?.GetTable(newTable.Name);

                var oldCluster = oldTable?.ClusterIndexName;

                var newCluster = newTable.ClusterIndexName;

                if (oldCluster != null && newCluster == null && newTable.ContainsIndex(oldCluster))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.Write("ALTER TABLE ");
                    writer.Write(PgDiffUtils.GetQuotedName(newTable.Name));
                    writer.WriteLine(" SET WITHOUT CLUSTER;");
                }
            }
        }
예제 #16
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);
            }
        }
예제 #17
0
        /// <summary>
        /// Outputs statements for dropping of clusters.
        /// </summary>
        public static void CreateClusters(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (PgTable newTable in newSchema.Tables)
            {
                PgTable oldTable;

                if (oldSchema == null)
                {
                    oldTable = null;
                }
                else
                {
                    oldTable = oldSchema.GetTable(newTable.Name);
                }

                string oldCluster;

                if (oldTable == null)
                {
                    oldCluster = null;
                }
                else
                {
                    oldCluster = oldTable.ClusterIndexName;
                }

                var newCluster = newTable.ClusterIndexName;

                if ((oldCluster == null && newCluster != null) || (oldCluster != null && newCluster != null && newCluster.CompareTo(oldCluster) != 0))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.Write("ALTER TABLE ");
                    writer.Write(PgDiffStringExtension.QuoteName(newTable.Name));
                    writer.Write(" CLUSTER ON ");
                    writer.Write(PgDiffStringExtension.QuoteName(newCluster));
                    writer.WriteLine(';');
                }
            }
        }
        /// <summary>
        /// Outputs statements for creation of new constraints.
        /// </summary>
        /// <param name="writer">Writer the output should be written to.</param>
        /// <param name="oldSchema">Original schema.</param>
        /// <param name="newSchema">New schema.</param>
        /// <param name="primaryKey">Determines whether primary keys should be processed or any other constraints should be processed.</param>
        /// <param name="searchPathHelper">Search path helper.</param>
        /// <param name="foreignKey">Determines wheter forein keys should be processed.</param>
        public static void Create(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, bool primaryKey, bool foreignKey, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.Tables)
            {
                PgTable oldTable = null;
                if (oldSchema != null)
                {
                    oldTable = oldSchema.GetTable(newTable.Name);
                }

                var oldConstraints = new List <PgConstraint>();
                if (oldTable != null)
                {
                    oldConstraints.AddRange(oldTable.Constraints);
                }

                // Add new constraints
                foreach (var newConstraint in GetNewConstraints(oldTable, newTable, primaryKey, foreignKey))
                {
                    if (oldTable != null)
                    {
                        var oldConstraint = oldConstraints.FirstOrDefault(c => c.IsRenamed(newConstraint));
                        if (oldConstraint != null)
                        {
                            // constraint was renamed
                            searchPathHelper.OutputSearchPath(writer);
                            writer.WriteLine();
                            writer.WriteLine(oldConstraint.RenameToSql(newConstraint.Name));
                            oldConstraints.Remove(oldConstraint);
                            continue;
                        }
                    }

                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(newConstraint.CreationSQL);
                }
            }
        }
예제 #19
0
        public static void CreateClusters(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (var newTable in newSchema.GetTables())
            {
                var oldTable   = oldSchema?.GetTable(newTable.Name);
                var oldCluster = oldTable?.ClusterIndexName;

                var newCluster = newTable.ClusterIndexName;

                if (oldCluster == null && newCluster != null ||
                    oldCluster != null && newCluster != null &&
                    newCluster.CompareTo(oldCluster) != 0)
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.Write("ALTER TABLE ");
                    writer.Write(PgDiffUtils.GetQuotedName(newTable.Name));
                    writer.Write(" CLUSTER ON ");
                    writer.Write(PgDiffUtils.GetQuotedName(newCluster));
                    writer.WriteLine(';');
                }
            }
        }
예제 #20
0
        /// <summary>
        /// Outputs statements for creation of new triggers.
        /// </summary>
        public static void Create(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (PgTable newTable in newSchema.Tables)
            {
                PgTable oldTable;

                if (oldSchema == null)
                {
                    oldTable = null;
                }
                else
                {
                    oldTable = oldSchema.GetTable(newTable.Name);
                }

                // Add new triggers
                foreach (PgTrigger trigger in GetNewTriggers(oldTable, newTable))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(trigger.CreationSQL);
                }
            }
        }
예제 #21
0
        /// <summary>
        /// Outputs statements for dropping triggers.
        /// </summary>
        public static void Drop(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            foreach (PgTable newTable in newSchema.Tables)
            {
                PgTable oldTable;

                if (oldSchema == null)
                {
                    oldTable = null;
                }
                else
                {
                    oldTable = oldSchema.GetTable(newTable.Name);
                }

                // Drop triggers that no more exist or are modified
                foreach (PgTrigger trigger in GetDropTriggers(oldTable, newTable))
                {
                    searchPathHelper.OutputSearchPath(writer);
                    writer.WriteLine();
                    writer.WriteLine(trigger.DropSQL);
                }
            }
        }
        /// <summary>
        /// Parses CREATE TRIGGER statement.
        /// </summary>
        public static void Parse(PgDatabase database, string statement, bool ignoreSlonyTriggers)
        {
            var parser = new Parser(statement);

            parser.Expect("CREATE", "TRIGGER");

            var triggerName = parser.ParseIdentifier();

            var objectName = ParserUtils.GetObjectName(triggerName);

            var trigger = new PgTrigger()
            {
                Name = objectName,
            };

            if (parser.ExpectOptional("BEFORE"))
            {
                trigger.Before = true;
            }
            else if (parser.ExpectOptional("AFTER"))
            {
                trigger.Before = false;
            }

            var first = true;

            while (true)
            {
                if (!first && !parser.ExpectOptional("OR"))
                {
                    break;
                }
                else if (parser.ExpectOptional("INSERT"))
                {
                    trigger.OnInsert = true;
                }
                else if (parser.ExpectOptional("UPDATE"))
                {
                    trigger.OnUpdate = true;

                    if (parser.ExpectOptional("OF"))
                    {
                        do
                        {
                            trigger.AddUpdateColumn(parser.ParseIdentifier());
                        }while (parser.ExpectOptional(","));
                    }
                }
                else if (parser.ExpectOptional("DELETE"))
                {
                    trigger.OnDelete = true;
                }
                else if (parser.ExpectOptional("TRUNCATE"))
                {
                    trigger.OnTruncate = true;
                }
                else if (first)
                {
                    break;
                }
                else
                {
                    throw new TeamworkParserException("CannotParseStringUnsupportedCommand");
                }

                first = false;
            }

            parser.Expect("ON");

            var tableName = parser.ParseIdentifier();

            trigger.TableName = ParserUtils.GetObjectName(tableName);

            if (parser.ExpectOptional("FOR"))
            {
                parser.ExpectOptional("EACH");

                if (parser.ExpectOptional("ROW"))
                {
                    trigger.ForEachRow = true;
                }
                else if (parser.ExpectOptional("STATEMENT"))
                {
                    trigger.ForEachRow = false;
                }
                else
                {
                    throw new TeamworkParserException("CannotParseStringUnsupportedCommand");
                }
            }

            if (parser.ExpectOptional("WHEN"))
            {
                parser.Expect("(");
                trigger.When = parser.Expression();
                parser.Expect(")");
            }

            parser.Expect("EXECUTE", "PROCEDURE");
            trigger.Function = parser.Rest();

            var ignoreSlonyTrigger = ignoreSlonyTriggers && ("_slony_logtrigger".Equals(trigger.Name) || "_slony_denyaccess".Equals(trigger.Name));

            if (!ignoreSlonyTrigger)
            {
                PgSchema tableSchema = database.GetSchema(ParserUtils.GetSchemaName(tableName, database));
                tableSchema.GetTable(trigger.TableName).AddTrigger(trigger);
            }
        }
예제 #23
0
        /// <summary>
        /// Parses ALTER TABLE statement.
        /// </summary>
        public static void Parse(PgDatabase database, string statement, bool outputIgnoredStatements)
        {
            var parser = new Parser(statement);

            parser.Expect("ALTER", "TABLE");
            parser.ExpectOptional("ONLY");

            var tableName = parser.ParseIdentifier();

            var schemaName = ParserUtils.GetSchemaName(tableName, database);

            if (database.SchemaIsIgnored(schemaName))
            {
                return;
            }

            PgSchema schema = database.GetSchema(schemaName);

            if (schema == null)
            {
                throw new TeamworkParserException($"CannotFindSchema {schemaName} from {statement}");
            }

            var objectName = ParserUtils.GetObjectName(tableName);

            PgTable table = schema.GetTable(objectName);

            if (table == null)
            {
                PgView view = schema.GetView(objectName);

                if (view != null)
                {
                    ParseView(parser, view, outputIgnoredStatements, tableName, database);
                    return;
                }

                PgSequence sequence = schema.GetSequence(objectName);

                if (sequence != null)
                {
                    ParseSequence(parser, sequence, outputIgnoredStatements, tableName, database);
                    return;
                }

                throw new TeamworkParserException($"CannotFindObject in {tableName} from {statement}");
            }

            while (!parser.ExpectOptional(";"))
            {
                if (parser.ExpectOptional("ALTER"))
                {
                    ParseAlterColumn(parser, table);
                }
                else if (parser.ExpectOptional("CLUSTER", "ON"))
                {
                    table.ClusterIndexName = ParserUtils.GetObjectName(parser.ParseIdentifier());
                }
                else if (parser.ExpectOptional("OWNER", "TO"))
                {
                    // we do not parse this one so we just consume the identifier
                    if (outputIgnoredStatements)
                    {
                        database.AddIgnoredStatement("ALTER TABLE " + tableName + " OWNER TO " + parser.ParseIdentifier() + ';');
                    }
                    else
                    {
                        parser.ParseIdentifier();
                    }
                }
                else if (parser.ExpectOptional("ADD"))
                {
                    if (parser.ExpectOptional("FOREIGN", "KEY"))
                    {
                        ParseAddForeignKey(parser, table);
                    }
                    else if (parser.ExpectOptional("CONSTRAINT"))
                    {
                        ParseAddConstraint(parser, table, schema);
                    }
                    else
                    {
                        throw new TeamworkParserException("CannotParseStringUnsupportedCommand");
                    }
                }
                else if (parser.ExpectOptional("ENABLE"))
                {
                    ParseEnable(parser, outputIgnoredStatements, tableName, database);
                }
                else if (parser.ExpectOptional("DISABLE"))
                {
                    ParseDisable(parser, outputIgnoredStatements, tableName, database);
                }
                else if (parser.ExpectOptional("REPLICA IDENTITY"))
                {
                    parser.Expect("NOTHING");
                }
                else
                {
                    throw new TeamworkParserException("CannotParseStringUnsupportedCommand");
                }

                if (parser.ExpectOptional(";"))
                {
                    break;
                }
                else
                {
                    parser.Expect(",");
                }
            }
        }
        /// <summary>
        /// Outputs statements for constraint comments that have changed.
        /// </summary>
        public static void AlterComments(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            if (oldSchema == null)
            {
                return;
            }

            foreach (PgTable oldTable in oldSchema.Tables)
            {
                PgTable newTable = newSchema.GetTable(oldTable.Name);

                if (newTable == null)
                {
                    continue;
                }

                foreach (PgConstraint oldConstraint in oldTable.Constraints)
                {
                    PgConstraint newConstraint = newTable.GetConstraint(oldConstraint.Name);

                    if (newConstraint == null)
                    {
                        continue;
                    }

                    if ((oldConstraint.Comment == null && newConstraint.Comment != null) ||
                        (oldConstraint.Comment != null && newConstraint.Comment != null && !oldConstraint.Comment.Equals(newConstraint.Comment)))
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.Write("COMMENT ON ");

                        if (newConstraint.PrimaryKeyConstraint)
                        {
                            writer.Write("INDEX ");
                            writer.Write(PgDiffStringExtension.QuoteName(newConstraint.Name));
                        }
                        else
                        {
                            writer.Write("CONSTRAINT ");
                            writer.Write(PgDiffStringExtension.QuoteName(newConstraint.Name));
                            writer.Write(" ON ");
                            writer.Write(PgDiffStringExtension.QuoteName(newConstraint.TableName));
                        }

                        writer.Write(" IS ");
                        writer.Write(newConstraint.Comment);
                        writer.WriteLine(';');
                    }
                    else if (oldConstraint.Comment != null && newConstraint.Comment == null)
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.Write("COMMENT ON ");

                        if (newConstraint.PrimaryKeyConstraint)
                        {
                            writer.Write("INDEX ");
                            writer.Write(PgDiffStringExtension.QuoteName(newConstraint.Name));
                        }
                        else
                        {
                            writer.Write("CONSTRAINT ");
                            writer.Write(PgDiffStringExtension.QuoteName(newConstraint.Name));
                            writer.Write(" ON ");
                            writer.Write(PgDiffStringExtension.QuoteName(newConstraint.TableName));
                        }

                        writer.WriteLine(" IS NULL;");
                    }
                }
            }
        }
예제 #25
0
        public static void AlterComments(TextWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper)
        {
            if (oldSchema == null)
            {
                return;
            }

            foreach (var oldTable in oldSchema.GetTables())
            {
                var newTable = newSchema.GetTable(oldTable.Name);

                if (newTable == null)
                {
                    continue;
                }

                foreach (var oldConstraint in oldTable.Constraints)
                {
                    var newConstraint =
                        newTable.GetConstraint(oldConstraint.Name);

                    if (newConstraint == null)
                    {
                        continue;
                    }

                    if (oldConstraint.Comment == null &&
                        newConstraint.Comment != null ||
                        oldConstraint.Comment != null &&
                        newConstraint.Comment != null &&
                        !oldConstraint.Comment.Equals(
                            newConstraint.Comment))
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.Write("COMMENT ON ");

                        if (newConstraint.IsPrimaryKeyConstraint())
                        {
                            writer.Write("INDEX ");
                            writer.Write(PgDiffUtils.GetQuotedName(newConstraint.Name));
                        }
                        else
                        {
                            writer.Write("CONSTRAINT ");
                            writer.Write(PgDiffUtils.GetQuotedName(newConstraint.Name));
                            writer.Write(" ON ");
                            writer.Write(PgDiffUtils.GetQuotedName(newConstraint.TableName));
                        }

                        writer.Write(" IS ");
                        writer.Write(newConstraint.Comment);
                        writer.WriteLine(';');
                    }
                    else if (oldConstraint.Comment != null && newConstraint.Comment == null)
                    {
                        searchPathHelper.OutputSearchPath(writer);
                        writer.WriteLine();
                        writer.Write("COMMENT ON ");

                        if (newConstraint.IsPrimaryKeyConstraint())
                        {
                            writer.Write("INDEX ");
                            writer.Write(PgDiffUtils.GetQuotedName(newConstraint.Name));
                        }
                        else
                        {
                            writer.Write("CONSTRAINT ");
                            writer.Write(PgDiffUtils.GetQuotedName(newConstraint.Name));
                            writer.Write(" ON ");
                            writer.Write(PgDiffUtils.GetQuotedName(newConstraint.TableName));
                        }

                        writer.WriteLine(" IS NULL;");
                    }
                }
            }
        }