/// <summary> /// Generate the needed alter table xxx set storage when needed. /// </summary> private static void AddAlterStorage(StreamWriter writer, PgTable oldTable, PgTable newTable, SearchPathHelper searchPathHelper) { foreach (PgColumn newColumn in newTable.Columns) { PgColumn oldColumn = oldTable.GetColumn(newColumn.Name); var oldStorage = (oldColumn == null || oldColumn.Storage == null || oldColumn.Storage == string.Empty) ? null : oldColumn.Storage; var newStorage = (newColumn.Storage == null || newColumn.Storage == string.Empty) ? null : newColumn.Storage; if (newStorage == null && oldStorage != null) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine($"WarningUnableToDetermineStorageType {newTable.Name + '.' + newColumn.Name}"); continue; } if (newStorage == null || newStorage.Equals(oldStorage, StringComparison.CurrentCultureIgnoreCase)) { continue; } searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("ALTER TABLE ONLY "); writer.Write(PgDiffStringExtension.QuoteName(newTable.Name)); writer.Write(" ALTER COLUMN "); writer.Write(PgDiffStringExtension.QuoteName(newColumn.Name)); writer.Write(" SET STORAGE "); writer.Write(newStorage); writer.Write(';'); } }
/// <summary> /// Outputs statements for altering of new sequences. /// </summary> /// <param name="writer">Writer the output should be written to.</param> /// <param name="oldSchema">The old schema.</param> /// <param name="newSchema">The new schema.</param> /// <param name="searchPathHelper">The search path helper.</param> public static void AlterCreatedSequences(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { // Alter created sequences foreach (PgSequence sequence in newSchema.Sequences) { if ((oldSchema == null || !oldSchema.ContainsSequence(sequence.Name)) && sequence.Owner != null && sequence.Owner != string.Empty) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(sequence.OwnedBySQL); } } }
/// <summary> /// Outputs statement for modified sequences. /// </summary> public static void Alter(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper, bool ignoreStartWith) { if (oldSchema == null) { return; } var alterSequenceSql = new StringBuilder(100); foreach (PgSequence newSequence in newSchema.Sequences) { PgSequence oldSequence = oldSchema.GetSequence(newSequence.Name); if (oldSequence == null) { continue; } alterSequenceSql.Length = 0; var oldIncrement = oldSequence.Increment; var newIncrement = newSequence.Increment; if (newIncrement != null && !newIncrement.Equals(oldIncrement)) { alterSequenceSql.Append("\n\tINCREMENT BY "); alterSequenceSql.Append(newIncrement); } var oldMinValue = oldSequence.MinValue; var newMinValue = newSequence.MinValue; if (newMinValue == null && oldMinValue != null) { alterSequenceSql.Append("\n\tNO MINVALUE"); } else if (newMinValue != null && !newMinValue.Equals(oldMinValue)) { alterSequenceSql.Append("\n\tMINVALUE "); alterSequenceSql.Append(newMinValue); } var oldMaxValue = oldSequence.MaxValue; var newMaxValue = newSequence.MaxValue; if (newMaxValue == null && oldMaxValue != null) { alterSequenceSql.Append("\n\tNO MAXVALUE"); } else if (newMaxValue != null && !newMaxValue.Equals(oldMaxValue)) { alterSequenceSql.Append("\n\tMAXVALUE "); alterSequenceSql.Append(newMaxValue); } if (!ignoreStartWith) { var oldStart = oldSequence.StartWith; var newStart = newSequence.StartWith; if (newStart != null && !newStart.Equals(oldStart)) { alterSequenceSql.Append("\n\tRESTART WITH "); alterSequenceSql.Append(newStart); } } var oldCache = oldSequence.Cache; var newCache = newSequence.Cache; if (newCache != null && !newCache.Equals(oldCache)) { alterSequenceSql.Append("\n\tCACHE "); alterSequenceSql.Append(newCache); } var oldCycle = oldSequence.Cycle; var newCycle = newSequence.Cycle; if (oldCycle && !newCycle) { alterSequenceSql.Append("\n\tNO CYCLE"); } else if (!oldCycle && newCycle) { alterSequenceSql.Append("\n\tCYCLE"); } var oldOwnedBy = oldSequence.Owner; var newOwnedBy = newSequence.Owner; if (newOwnedBy != null && !newOwnedBy.Equals(oldOwnedBy)) { alterSequenceSql.Append("\n\tOWNED BY "); alterSequenceSql.Append(newOwnedBy); } if (alterSequenceSql.Length > 0) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("ALTER SEQUENCE " + PgDiffStringExtension.QuoteName(newSequence.Name)); writer.Write(alterSequenceSql.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(PgDiffStringExtension.QuoteName(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;"); } } }
/// <summary> /// Outputs statements for new or modified functions. /// </summary> public static void Create(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper, bool ignoreFunctionWhitespace) { // Add new functions and replace modified functions foreach (PgFunction newFunction in newSchema.Functions) { PgFunction oldFunction; if (oldSchema == null) { oldFunction = null; } else { oldFunction = oldSchema.GetFunction(newFunction.Signature); } if ((oldFunction == null) || !newFunction.Equals(oldFunction, ignoreFunctionWhitespace)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(newFunction.CreationSQL); } } }
/// <summary> /// Outputs statements for function comments that have changed. /// </summary> public static void AlterComments(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { if (oldSchema == null) { return; } foreach (PgFunction oldfunction in oldSchema.Functions) { PgFunction newFunction = newSchema.GetFunction(oldfunction.Signature); if (newFunction == null) { continue; } if ((oldfunction.Comment == null && newFunction.Comment != null) || (oldfunction.Comment != null && newFunction.Comment != null && !oldfunction.Comment.Equals(newFunction.Comment))) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON FUNCTION "); writer.Write(PgDiffStringExtension.QuoteName(newFunction.Name)); writer.Write('('); var addComma = false; foreach (PgFunction.Argument argument in newFunction.Arguments) { if (addComma) { writer.Write(", "); } else { addComma = true; } writer.Write(argument.GetDeclaration(false)); } writer.Write(") IS "); writer.Write(newFunction.Comment); writer.WriteLine(';'); } else if (oldfunction.Comment != null && newFunction.Comment == null) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON FUNCTION "); writer.Write(PgDiffStringExtension.QuoteName(newFunction.Name)); writer.Write('('); var addComma = false; foreach (PgFunction.Argument argument in newFunction.Arguments) { if (addComma) { writer.Write(", "); } else { addComma = true; } writer.Write(argument.GetDeclaration(false)); } writer.WriteLine(") IS NULL;"); } } }
/// <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;"); } } } }
/// <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); } } }
/// <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 new or modified aggregates. /// </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="searchPathHelper">Search path helper.</param> public static void Create(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { // Add new aggregates and replace modified aggregates foreach (PgAggregate newAggregate in newSchema.Aggregates) { PgAggregate oldAggregate; if (oldSchema == null) { oldAggregate = null; } else { oldAggregate = oldSchema.GetAggregate(newAggregate.Signature); } if ((oldAggregate == null) || !newAggregate.Equals(oldAggregate)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(newAggregate.CreationSQL); } } }
/// <summary> /// Outputs statements for addition, removal and modifications of table /// columns. /// </summary> private static void UpdateTableColumns(StreamWriter writer, PgTable oldTable, PgTable newTable, SearchPathHelper searchPathHelper) { IList <string> statements = new List <string>(); IList <PgColumn> dropDefaultsColumns = new List <PgColumn>(); AddDropTableColumns(statements, oldTable, newTable); AddCreateTableColumns(statements, oldTable, newTable, dropDefaultsColumns, false); AddModifyTableColumns(statements, oldTable, newTable, dropDefaultsColumns, false); if (statements.Count > 0) { var quotedTableName = PgDiffStringExtension.QuoteName(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(PgDiffStringExtension.QuoteName(dropDefaultsColumns[i].Name)); writer.Write(" DROP DEFAULT"); writer.WriteLine((i + 1) < dropDefaultsColumns.Count ? "," : ";"); } } } }
/// <summary> /// Outputs statements for tables and columns for which comments have /// changed. /// </summary> private static void AlterComments(StreamWriter writer, PgTable oldTable, PgTable newTable, SearchPathHelper searchPathHelper) { if ((oldTable.Comment == null && newTable.Comment != null) || (oldTable.Comment != null && newTable.Comment != null && !oldTable.Comment.Equals(newTable.Comment))) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON TABLE "); writer.Write(PgDiffStringExtension.QuoteName(newTable.Name)); writer.Write(" IS "); writer.Write(newTable.Comment); writer.WriteLine(';'); } else if (oldTable.Comment != null && newTable.Comment == null) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON TABLE "); writer.Write(PgDiffStringExtension.QuoteName(newTable.Name)); writer.WriteLine(" IS NULL;"); } foreach (PgColumn newColumn in newTable.Columns) { PgColumn oldColumn = oldTable.GetColumn(newColumn.Name); var oldComment = oldColumn?.Comment; var newComment = newColumn.Comment; if (newComment != null && (oldComment == null ? newComment != null : !oldComment.Equals(newComment))) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON COLUMN "); writer.Write(PgDiffStringExtension.QuoteName(newTable.Name)); writer.Write('.'); writer.Write(PgDiffStringExtension.QuoteName(newColumn.Name)); writer.Write(" IS "); writer.Write(newColumn.Comment); writer.WriteLine(';'); } else if (oldComment != null && newComment == null) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON COLUMN "); writer.Write(PgDiffStringExtension.QuoteName(newTable.Name)); writer.Write('.'); writer.Write(PgDiffStringExtension.QuoteName(newColumn.Name)); writer.WriteLine(" IS NULL;"); } } }
/// <summary> /// Checks tablespace modification. /// </summary> private static void CheckTablespace(StreamWriter writer, PgTable oldTable, PgTable newTable, SearchPathHelper searchPathHelper) { if ((oldTable.Tablespace == null && newTable.Tablespace == null) || (oldTable.Tablespace != null && oldTable.Tablespace.Equals(newTable.Tablespace))) { return; } searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine("ALTER TABLE " + PgDiffStringExtension.QuoteName(newTable.Name)); writer.WriteLine("\tTABLESPACE " + newTable.Tablespace + ';'); }
/// <summary> /// Checks whether OIDS are dropped from the new table. There is no way to add OIDS to existing table so we do not /// create SQL statement for addition of OIDS but we issue warning. /// </summary> private static void CheckWithOIDS(StreamWriter writer, PgTable oldTable, PgTable newTable, SearchPathHelper searchPathHelper) { if ((oldTable.With == null && newTable.With == null) || (oldTable.With != null && oldTable.With.Equals(newTable.With))) { return; } searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine("ALTER TABLE " + PgDiffStringExtension.QuoteName(newTable.Name)); if (newTable.With == null || "OIDS=false".Equals(newTable.With, StringComparison.CurrentCultureIgnoreCase)) { writer.WriteLine("\tSET WITHOUT OIDS;"); } else if ("OIDS".Equals(newTable.With, StringComparison.CurrentCultureIgnoreCase) || "OIDS=true".Equals(newTable.With, StringComparison.CurrentCultureIgnoreCase)) { writer.WriteLine("\tSET WITH OIDS;"); } else { writer.WriteLine("\tSET " + newTable.With + ";"); } }
/// <summary> /// Checks whether there is a discrepancy in INHERITS for original and new /// table. /// </summary> private static void CheckInherits(StreamWriter writer, PgTable oldTable, PgTable newTable, SearchPathHelper searchPathHelper) { foreach (var tableName in oldTable.Inherits) { if (!newTable.Inherits.Contains(tableName)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine("ALTER TABLE " + PgDiffStringExtension.QuoteName(newTable.Name)); writer.WriteLine("\tNO INHERIT " + PgDiffStringExtension.QuoteName(tableName) + ';'); } } foreach (var tableName in newTable.Inherits) { if (!oldTable.Inherits.Contains(tableName)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine("ALTER TABLE " + PgDiffStringExtension.QuoteName(newTable.Name)); writer.WriteLine("\tINHERIT " + PgDiffStringExtension.QuoteName(tableName) + ';'); } } }
/// <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); } } }
/// <summary> /// Outputs statements for dropping of aggregates that exist no more. /// </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="searchPathHelper">Search path helper.</param> public static void Drop(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { if (oldSchema == null) { return; } // Drop aggregates that exist no more foreach (PgAggregate oldAggregate in oldSchema.Aggregates) { if (!newSchema.ContainsAggregate(oldAggregate.Signature)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(oldAggregate.DropSQL); } } }
/// <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); } } }
/// <summary> /// Outputs statements for aggregate comments that have changed. /// </summary> public static void AlterComments(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { if (oldSchema == null) { return; } foreach (PgAggregate oldAggregate in oldSchema.Aggregates) { PgAggregate newAggregate = newSchema.GetAggregate(oldAggregate.Signature); if (newAggregate == null) { continue; } if ((oldAggregate.Comment == null && newAggregate.Comment != null) || (oldAggregate.Comment != null && newAggregate.Comment != null && !oldAggregate.Comment.Equals(newAggregate.Comment))) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON AGGREGATE "); writer.Write(PgDiffStringExtension.QuoteName(newAggregate.Name)); writer.Write('('); var addComma = false; foreach (PgAggregate.Argument argument in newAggregate.Arguments) { if (addComma) { writer.Write(", "); } else { addComma = true; } writer.Write(argument.DataType); } writer.Write(") IS "); writer.Write(newAggregate.Comment); writer.WriteLine(';'); } else if (oldAggregate.Comment != null && newAggregate.Comment == null) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON AGGREGATE "); writer.Write(PgDiffStringExtension.QuoteName(newAggregate.Name)); writer.Write('('); var addComma = false; foreach (PgAggregate.Argument argument in newAggregate.Arguments) { if (addComma) { writer.Write(", "); } else { addComma = true; } writer.Write(argument.DataType); } writer.WriteLine(") IS NULL;"); } } }
/// <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); } } } }
internal static void Drop(StreamWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { if (oldSchema == null) { return; } var referencedRules = new Dictionary <string, List <PgRule> >(); var dropedRules = new List <PgRule>(); foreach (var rule in oldSchema.Rules) { if (!newSchema.Contains(rule)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(rule.DropSql); } } }
/// <summary> /// Outputs statements for index comments that have changed. /// </summary> public static void AlterComments(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { if (oldSchema == null) { return; } foreach (PgIndex oldIndex in oldSchema.Indexes) { PgIndex newIndex = newSchema.GetIndex(oldIndex.Name); if (newIndex == null) { continue; } if ((oldIndex.Comment == null && newIndex.Comment != null) || (oldIndex.Comment != null && newIndex.Comment != null && !oldIndex.Comment.Equals(newIndex.Comment))) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON INDEX "); writer.Write(PgDiffStringExtension.QuoteName(newIndex.Name)); writer.Write(" IS "); writer.Write(newIndex.Comment); writer.WriteLine(';'); } else if (oldIndex.Comment != null && newIndex.Comment == null) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("COMMENT ON INDEX "); writer.Write(PgDiffStringExtension.QuoteName(newIndex.Name)); writer.WriteLine(" IS NULL;"); } } }
/// <summary> /// Outputs statements for creation of new <see cref="PgRule"/>s. /// </summary> internal static void Create(StreamWriter writer, PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { foreach (var rule in newSchema.Rules) { if (oldSchema == null || !oldSchema.Contains(rule)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(rule.CreationSql); } } }
/// <summary> /// Outputs statements for dropping of functions that exist no more. /// </summary> public static void Drop(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { if (oldSchema == null) { return; } // Drop functions that exist no more foreach (PgFunction oldFunction in oldSchema.Functions) { if (!newSchema.ContainsFunction(oldFunction.Signature)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(oldFunction.DropSQL); } } }
/// <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); } } }
/// <summary> /// Outputs statements for creation of new sequences. /// </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="searchPathHelper">Search path helper.</param> public static void Create(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { // Add new sequences foreach (PgSequence sequence in newSchema.Sequences) { if (oldSchema == null || !oldSchema.ContainsSequence(sequence.Name)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(sequence.CreationSQL); } } }
/// <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> /// Outputs statements for dropping of sequences that do not exist anymore. /// </summary> public static void Drop(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { if (oldSchema == null) { return; } // Drop sequences that do not exist in new schema foreach (PgSequence sequence in oldSchema.Sequences) { if (!newSchema.ContainsSequence(sequence.Name)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(sequence.DropSQL); } } }
/// <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> /// Adds <see cref="PgPrivilegeCommand.Grant"/> and <see cref="PgPrivilegeCommand.Revoke"/> privileges. /// </summary> public static void Create(StreamWriter writer, [NullGuard.AllowNull] PgSchema oldSchema, PgSchema newSchema, SearchPathHelper searchPathHelper) { // Add new sequences foreach (var privilege in newSchema.Privileges) { if (oldSchema == null || !oldSchema.ContainsPrivilege(privilege)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(BetaMessage); writer.WriteLine(privilege.Create()); } } if (oldSchema == null) { return; } // revert privileges foreach (var privilege in oldSchema.Privileges) { if (!newSchema.ContainsPrivilege(privilege)) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.WriteLine(BetaMessage); writer.WriteLine(privilege.CreateRevert()); } } }
/// <summary> /// Generate the needed alter table xxx set statistics when needed. /// </summary> private static void AddAlterStatistics(StreamWriter writer, PgTable oldTable, PgTable newTable, SearchPathHelper searchPathHelper) { var stats = new Dictionary <string, int?>(); foreach (PgColumn newColumn in newTable.Columns) { PgColumn oldColumn = oldTable.GetColumn(newColumn.Name); if (oldColumn != null) { int?oldStat = oldColumn.Statistics; int?newStat = newColumn.Statistics; int?newStatValue = null; if (newStat != null && (oldStat == null || !newStat.Equals(oldStat))) { newStatValue = newStat; } else if (oldStat != null && newStat == null) { newStatValue = Convert.ToInt32(-1); } if (newStatValue != null) { stats[newColumn.Name] = newStatValue; } } } foreach (KeyValuePair <string, int?> entry in stats) { searchPathHelper.OutputSearchPath(writer); writer.WriteLine(); writer.Write("ALTER TABLE ONLY "); writer.Write(PgDiffStringExtension.QuoteName(newTable.Name)); writer.Write(" ALTER COLUMN "); writer.Write(PgDiffStringExtension.QuoteName(entry.Key)); writer.Write(" SET STATISTICS "); writer.Write(entry.Value); writer.WriteLine(';'); } }