diff --git a/src/ConsoleTestQuickCompare/ConsoleTestQuickCompare.csproj b/src/ConsoleTestQuickCompare/ConsoleTestQuickCompare.csproj
index d8045c7..6429cf8 100644
--- a/src/ConsoleTestQuickCompare/ConsoleTestQuickCompare.csproj
+++ b/src/ConsoleTestQuickCompare/ConsoleTestQuickCompare.csproj
@@ -14,7 +14,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/ConsoleTestQuickCompare/Program.cs b/src/ConsoleTestQuickCompare/Program.cs
index b7cfff8..b93397e 100644
--- a/src/ConsoleTestQuickCompare/Program.cs
+++ b/src/ConsoleTestQuickCompare/Program.cs
@@ -8,6 +8,7 @@ namespace ConsoleTestQuickCompare;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using QuickCompareModel;
+using QuickCompareModel.Models;
/// Main program loop.
internal static class Program
diff --git a/src/ConsoleTestQuickCompare/Startup.cs b/src/ConsoleTestQuickCompare/Startup.cs
index 622963d..1003504 100644
--- a/src/ConsoleTestQuickCompare/Startup.cs
+++ b/src/ConsoleTestQuickCompare/Startup.cs
@@ -7,6 +7,7 @@ namespace ConsoleTestQuickCompare;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using QuickCompareModel;
+using QuickCompareModel.Models;
/// Initialises the dependency injection container from app settings.
internal class Startup
diff --git a/src/QuickCompareModel/DatabaseDifferences/BaseDifference.cs b/src/QuickCompareModel/DatabaseDifferences/BaseDifference.cs
index a4451c2..e4a48d5 100644
--- a/src/QuickCompareModel/DatabaseDifferences/BaseDifference.cs
+++ b/src/QuickCompareModel/DatabaseDifferences/BaseDifference.cs
@@ -2,97 +2,100 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseDifferences
+namespace QuickCompareModel.DatabaseDifferences;
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+/// Model to represent the most basic element and track the existence across two databases.
+///
+/// Initialises a new instance of the class
+/// with values determining whether the item exists in each database.
+///
+/// Value indicating whether the item exists in database 1.
+/// Value indicating whether the item exists in database 2.
+public partial class BaseDifference(bool existsInDatabase1, bool existsInDatabase2)
{
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
+ /// Whitespace indentation used for output text.
+ protected const string TabIndent = " ";
- /// Model to represent the most basic element and track the existence across two databases.
- public class BaseDifference
+ /// Gets or sets a value indicating whether the item exists in database 1.
+ public bool ExistsInDatabase1 { get; set; } = existsInDatabase1;
+
+ /// Gets or sets a value indicating whether the item exists in database 2.
+ public bool ExistsInDatabase2 { get; set; } = existsInDatabase2;
+
+ /// Gets a value indicating whether the item exists in both databases.
+ public bool ExistsInBothDatabases => this.ExistsInDatabase1 && this.ExistsInDatabase2;
+
+ /// Gets a value indicating whether there are any differences.
+ public virtual bool IsDifferent => !this.ExistsInBothDatabases;
+
+ /// A helper method to trim whitespace and comments from text to reduce false-positive results.
+ /// Text to modify.
+ /// Value indicating where to reduce all whitespace to a single character.
+ /// Modified text ready for comparison.
+ public static string CleanDefinitionText(string definition, bool stripWhiteSpace)
{
- /// Whitespace indentation used for output text.
- protected const string TabIndent = " ";
-
- ///
- /// Initialises a new instance of the class
- /// with values determining whether the item exists in each database.
- ///
- /// Value indicating whether the item exists in database 1.
- /// Value indicating whether the item exists in database 2.
- public BaseDifference(bool existsInDatabase1, bool existsInDatabase2)
+ if (string.IsNullOrWhiteSpace(definition))
{
- this.ExistsInDatabase1 = existsInDatabase1;
- this.ExistsInDatabase2 = existsInDatabase2;
+ return string.Empty;
}
- /// Gets or sets a value indicating whether the item exists in database 1.
- public bool ExistsInDatabase1 { get; set; }
+ definition = StripMultiLineComments(definition);
+ definition = StripSingleLineComments(definition);
- /// Gets or sets a value indicating whether the item exists in database 2.
- public bool ExistsInDatabase2 { get; set; }
+ if (stripWhiteSpace)
+ {
+ definition = StripCommaWhitespace(definition);
+ definition = NormaliseCommas(definition);
+ definition = ReduceWhitespaceToSingleCharacter(definition);
+ }
- /// Gets a value indicating whether the item exists in both databases.
- public bool ExistsInBothDatabases => this.ExistsInDatabase1 && this.ExistsInDatabase2;
+ return definition.Trim();
+ }
- /// Gets a value indicating whether there are any differences.
- public virtual bool IsDifferent => !this.ExistsInBothDatabases;
+ /// Gets a text description of the difference or returns an empty string if no difference is detected.
+ /// Difference description.
+ public override string ToString() => this.ExistsInBothDatabases ? string.Empty : $"does not exist in database {(this.ExistsInDatabase1 ? 2 : 1)}\r\n";
+
+ /// A helper method to list difference values for subsections.
+ /// Implementation of .
+ /// Difference collection.
+ /// Name of subsection.
+ /// Text output for subsection.
+ protected static string GetSubSectionDifferenceOutput(Dictionary source, string name)
+ where T : BaseDifference
+ {
+ var section = new StringBuilder();
- /// A helper method to trim whitespace and comments from text to reduce false-positive results.
- /// Text to modify.
- /// Value indicating where to reduce all whitespace to a single character.
- /// Modified text ready for comparison.
- public static string CleanDefinitionText(string definition, bool stripWhiteSpace)
+ foreach (var prop in source.Where(x => x.Value.IsDifferent))
{
- if (string.IsNullOrWhiteSpace(definition))
- {
- return string.Empty;
- }
-
- definition = StripMultiLineComments(definition);
- definition = StripSingleLineComments(definition);
-
- if (stripWhiteSpace)
- {
- definition = StripCommaWhitespace(definition);
- definition = NormaliseCommas(definition);
- definition = ReduceWhitespaceToSingleCharacter(definition);
- }
-
- return definition.Trim();
+ section.Append($"{TabIndent}{name}: {prop.Key} {prop.Value}");
}
- /// Gets a text description of the difference or returns an empty string if no difference is detected.
- /// Difference description.
- public override string ToString() => this.ExistsInBothDatabases ? string.Empty : $"does not exist in database {(this.ExistsInDatabase1 ? 2 : 1)}\r\n";
-
- /// A helper method to list difference values for subsections.
- /// Implementation of .
- /// Difference collection.
- /// Name of subsection.
- /// Text output for subsection.
- protected static string GetSubSectionDifferenceOutput(Dictionary source, string name)
- where T : BaseDifference
- {
- var section = new StringBuilder();
+ return section.ToString();
+ }
- foreach (var prop in source.Where(x => x.Value.IsDifferent))
- {
- section.Append($"{TabIndent}{name}: {prop.Key} {prop.Value}");
- }
+ private static string StripMultiLineComments(string input) => MultilineCommentRegex().Replace(input, string.Empty);
- return section.ToString();
- }
+ private static string StripSingleLineComments(string input) => SingleLineCommentRegex().Replace(input, string.Empty);
- private static string StripMultiLineComments(string input) => Regex.Replace(input, @"/\*[^*]*\*+([^/*][^*]*\*+)*/", string.Empty);
+ private static string StripCommaWhitespace(string input) => CommaWitespaceRegex().Replace(input, ",");
- private static string StripSingleLineComments(string input) => Regex.Replace(input, @"(--)([^\r\n]+)", string.Empty);
+ private static string NormaliseCommas(string input) => CommaRegex().Replace(input, ", ");
- private static string StripCommaWhitespace(string input) => Regex.Replace(input, @"\s*,\s*", ",");
+ private static string ReduceWhitespaceToSingleCharacter(string input) => WhitespaceRegex().Replace(input, " ");
- private static string NormaliseCommas(string input) => Regex.Replace(input, @"[,]", ", ");
+ [GeneratedRegex(@"/\*[^*]*\*+([^/*][^*]*\*+)*/")] private static partial Regex MultilineCommentRegex();
- private static string ReduceWhitespaceToSingleCharacter(string input) => Regex.Replace(input, @"[\s]+", " ");
- }
+ [GeneratedRegex(@"(--)([^\r\n]+)")] private static partial Regex SingleLineCommentRegex();
+
+ [GeneratedRegex(@"\s*,\s*")] private static partial Regex CommaWitespaceRegex();
+
+ [GeneratedRegex(@"[,]")] private static partial Regex CommaRegex();
+
+ [GeneratedRegex(@"[\s]+")] private static partial Regex WhitespaceRegex();
}
diff --git a/src/QuickCompareModel/DatabaseDifferences/DatabaseObjectDifference.cs b/src/QuickCompareModel/DatabaseDifferences/DatabaseObjectDifference.cs
index 1f11d69..5c4c9f4 100644
--- a/src/QuickCompareModel/DatabaseDifferences/DatabaseObjectDifference.cs
+++ b/src/QuickCompareModel/DatabaseDifferences/DatabaseObjectDifference.cs
@@ -2,73 +2,63 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseDifferences
-{
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
+namespace QuickCompareModel.DatabaseDifferences;
- /// Model to represent a complex database element and track the differences across two databases.
- public class DatabaseObjectDifference : BaseDifference
- {
- ///
- /// Initialises a new instance of the class
- /// with values determining whether the item exists in each database.
- ///
- /// Value indicating whether the item exists in database 1.
- /// Value indicating whether the item exists in database 2.
- public DatabaseObjectDifference(bool existsInDatabase1, bool existsInDatabase2)
- : base(existsInDatabase1, existsInDatabase2)
- {
- }
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
- /// Gets or sets the body text of the object in database 1.
- public string ObjectDefinition1 { get; set; }
+/// Model to represent a complex database element and track the differences across two databases.
+/// Value indicating whether the item exists in database 1.
+/// Value indicating whether the item exists in database 2.
+public class DatabaseObjectDifference(bool existsInDatabase1, bool existsInDatabase2) : BaseDifference(existsInDatabase1, existsInDatabase2)
+{
+ /// Gets or sets the body text of the object in database 1.
+ public string ObjectDefinition1 { get; set; }
- /// Gets or sets the body text of the object in database 2.
- public string ObjectDefinition2 { get; set; }
+ /// Gets or sets the body text of the object in database 2.
+ public string ObjectDefinition2 { get; set; }
- /// Gets or sets a set of models to represent extended properties and track the differences across two databases.
- public Dictionary ExtendedPropertyDifferences { get; set; } = new Dictionary();
+ /// Gets or sets a set of models to represent extended properties and track the differences across two databases.
+ public Dictionary ExtendedPropertyDifferences { get; set; } = [];
- /// Gets or sets a set of models to represent permissions and track the differences across two databases.
- public Dictionary PermissionDifferences { get; set; } = new Dictionary();
+ /// Gets or sets a set of models to represent permissions and track the differences across two databases.
+ public Dictionary PermissionDifferences { get; set; } = [];
- /// Gets a value indicating whether the body text is different.
- public bool DefinitionsAreDifferent => CleanDefinitionText(this.ObjectDefinition1, true) != CleanDefinitionText(this.ObjectDefinition2, true);
+ /// Gets a value indicating whether the body text is different.
+ public bool DefinitionsAreDifferent => CleanDefinitionText(this.ObjectDefinition1, true) != CleanDefinitionText(this.ObjectDefinition2, true);
- /// Gets a value indicating whether any differences have been tracked.
- public override bool IsDifferent =>
- base.IsDifferent ||
- this.DefinitionsAreDifferent ||
- this.PermissionDifferences.Values.Any(x => x.IsDifferent) ||
- this.ExtendedPropertyDifferences.Values.Any(x => x.IsDifferent);
+ /// Gets a value indicating whether any differences have been tracked.
+ public override bool IsDifferent =>
+ base.IsDifferent ||
+ this.DefinitionsAreDifferent ||
+ this.PermissionDifferences.Values.Any(x => x.IsDifferent) ||
+ this.ExtendedPropertyDifferences.Values.Any(x => x.IsDifferent);
- /// Gets a text description of the difference or returns an empty string if no difference is detected.
- /// Difference description.
- public override string ToString()
+ /// Gets a text description of the difference or returns an empty string if no difference is detected.
+ /// Difference description.
+ public override string ToString()
+ {
+ if (!this.IsDifferent)
{
- if (!this.IsDifferent)
- {
- return string.Empty;
- }
+ return string.Empty;
+ }
- if (base.IsDifferent)
- {
- return base.ToString();
- }
+ if (base.IsDifferent)
+ {
+ return base.ToString();
+ }
- var sb = new StringBuilder("\r\n");
+ var sb = new StringBuilder("\r\n");
- if (this.DefinitionsAreDifferent)
- {
- sb.AppendLine($"{TabIndent}Definitions are different");
- }
+ if (this.DefinitionsAreDifferent)
+ {
+ sb.AppendLine($"{TabIndent}Definitions are different");
+ }
- sb.Append(GetSubSectionDifferenceOutput(this.ExtendedPropertyDifferences, "Extended property"));
- sb.Append(GetSubSectionDifferenceOutput(this.PermissionDifferences, "Permission"));
+ sb.Append(GetSubSectionDifferenceOutput(this.ExtendedPropertyDifferences, "Extended property"));
+ sb.Append(GetSubSectionDifferenceOutput(this.PermissionDifferences, "Permission"));
- return sb.ToString();
- }
+ return sb.ToString();
}
}
diff --git a/src/QuickCompareModel/DatabaseDifferences/Differences.cs b/src/QuickCompareModel/DatabaseDifferences/Differences.cs
index 91d79ce..818154d 100644
--- a/src/QuickCompareModel/DatabaseDifferences/Differences.cs
+++ b/src/QuickCompareModel/DatabaseDifferences/Differences.cs
@@ -2,105 +2,104 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseDifferences
-{
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
+namespace QuickCompareModel.DatabaseDifferences;
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
- /// Model to hold lists of various differences between two databases.
- public class Differences
+/// Model to hold lists of various differences between two databases.
+public class Differences
+{
+ /// Gets or sets a friendly name for database 1.
+ public string Database1 { get; set; }
+
+ /// Gets or sets a friendly name for database 2.
+ public string Database2 { get; set; }
+
+ /// Gets or sets a set of models to represent extended properties and track the differences across two databases.
+ public Dictionary ExtendedPropertyDifferences { get; set; }
+ = [];
+
+ /// Gets or sets a set of models to represent permissions and track the differences across two databases.
+ public Dictionary PermissionDifferences { get; set; }
+ = [];
+
+ /// Gets or sets a set of models to represent tables and track the differences across two databases.
+ public Dictionary TableDifferences { get; set; }
+ = [];
+
+ /// Gets or sets a set of models to represent user types and track the differences across two databases.
+ public Dictionary UserTypeDifferences { get; set; }
+ = [];
+
+ /// Gets or sets a set of models to represent functions and track the differences across two databases.
+ public Dictionary FunctionDifferences { get; set; }
+ = [];
+
+ /// Gets or sets a set of models to represent stored procedures and track the differences across two databases.
+ public Dictionary StoredProcedureDifferences { get; set; }
+ = [];
+
+ /// Gets or sets a set of models to represent views and track the differences across two databases.
+ public Dictionary ViewDifferences { get; set; }
+ = [];
+
+ /// Gets or sets a set of models to represent synonyms and track the differences across two databases.
+ public Dictionary SynonymDifferences { get; set; }
+ = [];
+
+ /// Gets a value indicating whether any differences have been tracked.
+ public bool HasDifferences =>
+ this.ExtendedPropertyDifferences.Any(x => x.Value.IsDifferent) ||
+ this.PermissionDifferences.Any(x => x.Value.IsDifferent) ||
+ this.TableDifferences.Any(x => x.Value.IsDifferent) ||
+ this.FunctionDifferences.Any(x => x.Value.IsDifferent) ||
+ this.StoredProcedureDifferences.Any(x => x.Value.IsDifferent) ||
+ this.ViewDifferences.Any(x => x.Value.IsDifferent) ||
+ this.SynonymDifferences.Any(x => x.Value.IsDifferent);
+
+ /// Gets a report of the differences, whether any were detected or not.
+ /// Difference description.
+ public override string ToString()
{
- /// Gets or sets a friendly name for database 1.
- public string Database1 { get; set; }
-
- /// Gets or sets a friendly name for database 2.
- public string Database2 { get; set; }
-
- /// Gets or sets a set of models to represent extended properties and track the differences across two databases.
- public Dictionary ExtendedPropertyDifferences { get; set; }
- = new Dictionary();
-
- /// Gets or sets a set of models to represent permissions and track the differences across two databases.
- public Dictionary PermissionDifferences { get; set; }
- = new Dictionary();
-
- /// Gets or sets a set of models to represent tables and track the differences across two databases.
- public Dictionary TableDifferences { get; set; }
- = new Dictionary();
-
- /// Gets or sets a set of models to represent user types and track the differences across two databases.
- public Dictionary UserTypeDifferences { get; set; }
- = new Dictionary();
-
- /// Gets or sets a set of models to represent functions and track the differences across two databases.
- public Dictionary FunctionDifferences { get; set; }
- = new Dictionary();
-
- /// Gets or sets a set of models to represent stored procedures and track the differences across two databases.
- public Dictionary StoredProcedureDifferences { get; set; }
- = new Dictionary();
-
- /// Gets or sets a set of models to represent views and track the differences across two databases.
- public Dictionary ViewDifferences { get; set; }
- = new Dictionary();
-
- /// Gets or sets a set of models to represent synonyms and track the differences across two databases.
- public Dictionary SynonymDifferences { get; set; }
- = new Dictionary();
-
- /// Gets a value indicating whether any differences have been tracked.
- public bool HasDifferences =>
- this.ExtendedPropertyDifferences.Any(x => x.Value.IsDifferent) ||
- this.PermissionDifferences.Any(x => x.Value.IsDifferent) ||
- this.TableDifferences.Any(x => x.Value.IsDifferent) ||
- this.FunctionDifferences.Any(x => x.Value.IsDifferent) ||
- this.StoredProcedureDifferences.Any(x => x.Value.IsDifferent) ||
- this.ViewDifferences.Any(x => x.Value.IsDifferent) ||
- this.SynonymDifferences.Any(x => x.Value.IsDifferent);
-
- /// Gets a report of the differences, whether any were detected or not.
- /// Difference description.
- public override string ToString()
- {
- var output = new StringBuilder("QuickCompare schema comparison result\r\n\r\n");
- output.AppendLine($"Database 1: {this.Database1}");
- output.AppendLine($"Database 2: {this.Database2}\r\n");
-
- if (!this.HasDifferences)
- {
- output.AppendLine("NO DIFFERENCES HAVE BEEN FOUND");
- return output.ToString();
- }
-
- output.Append(GetSectionDifferenceOutput(this.ExtendedPropertyDifferences, "Extended property"));
- output.Append(GetSectionDifferenceOutput(this.PermissionDifferences, "Permission"));
- output.Append(GetSectionDifferenceOutput(this.TableDifferences, "Table"));
- output.Append(GetSectionDifferenceOutput(this.UserTypeDifferences, "User type"));
- output.Append(GetSectionDifferenceOutput(this.ViewDifferences, "View"));
- output.Append(GetSectionDifferenceOutput(this.FunctionDifferences, "Function"));
- output.Append(GetSectionDifferenceOutput(this.StoredProcedureDifferences, "Stored procedure"));
- output.Append(GetSectionDifferenceOutput(this.SynonymDifferences, "Synonym"));
+ var output = new StringBuilder("QuickCompare schema comparison result\r\n\r\n");
+ output.AppendLine($"Database 1: {this.Database1}");
+ output.AppendLine($"Database 2: {this.Database2}\r\n");
+ if (!this.HasDifferences)
+ {
+ output.AppendLine("NO DIFFERENCES HAVE BEEN FOUND");
return output.ToString();
}
- private static string GetSectionDifferenceOutput(Dictionary source, string name)
- where T : BaseDifference
- {
- var section = new StringBuilder();
+ output.Append(GetSectionDifferenceOutput(this.ExtendedPropertyDifferences, "Extended property"));
+ output.Append(GetSectionDifferenceOutput(this.PermissionDifferences, "Permission"));
+ output.Append(GetSectionDifferenceOutput(this.TableDifferences, "Table"));
+ output.Append(GetSectionDifferenceOutput(this.UserTypeDifferences, "User type"));
+ output.Append(GetSectionDifferenceOutput(this.ViewDifferences, "View"));
+ output.Append(GetSectionDifferenceOutput(this.FunctionDifferences, "Function"));
+ output.Append(GetSectionDifferenceOutput(this.StoredProcedureDifferences, "Stored procedure"));
+ output.Append(GetSectionDifferenceOutput(this.SynonymDifferences, "Synonym"));
- foreach (var prop in source.Where(x => x.Value.IsDifferent))
- {
- section.Append($"{name}: {prop.Key} {prop.Value}");
- }
+ return output.ToString();
+ }
- if (section.Length > 0)
- {
- section.Insert(0, $"\r\n{name.ToUpperInvariant()} DIFFERENCES\r\n\r\n");
- }
+ private static string GetSectionDifferenceOutput(Dictionary source, string name)
+ where T : BaseDifference
+ {
+ var section = new StringBuilder();
+
+ foreach (var prop in source.Where(x => x.Value.IsDifferent))
+ {
+ section.Append($"{name}: {prop.Key} {prop.Value}");
+ }
- return section.ToString();
+ if (section.Length > 0)
+ {
+ section.Insert(0, $"\r\n{name.ToUpperInvariant()} DIFFERENCES\r\n\r\n");
}
+
+ return section.ToString();
}
}
diff --git a/src/QuickCompareModel/DatabaseDifferences/ExtendedPropertyDifference.cs b/src/QuickCompareModel/DatabaseDifferences/ExtendedPropertyDifference.cs
index 6768191..75323c6 100644
--- a/src/QuickCompareModel/DatabaseDifferences/ExtendedPropertyDifference.cs
+++ b/src/QuickCompareModel/DatabaseDifferences/ExtendedPropertyDifference.cs
@@ -2,35 +2,25 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseDifferences
-{
- /// Model to represent an extended property and track the differences across two databases.
- public class ExtendedPropertyDifference : BaseDifference
- {
- ///
- /// Initialises a new instance of the class
- /// with values determining whether the item exists in each database.
- ///
- /// Value indicating whether the item exists in database 1.
- /// Value indicating whether the item exists in database 2.
- public ExtendedPropertyDifference(bool existsInDatabase1, bool existsInDatabase2)
- : base(existsInDatabase1, existsInDatabase2)
- {
- }
+namespace QuickCompareModel.DatabaseDifferences;
- /// Gets or sets the property value for database 1.
- public string Value1 { get; set; }
+/// Model to represent an extended property and track the differences across two databases.
+/// Value indicating whether the item exists in database 1.
+/// Value indicating whether the item exists in database 2.
+public class ExtendedPropertyDifference(bool existsInDatabase1, bool existsInDatabase2) : BaseDifference(existsInDatabase1, existsInDatabase2)
+{
+ /// Gets or sets the property value for database 1.
+ public string Value1 { get; set; }
- /// Gets or sets the property value for database 2.
- public string Value2 { get; set; }
+ /// Gets or sets the property value for database 2.
+ public string Value2 { get; set; }
- /// Gets a value indicating whether any differences have been tracked.
- public override bool IsDifferent => base.IsDifferent || this.Value1 != this.Value2;
+ /// Gets a value indicating whether any differences have been tracked.
+ public override bool IsDifferent => base.IsDifferent || this.Value1 != this.Value2;
- /// Gets a text description of the difference or returns an empty string if no difference is detected.
- /// Difference description.
- public override string ToString() => this.IsDifferent
- ? base.IsDifferent ? base.ToString() : $"value is different; [{this.Value1}] in database 1, [{this.Value2}] in database 2\r\n"
- : string.Empty;
- }
+ /// Gets a text description of the difference or returns an empty string if no difference is detected.
+ /// Difference description.
+ public override string ToString() => this.IsDifferent
+ ? base.IsDifferent ? base.ToString() : $"value is different; [{this.Value1}] in database 1, [{this.Value2}] in database 2\r\n"
+ : string.Empty;
}
diff --git a/src/QuickCompareModel/DatabaseDifferences/ItemDifference.cs b/src/QuickCompareModel/DatabaseDifferences/ItemDifference.cs
index 45e7b06..47ca6b6 100644
--- a/src/QuickCompareModel/DatabaseDifferences/ItemDifference.cs
+++ b/src/QuickCompareModel/DatabaseDifferences/ItemDifference.cs
@@ -2,64 +2,54 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseDifferences
+namespace QuickCompareModel.DatabaseDifferences;
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+///
+/// Model to represent an element that belongs to a table.
+///
+/// Value indicating whether the item exists in database 1.
+/// Value indicating whether the item exists in database 2.
+public class ItemDifference(bool existsInDatabase1, bool existsInDatabase2) : BaseDifference(existsInDatabase1, existsInDatabase2)
{
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
+ /// Gets or sets a list of tracked difference strings.
+ public List Differences { get; set; } = [];
- ///
- /// Model to represent an element that belongs to a table.
- ///
- public class ItemDifference : BaseDifference
- {
- ///
- /// Initialises a new instance of the class
- /// with values determining whether the item exists in each database.
- ///
- /// Value indicating whether the item exists in database 1.
- /// Value indicating whether the item exists in database 2.
- public ItemDifference(bool existsInDatabase1, bool existsInDatabase2)
- : base(existsInDatabase1, existsInDatabase2)
- {
- }
+ /// Gets or sets the item type.
+ public string ItemType { get; set; }
- /// Gets or sets a list of tracked difference strings.
- public List Differences { get; set; } = new List();
+ /// Gets a value indicating whether any differences have been tracked.
+ public override bool IsDifferent => base.IsDifferent || this.Differences.Count > 0;
- /// Gets or sets the item type.
- public string ItemType { get; set; }
-
- /// Gets a value indicating whether any differences have been tracked.
- public override bool IsDifferent => base.IsDifferent || this.Differences.Count > 0;
+ /// Gets a text description of the list of differences or returns an empty string if no difference is detected.
+ /// Ttext description of the list of differences.
+ public string DifferenceList()
+ {
+ var sb = new StringBuilder();
- /// Gets a text description of the list of differences or returns an empty string if no difference is detected.
- /// Ttext description of the list of differences.
- public string DifferenceList()
+ if (this.Differences.Count == 1)
{
- var sb = new StringBuilder();
-
- if (this.Differences.Count == 1)
- {
- sb.AppendLine(this.Differences.Single());
- }
- else if (this.Differences.Count > 1)
- {
- sb.Append($"\r\n{TabIndent} - ");
- sb.AppendLine(string.Join($"\r\n{TabIndent} - ", this.Differences.ToArray()));
- }
- else
- {
- sb.Append("\r\n"); // (only ItemWithPropertiesDifference has output)
- }
-
- return sb.ToString();
+ sb.AppendLine(this.Differences.Single());
+ }
+ else if (this.Differences.Count > 1)
+ {
+ sb.Append($"\r\n{TabIndent} - ");
+ sb.AppendLine(string.Join($"\r\n{TabIndent} - ", this.Differences.ToArray()));
+ }
+ else
+ {
+ sb.Append("\r\n"); // (only ItemWithPropertiesDifference has output)
}
- /// Gets a text description of the differences or returns an empty string if no difference is detected.
- /// Difference description.
- public override string ToString() => this.IsDifferent
- ? base.IsDifferent ? base.ToString() : this.DifferenceList()
- : string.Empty;
+ return sb.ToString();
}
+
+ /// Gets a text description of the differences or returns an empty string if no difference is detected.
+ /// Difference description.
+ public override string ToString() => this.IsDifferent
+ ? base.IsDifferent ? base.ToString() : this.DifferenceList()
+ : string.Empty;
}
diff --git a/src/QuickCompareModel/DatabaseDifferences/ItemWithPropertiesDifference.cs b/src/QuickCompareModel/DatabaseDifferences/ItemWithPropertiesDifference.cs
index 019ce05..9c860f7 100644
--- a/src/QuickCompareModel/DatabaseDifferences/ItemWithPropertiesDifference.cs
+++ b/src/QuickCompareModel/DatabaseDifferences/ItemWithPropertiesDifference.cs
@@ -2,62 +2,61 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseDifferences
+namespace QuickCompareModel.DatabaseDifferences;
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+/// Model to represent an element that can have extended properties and belongs to a table.
+public class ItemWithPropertiesDifference
+ : ItemDifference
{
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
+ ///
+ /// Initialises a new instance of the class
+ /// with values determining whether the item exists in each database.
+ ///
+ /// Value indicating whether the item exists in database 1.
+ /// Value indicating whether the item exists in database 2.
+ public ItemWithPropertiesDifference(bool existsInDatabase1, bool existsInDatabase2)
+ : base(existsInDatabase1, existsInDatabase2)
+ {
+ }
- /// Model to represent an element that can have extended properties and belongs to a table.
- public class ItemWithPropertiesDifference
- : ItemDifference
+ ///
+ /// Initialises a new instance of the class
+ /// with values determining the type and whether the item exists in each database.
+ ///
+ /// Value indicating whether the item exists in database 1.
+ /// Value indicating whether the item exists in database 2.
+ /// String describing the element type.
+ public ItemWithPropertiesDifference(bool existsInDatabase1, bool existsInDatabase2, string itemType)
+ : base(existsInDatabase1, existsInDatabase2) => this.ItemType = itemType;
+
+ /// Gets or sets a set of models to represent extended properties and track the differences across two databases.
+ public Dictionary ExtendedPropertyDifferences { get; set; }
+ = [];
+
+ /// Gets a value indicating whether any differences have been tracked.
+ public override bool IsDifferent => base.IsDifferent || this.ExtendedPropertyDifferences.Values.Any(x => x.IsDifferent);
+
+ /// Gets a text description of the difference or returns an empty string if no difference is detected.
+ /// Difference description.
+ public override string ToString()
{
- ///
- /// Initialises a new instance of the class
- /// with values determining whether the item exists in each database.
- ///
- /// Value indicating whether the item exists in database 1.
- /// Value indicating whether the item exists in database 2.
- public ItemWithPropertiesDifference(bool existsInDatabase1, bool existsInDatabase2)
- : base(existsInDatabase1, existsInDatabase2)
+ if (!this.IsDifferent)
{
+ return string.Empty;
}
- ///
- /// Initialises a new instance of the class
- /// with values determining the type and whether the item exists in each database.
- ///
- /// Value indicating whether the item exists in database 1.
- /// Value indicating whether the item exists in database 2.
- /// String describing the element type.
- public ItemWithPropertiesDifference(bool existsInDatabase1, bool existsInDatabase2, string itemType)
- : base(existsInDatabase1, existsInDatabase2) => this.ItemType = itemType;
-
- /// Gets or sets a set of models to represent extended properties and track the differences across two databases.
- public Dictionary ExtendedPropertyDifferences { get; set; }
- = new Dictionary();
-
- /// Gets a value indicating whether any differences have been tracked.
- public override bool IsDifferent => base.IsDifferent || this.ExtendedPropertyDifferences.Values.Any(x => x.IsDifferent);
-
- /// Gets a text description of the difference or returns an empty string if no difference is detected.
- /// Difference description.
- public override string ToString()
+ if (!this.ExistsInBothDatabases)
{
- if (!this.IsDifferent)
- {
- return string.Empty;
- }
-
- if (!this.ExistsInBothDatabases)
- {
- return base.ToString();
- }
+ return base.ToString();
+ }
- var sb = new StringBuilder(base.ToString());
- sb.Append(GetSubSectionDifferenceOutput(this.ExtendedPropertyDifferences, "Extended property"));
+ var sb = new StringBuilder(base.ToString());
+ sb.Append(GetSubSectionDifferenceOutput(this.ExtendedPropertyDifferences, "Extended property"));
- return sb.ToString();
- }
+ return sb.ToString();
}
}
diff --git a/src/QuickCompareModel/DatabaseDifferences/TableDifference.cs b/src/QuickCompareModel/DatabaseDifferences/TableDifference.cs
index a3ab1ba..22dce3b 100644
--- a/src/QuickCompareModel/DatabaseDifferences/TableDifference.cs
+++ b/src/QuickCompareModel/DatabaseDifferences/TableDifference.cs
@@ -2,88 +2,72 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseDifferences
-{
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
+namespace QuickCompareModel.DatabaseDifferences;
- /// Model to represent the table element and track the differences across two databases.
- public class TableDifference : BaseDifference
- {
- ///
- /// Initialises a new instance of the class
- /// with values determining whether the item exists in each database.
- ///
- /// Value indicating whether the item exists in database 1.
- /// Value indicating whether the item exists in database 2.
- public TableDifference(bool existsInDatabase1, bool existsInDatabase2)
- : base(existsInDatabase1, existsInDatabase2)
- {
- }
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
- /// Gets or sets a set of models to represent columns and track the differences across two databases.
- public Dictionary ColumnDifferences { get; set; }
- = new Dictionary();
+/// Model to represent the table element and track the differences across two databases.
+/// Value indicating whether the item exists in database 1.
+/// Value indicating whether the item exists in database 2.
+public class TableDifference(bool existsInDatabase1, bool existsInDatabase2) : BaseDifference(existsInDatabase1, existsInDatabase2)
+{
+ /// Gets or sets a set of models to represent columns and track the differences across two databases.
+ public Dictionary ColumnDifferences { get; set; } = [];
- /// Gets or sets a set of models to represent columns and track the differences across two databases.
- public Dictionary RelationshipDifferences { get; set; }
- = new Dictionary();
+ /// Gets or sets a set of models to represent columns and track the differences across two databases.
+ public Dictionary RelationshipDifferences { get; set; } = [];
- /// Gets or sets a set of models to represent indexes and track the differences across two databases.
- public Dictionary IndexDifferences { get; set; }
- = new Dictionary();
+ /// Gets or sets a set of models to represent indexes and track the differences across two databases.
+ public Dictionary IndexDifferences { get; set; } = [];
- /// Gets or sets a set of models to represent triggers and track the differences across two databases.
- public Dictionary TriggerDifferences { get; set; }
- = new Dictionary();
+ /// Gets or sets a set of models to represent triggers and track the differences across two databases.
+ public Dictionary TriggerDifferences { get; set; } = [];
- /// Gets or sets a set of models to represent extended properties and track the differences across two databases.
- public Dictionary ExtendedPropertyDifferences { get; set; }
- = new Dictionary();
+ /// Gets or sets a set of models to represent extended properties and track the differences across two databases.
+ public Dictionary ExtendedPropertyDifferences { get; set; } = [];
- /// Gets or sets a set of models to represent permissions and track the differences across two databases.
- public Dictionary PermissionDifferences { get; set; }
- = new Dictionary();
+ /// Gets or sets a set of models to represent permissions and track the differences across two databases.
+ public Dictionary PermissionDifferences { get; set; } = [];
- /// Gets a value indicating whether any differences have been tracked.
- public override bool IsDifferent =>
- base.IsDifferent ||
- this.ColumnDifferences.Values.Any(x => x.IsDifferent) ||
- this.RelationshipDifferences.Values.Any(x => x.IsDifferent) ||
- this.IndexDifferences.Values.Any(x => x.IsDifferent) ||
- this.TriggerDifferences.Values.Any(x => x.IsDifferent) ||
- this.PermissionDifferences.Values.Any(x => x.IsDifferent) ||
- this.ExtendedPropertyDifferences.Values.Any(x => x.IsDifferent);
+ /// Gets a value indicating whether any differences have been tracked.
+ public override bool IsDifferent =>
+ base.IsDifferent ||
+ this.ColumnDifferences.Values.Any(x => x.IsDifferent) ||
+ this.RelationshipDifferences.Values.Any(x => x.IsDifferent) ||
+ this.IndexDifferences.Values.Any(x => x.IsDifferent) ||
+ this.TriggerDifferences.Values.Any(x => x.IsDifferent) ||
+ this.PermissionDifferences.Values.Any(x => x.IsDifferent) ||
+ this.ExtendedPropertyDifferences.Values.Any(x => x.IsDifferent);
- /// Gets a text description of the difference or returns an empty string if no difference is detected.
- /// Difference description.
- public override string ToString()
+ /// Gets a text description of the difference or returns an empty string if no difference is detected.
+ /// Difference description.
+ public override string ToString()
+ {
+ if (!this.IsDifferent)
{
- if (!this.IsDifferent)
- {
- return string.Empty;
- }
-
- if (base.IsDifferent)
- {
- return base.ToString();
- }
+ return string.Empty;
+ }
- var section = new StringBuilder("\r\n");
+ if (base.IsDifferent)
+ {
+ return base.ToString();
+ }
- section.Append(GetSubSectionDifferenceOutput(this.ColumnDifferences, "Column"));
- section.Append(GetSubSectionDifferenceOutput(this.TriggerDifferences, "Trigger"));
- section.Append(GetSubSectionDifferenceOutput(this.RelationshipDifferences, "Relation"));
- section.Append(GetSubSectionDifferenceOutput(this.ExtendedPropertyDifferences, "Extended property"));
- section.Append(GetSubSectionDifferenceOutput(this.PermissionDifferences, "Permission"));
+ var section = new StringBuilder("\r\n");
- foreach (var indexDiff in this.IndexDifferences.Where(x => x.Value.IsDifferent))
- {
- section.Append($"{TabIndent}{indexDiff.Value.ItemType}: {indexDiff.Key} {indexDiff.Value}");
- }
+ section.Append(GetSubSectionDifferenceOutput(this.ColumnDifferences, "Column"));
+ section.Append(GetSubSectionDifferenceOutput(this.TriggerDifferences, "Trigger"));
+ section.Append(GetSubSectionDifferenceOutput(this.RelationshipDifferences, "Relation"));
+ section.Append(GetSubSectionDifferenceOutput(this.ExtendedPropertyDifferences, "Extended property"));
+ section.Append(GetSubSectionDifferenceOutput(this.PermissionDifferences, "Permission"));
- return section.ToString();
+ foreach (var indexDiff in this.IndexDifferences.Where(x => x.Value.IsDifferent))
+ {
+ section.Append($"{TabIndent}{indexDiff.Value.ItemType}: {indexDiff.Key} {indexDiff.Value}");
}
+
+ return section.ToString();
}
}
diff --git a/src/QuickCompareModel/DatabaseInstance.cs b/src/QuickCompareModel/DatabaseInstance.cs
deleted file mode 100644
index b795782..0000000
--- a/src/QuickCompareModel/DatabaseInstance.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Copyright (c) Dan Ware. All rights reserved.
-//
-
-namespace QuickCompareModel
-{
- /// Enumeration to define which database is in scope.
- public enum DatabaseInstance
- {
- /// Value is not defined.
- Unknown,
-
- /// The first database in the comparison.
- Database1,
-
- /// The second database in the comparison.
- Database2,
- }
-}
diff --git a/src/QuickCompareModel/DatabaseSchema/DataReaderExtensions.cs b/src/QuickCompareModel/DatabaseSchema/DataReaderExtensions.cs
index 792098a..b6f063b 100644
--- a/src/QuickCompareModel/DatabaseSchema/DataReaderExtensions.cs
+++ b/src/QuickCompareModel/DatabaseSchema/DataReaderExtensions.cs
@@ -2,55 +2,54 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
+namespace QuickCompareModel.DatabaseSchema;
+
+using System.Data.SqlClient;
+
+///
+/// Set of extensions to improve cognitive complexity when dealing with DBNull to null conversions.
+///
+public static class DataReaderExtensions
{
- using System.Data.SqlClient;
-
- ///
- /// Set of extensions to improve cognitive complexity when dealing with DBNull to null conversions.
- ///
- public static class DataReaderExtensions
- {
- /// Gets the value of the specified column as a string or a null.
- /// The current instance of .
- /// The zero-based column ordinal.
- /// The value of the specified column.
- public static string GetNullableString(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : dr.GetString(index);
-
- /// Gets the value of the specified column as a byte or a null.
- /// The current instance of .
- /// The zero-based column ordinal.
- /// The value of the specified column.
- public static int? GetNullableByte(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : (int?)dr.GetByte(index);
-
- /// Gets the value of the specified column as a decimal or a null.
- /// The current instance of .
- /// The zero-based column ordinal.
- /// The value of the specified column.
- public static decimal? GetNullableDecimal(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : (decimal?)dr.GetDecimal(index);
-
- /// Gets the value of the specified column as an Int16 or a null.
- /// The current instance of .
- /// The zero-based column ordinal.
- /// The value of the specified column.
- public static int? GetNullableInt16(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : (int?)dr.GetInt16(index);
-
- /// Gets the value of the specified column as an Int32 or a null.
- /// The current instance of .
- /// The zero-based column ordinal.
- /// The value of the specified column.
- public static int? GetNullableInt32(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : (int?)dr.GetInt32(index);
-
- /// Gets the value of the specified column as an Int32 and returns a Boolean.
- /// The current instance of .
- /// The zero-based column ordinal.
- /// The interpreted value of the specified column.
- public static bool GetNullableInt32AsBoolean(this SqlDataReader dr, int index) => !dr.IsDBNull(index) && dr.GetInt32(index) == 1;
-
- /// Gets the value of the specified column as an Int32 and returns a Boolean.
- /// The current instance of .
- /// The zero-based column ordinal.
- /// The interpreted value of the specified column.
- public static bool GetInt32AsBoolean(this SqlDataReader dr, int index) => dr.GetInt32(index) == 1;
- }
+ /// Gets the value of the specified column as a string or a null.
+ /// The current instance of .
+ /// The zero-based column ordinal.
+ /// The value of the specified column.
+ public static string GetNullableString(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : dr.GetString(index);
+
+ /// Gets the value of the specified column as a byte or a null.
+ /// The current instance of .
+ /// The zero-based column ordinal.
+ /// The value of the specified column.
+ public static int? GetNullableByte(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : (int?)dr.GetByte(index);
+
+ /// Gets the value of the specified column as a decimal or a null.
+ /// The current instance of .
+ /// The zero-based column ordinal.
+ /// The value of the specified column.
+ public static decimal? GetNullableDecimal(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : (decimal?)dr.GetDecimal(index);
+
+ /// Gets the value of the specified column as an Int16 or a null.
+ /// The current instance of .
+ /// The zero-based column ordinal.
+ /// The value of the specified column.
+ public static int? GetNullableInt16(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : (int?)dr.GetInt16(index);
+
+ /// Gets the value of the specified column as an Int32 or a null.
+ /// The current instance of .
+ /// The zero-based column ordinal.
+ /// The value of the specified column.
+ public static int? GetNullableInt32(this SqlDataReader dr, int index) => dr.IsDBNull(index) ? null : (int?)dr.GetInt32(index);
+
+ /// Gets the value of the specified column as an Int32 and returns a Boolean.
+ /// The current instance of .
+ /// The zero-based column ordinal.
+ /// The interpreted value of the specified column.
+ public static bool GetNullableInt32AsBoolean(this SqlDataReader dr, int index) => !dr.IsDBNull(index) && dr.GetInt32(index) == 1;
+
+ /// Gets the value of the specified column as an Int32 and returns a Boolean.
+ /// The current instance of .
+ /// The zero-based column ordinal.
+ /// The interpreted value of the specified column.
+ public static bool GetInt32AsBoolean(this SqlDataReader dr, int index) => dr.GetInt32(index) == 1;
}
diff --git a/src/QuickCompareModel/DatabaseSchema/Enums/PermissionObjectType.cs b/src/QuickCompareModel/DatabaseSchema/Enums/PermissionObjectType.cs
index 440eeb9..ce0359c 100644
--- a/src/QuickCompareModel/DatabaseSchema/Enums/PermissionObjectType.cs
+++ b/src/QuickCompareModel/DatabaseSchema/Enums/PermissionObjectType.cs
@@ -2,35 +2,34 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema.Enums
+namespace QuickCompareModel.DatabaseSchema.Enums;
+
+///
+/// Object type that permission applies to.
+///
+public enum PermissionObjectType
{
- ///
- /// Object type that permission applies to.
- ///
- public enum PermissionObjectType
- {
- /// Unknown.
- Unknown,
+ /// Unknown.
+ Unknown,
- /// Database.
- Database,
+ /// Database.
+ Database,
- /// SQL stored procedure.
- SqlStoredProcedure,
+ /// SQL stored procedure.
+ SqlStoredProcedure,
- /// SQL function.
- SqlFunction,
+ /// SQL function.
+ SqlFunction,
- /// SQL synonym.
- Synonym,
+ /// SQL synonym.
+ Synonym,
- /// SQL user table.
- UserTable,
+ /// SQL user table.
+ UserTable,
- /// SQL system table.
- SystemTable,
+ /// SQL system table.
+ SystemTable,
- /// SQL view.
- View,
- }
+ /// SQL view.
+ View,
}
diff --git a/src/QuickCompareModel/DatabaseSchema/Enums/PropertyObjectType.cs b/src/QuickCompareModel/DatabaseSchema/Enums/PropertyObjectType.cs
index 16b2619..d0cec0f 100644
--- a/src/QuickCompareModel/DatabaseSchema/Enums/PropertyObjectType.cs
+++ b/src/QuickCompareModel/DatabaseSchema/Enums/PropertyObjectType.cs
@@ -2,29 +2,28 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema.Enums
+namespace QuickCompareModel.DatabaseSchema.Enums;
+
+///
+/// Object type that extended property applies to.
+///
+public enum PropertyObjectType
{
- ///
- /// Object type that extended property applies to.
- ///
- public enum PropertyObjectType
- {
- /// Database.
- Database,
+ /// Database.
+ Database,
- /// Routine.
- Routine,
+ /// Routine.
+ Routine,
- /// Routine column.
- RoutineColumn,
+ /// Routine column.
+ RoutineColumn,
- /// Table.
- Table,
+ /// Table.
+ Table,
- /// Table column.
- TableColumn,
+ /// Table column.
+ TableColumn,
- /// Index.
- Index,
- }
+ /// Index.
+ Index,
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SchemaNameExtensions.cs b/src/QuickCompareModel/DatabaseSchema/SchemaNameExtensions.cs
index 8e927c2..443ff8b 100644
--- a/src/QuickCompareModel/DatabaseSchema/SchemaNameExtensions.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SchemaNameExtensions.cs
@@ -2,52 +2,51 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
+namespace QuickCompareModel.DatabaseSchema;
+
+/// Extensions to derive the schema and object names from a full object ID.
+public static class SchemaNameExtensions
{
- /// Extensions to derive the schema and object names from a full object ID.
- public static class SchemaNameExtensions
+ /// Returns the schema name from a full object ID.
+ /// Full object ID.
+ /// Schema name or empty string.
+ public static string GetSchemaName(this string input)
{
- /// Returns the schema name from a full object ID.
- /// Full object ID.
- /// Schema name or empty string.
- public static string GetSchemaName(this string input)
+ if (string.IsNullOrWhiteSpace(input))
{
- if (string.IsNullOrWhiteSpace(input))
- {
- return string.Empty;
- }
-
- string[] parts = input.Split('.');
- return parts.Length != 2 ? string.Empty : parts[0].StripSquareBrackets();
+ return string.Empty;
}
- /// Returns the object name from a full object ID.
- /// Full object ID.
- /// Object name or empty string.
- public static string GetObjectName(this string input)
- {
- if (string.IsNullOrWhiteSpace(input))
- {
- return string.Empty;
- }
+ string[] parts = input.Split('.');
+ return parts.Length != 2 ? string.Empty : parts[0].StripSquareBrackets();
+ }
- string[] parts = input.Split('.');
- return parts.Length != 2 ? string.Empty : parts[1].StripSquareBrackets();
+ /// Returns the object name from a full object ID.
+ /// Full object ID.
+ /// Object name or empty string.
+ public static string GetObjectName(this string input)
+ {
+ if (string.IsNullOrWhiteSpace(input))
+ {
+ return string.Empty;
}
- /// Adds the schema name to the beginning of the string.
- /// Source object name.
- /// Schema name to prepend.
- /// A dot-delimited string containing the schema name and object name.
- public static string PrependSchemaName(this string objectName, string schemaName) =>
- string.IsNullOrEmpty(schemaName) ? objectName : $"[{schemaName}].[{objectName}]";
-
- /// / Removes instances of square bracket characters from the string.
- /// Source input.
- /// The source input without square bracket characters.
- public static string StripSquareBrackets(this string input) =>
- input
- .Replace("[", string.Empty)
- .Replace("]", string.Empty);
+ string[] parts = input.Split('.');
+ return parts.Length != 2 ? string.Empty : parts[1].StripSquareBrackets();
}
+
+ /// Adds the schema name to the beginning of the string.
+ /// Source object name.
+ /// Schema name to prepend.
+ /// A dot-delimited string containing the schema name and object name.
+ public static string PrependSchemaName(this string objectName, string schemaName) =>
+ string.IsNullOrEmpty(schemaName) ? objectName : $"[{schemaName}].[{objectName}]";
+
+ /// / Removes instances of square bracket characters from the string.
+ /// Source input.
+ /// The source input without square bracket characters.
+ public static string StripSquareBrackets(this string input) =>
+ input
+ .Replace("[", string.Empty)
+ .Replace("]", string.Empty);
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlColumnDetail.cs b/src/QuickCompareModel/DatabaseSchema/SqlColumnDetail.cs
index 00a4664..9ada10e 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlColumnDetail.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlColumnDetail.cs
@@ -2,86 +2,85 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
+namespace QuickCompareModel.DatabaseSchema;
+
+///
+/// Class representing properties of a table column.
+///
+public class SqlColumnDetail
{
- ///
- /// Class representing properties of a table column.
- ///
- public class SqlColumnDetail
- {
- /// Gets or sets the table schema.
- public string TableSchema { get; set; }
+ /// Gets or sets the table schema.
+ public string TableSchema { get; set; }
- /// Gets or sets the table name.
- public string TableName { get; set; }
+ /// Gets or sets the table name.
+ public string TableName { get; set; }
- /// Gets or sets the column name.
- public string ColumnName { get; set; }
+ /// Gets or sets the column name.
+ public string ColumnName { get; set; }
- /// Gets or sets the ordinal position.
- public int OrdinalPosition { get; set; }
+ /// Gets or sets the ordinal position.
+ public int OrdinalPosition { get; set; }
- /// Gets or sets the column default.
- public string ColumnDefault { get; set; }
+ /// Gets or sets the column default.
+ public string ColumnDefault { get; set; }
- /// Gets or sets a value indicating whether is nullable.
- public bool IsNullable { get; set; }
+ /// Gets or sets a value indicating whether is nullable.
+ public bool IsNullable { get; set; }
- /// Gets or sets the datatype.
- public string DataType { get; set; }
+ /// Gets or sets the datatype.
+ public string DataType { get; set; }
- /// Gets or sets the character maximum length.
- public int? CharacterMaximumLength { get; set; }
+ /// Gets or sets the character maximum length.
+ public int? CharacterMaximumLength { get; set; }
- /// Gets or sets the character octet length.
- public int? CharacterOctetLength { get; set; }
+ /// Gets or sets the character octet length.
+ public int? CharacterOctetLength { get; set; }
- /// Gets or sets the numeric precision.
- public int? NumericPrecision { get; set; }
+ /// Gets or sets the numeric precision.
+ public int? NumericPrecision { get; set; }
- /// Gets or sets the numeric precesion radix.
- public int? NumericPrecisionRadix { get; set; }
+ /// Gets or sets the numeric precesion radix.
+ public int? NumericPrecisionRadix { get; set; }
- /// Gets or sets the numeric scale.
- public int? NumericScale { get; set; }
+ /// Gets or sets the numeric scale.
+ public int? NumericScale { get; set; }
- /// Gets or sets the datetime precision.
- public int? DatetimePrecision { get; set; }
+ /// Gets or sets the datetime precision.
+ public int? DatetimePrecision { get; set; }
- /// Gets or sets the character set name.
- public string CharacterSetName { get; set; }
+ /// Gets or sets the character set name.
+ public string CharacterSetName { get; set; }
- /// Gets or sets the collation name.
- public string CollationName { get; set; }
+ /// Gets or sets the collation name.
+ public string CollationName { get; set; }
- /// Gets or sets the domain schema.
- public string DomainSchema { get; set; }
+ /// Gets or sets the domain schema.
+ public string DomainSchema { get; set; }
- /// Gets or sets the domain name.
- public string DomainName { get; set; }
+ /// Gets or sets the domain name.
+ public string DomainName { get; set; }
- /// Gets or sets a value indicating whether is full-text indexed.
- public bool IsFullTextIndexed { get; set; }
+ /// Gets or sets a value indicating whether is full-text indexed.
+ public bool IsFullTextIndexed { get; set; }
- /// Gets or sets a value indicating whether is computed.
- public bool IsComputed { get; set; }
+ /// Gets or sets a value indicating whether is computed.
+ public bool IsComputed { get; set; }
- /// Gets or sets a value indicating whether is identity.
- public bool IsIdentity { get; set; }
+ /// Gets or sets a value indicating whether is identity.
+ public bool IsIdentity { get; set; }
- /// Gets or sets the identity seed.
- public decimal? IdentitySeed { get; set; }
+ /// Gets or sets the identity seed.
+ public decimal? IdentitySeed { get; set; }
- /// Gets or sets the identity increment.
- public decimal? IdentityIncrement { get; set; }
+ /// Gets or sets the identity increment.
+ public decimal? IdentityIncrement { get; set; }
- /// Gets or sets a value indicating whether is sparse.
- public bool IsSparse { get; set; }
+ /// Gets or sets a value indicating whether is sparse.
+ public bool IsSparse { get; set; }
- /// Gets or sets a value indicating whether is column set.
- public bool IsColumnSet { get; set; }
+ /// Gets or sets a value indicating whether is column set.
+ public bool IsColumnSet { get; set; }
- /// Gets or sets a value indicating whether is row guid.
- public bool IsRowGuid { get; set; }
- }
+ /// Gets or sets a value indicating whether is row guid.
+ public bool IsRowGuid { get; set; }
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlDatabase.cs b/src/QuickCompareModel/DatabaseSchema/SqlDatabase.cs
index 28c66c3..435db35 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlDatabase.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlDatabase.cs
@@ -2,835 +2,831 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
+namespace QuickCompareModel.DatabaseSchema;
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.SqlClient;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using QuickCompareModel.Models;
+
+///
+/// Class for running database queries and building lists that detail the content of the database schema.
+///
+///
+/// Initialises a new instance of the class with a connection string and setting options.
+///
+/// The database connection string for the current instance being inspected.
+/// Collection of configuration settings.
+public partial class SqlDatabase(string connectionString, QuickCompareOptions options)
{
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Data.SqlClient;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
+ private readonly string connectionString = connectionString;
+ private readonly QuickCompareOptions options = options;
///
- /// Class for running database queries and building lists that detail the content of the database schema.
+ /// Initialises a new instance of the class with a connection string.
///
- public class SqlDatabase
+ /// The database connection string for the current instance being inspected.
+ public SqlDatabase(string connectionString)
+ : this(connectionString, new QuickCompareOptions())
{
- private readonly string connectionString;
- private readonly QuickCompareOptions options;
-
- ///
- /// Initialises a new instance of the class with a connection string and setting options.
- ///
- /// The database connection string for the current instance being inspected.
- /// Collection of configuration settings.
- public SqlDatabase(string connectionString, QuickCompareOptions options)
- {
- this.connectionString = connectionString;
- this.options = options;
- }
-
- ///
- /// Initialises a new instance of the class with a connection string.
- ///
- /// The database connection string for the current instance being inspected.
- public SqlDatabase(string connectionString)
- : this(connectionString, new QuickCompareOptions())
- {
- }
+ }
- /// Handler for when the status message changes.
- public event EventHandler LoaderStatusChanged;
+ /// Handler for when the status message changes.
+ public event EventHandler LoaderStatusChanged;
- ///
- /// Gets a friendly name for the database instance, including both server name and database name.
- ///
- public string FriendlyName
+ ///
+ /// Gets a friendly name for the database instance, including both server name and database name.
+ ///
+ public string FriendlyName
+ {
+ get
{
- get
- {
- var builder = new SqlConnectionStringBuilder(this.connectionString);
- return $"[{builder.DataSource}].[{builder.InitialCatalog}]";
- }
+ var builder = new SqlConnectionStringBuilder(this.connectionString);
+ return $"[{builder.DataSource}].[{builder.InitialCatalog}]";
}
+ }
- /// Gets or sets a list of instances, indexed by table name.
- public Dictionary Tables { get; set; } = new Dictionary();
+ /// Gets or sets a list of instances, indexed by table name.
+ public Dictionary Tables { get; set; } = [];
- /// Gets or sets a list of instances, indexed by name.
- public Dictionary UserTypes { get; set; } = new Dictionary();
+ /// Gets or sets a list of instances, indexed by name.
+ public Dictionary UserTypes { get; set; } = [];
- /// Gets or sets a list of database views, indexed by view name.
- public Dictionary Views { get; set; } = new Dictionary();
+ /// Gets or sets a list of database views, indexed by view name.
+ public Dictionary Views { get; set; } = [];
- /// Gets or sets a list of SQL synonyms, indexed by synonym name.
- public Dictionary Synonyms { get; set; } = new Dictionary();
+ /// Gets or sets a list of SQL synonyms, indexed by synonym name.
+ public Dictionary Synonyms { get; set; } = [];
- /// Gets or sets a list of instances, indexed by routine name.
- /// User routines include views, functions and stored procedures.
- public Dictionary UserRoutines { get; set; } = new Dictionary();
+ /// Gets or sets a list of instances, indexed by routine name.
+ /// User routines include views, functions and stored procedures.
+ public Dictionary UserRoutines { get; set; } = [];
- /// Gets or sets a list of instances, for both roles and users.
- public List Permissions { get; set; } = new List();
+ /// Gets or sets a list of instances, for both roles and users.
+ public List Permissions { get; set; } = [];
- /// Gets or sets a list of instances for the database itself.
- public List ExtendedProperties { get; set; } = new List();
+ /// Gets or sets a list of instances for the database itself.
+ public List ExtendedProperties { get; set; } = [];
- ///
- /// Helper method to return embedded SQL resource by filename.
- ///
- /// Name of the SQL file without the extension.
- /// SQL query text.
- public static string LoadQueryFromResource(string queryName)
- {
- var resourceName = $"{nameof(QuickCompareModel)}.{nameof(DatabaseSchema)}.Queries.{queryName}.sql";
- using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
- return stream != null ? StreamToString(stream) : string.Empty;
- }
+ ///
+ /// Helper method to return embedded SQL resource by filename.
+ ///
+ /// Name of the SQL file without the extension.
+ /// SQL query text.
+ public static string LoadQueryFromResource(string queryName)
+ {
+ var resourceName = $"{nameof(QuickCompareModel)}.{nameof(DatabaseSchema)}.Queries.{queryName}.sql";
+ using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
+ return stream != null ? StreamToString(stream) : string.Empty;
+ }
- ///
- /// Populate the models based on the supplied connection string.
- ///
- /// A representing the asynchronous operation.
- public async Task PopulateSchemaModelAsync()
- {
- this.RaiseStatusChanged("Connecting");
+ ///
+ /// Populate the models based on the supplied connection string.
+ ///
+ /// A representing the asynchronous operation.
+ public async Task PopulateSchemaModelAsync()
+ {
+ this.RaiseStatusChanged("Connecting");
- await this.LoadFullyQualifiedTableNamesAsync();
- await Task.WhenAll(this.RequiredItemTasks());
- await Task.WhenAll(this.DependentItemTasks());
+ await this.LoadFullyQualifiedTableNamesAsync();
+ await Task.WhenAll(this.RequiredItemTasks());
+ await Task.WhenAll(this.DependentItemTasks());
- this.RaiseStatusChanged("Done");
- }
+ this.RaiseStatusChanged("Done");
+ }
- ///
- /// Raises the status changed event.
- ///
- /// Status message.
- protected virtual void RaiseStatusChanged(string message) =>
- this.LoaderStatusChanged?.Invoke(this, new StatusChangedEventArgs(message));
+ ///
+ /// Raises the status changed event.
+ ///
+ /// Status message.
+ protected virtual void RaiseStatusChanged(string message) =>
+ this.LoaderStatusChanged?.Invoke(this, new StatusChangedEventArgs(message));
- private static string StreamToString(Stream stream)
- {
- using var reader = new StreamReader(stream);
- return reader.ReadToEnd();
- }
+ private static string StreamToString(Stream stream)
+ {
+ using var reader = new StreamReader(stream);
+ return reader.ReadToEnd();
+ }
- private static SqlIndex LoadIndex(SqlDataReader dr)
+ private static SqlIndex LoadIndex(SqlDataReader dr)
+ {
+ var index = new SqlIndex();
+ string desc;
+ var i = 0;
+ while (i < dr.FieldCount)
{
- var index = new SqlIndex();
- string desc;
- var i = 0;
- while (i < dr.FieldCount)
+ switch (dr.GetName(i))
{
- switch (dr.GetName(i))
- {
- case "index_name":
- index.IndexName = dr.GetString(i);
- break;
- case "index_keys":
- index.SetColumnsFromString(dr.GetString(i));
- break;
- case "index_description":
- desc = dr.GetString(i);
- index.IsPrimaryKey = desc.Contains("primary key");
- index.Clustered = !desc.Contains("nonclustered");
- index.Unique = desc.Contains("unique");
- index.IsUniqueKey = desc.Contains("unique key");
- index.FileGroup = Regex.Match(desc, "located on (.*)$").Groups[1].Value;
- break;
- default:
- break;
- }
-
- i++;
+ case "index_name":
+ index.IndexName = dr.GetString(i);
+ break;
+ case "index_keys":
+ index.SetColumnsFromString(dr.GetString(i));
+ break;
+ case "index_description":
+ desc = dr.GetString(i);
+ index.IsPrimaryKey = desc.Contains("primary key");
+ index.Clustered = !desc.Contains("nonclustered");
+ index.Unique = desc.Contains("unique");
+ index.IsUniqueKey = desc.Contains("unique key");
+ index.FileGroup = FileGroupRegex().Match(desc).Groups[1].Value;
+ break;
+ default:
+ break;
}
- return index;
+ i++;
}
- private static SqlRelation LoadRelation(SqlDataReader dr)
+ return index;
+ }
+
+ private static SqlRelation LoadRelation(SqlDataReader dr)
+ {
+ var relation = new SqlRelation();
+ var i = 0;
+ while (i < dr.FieldCount)
{
- var relation = new SqlRelation();
- var i = 0;
- while (i < dr.FieldCount)
+ switch (dr.GetName(i))
{
- switch (dr.GetName(i))
- {
- case "RELATION_NAME":
- relation.RelationName = dr.GetString(i);
- break;
- case "CHILD_SCHEMA":
- relation.ChildSchema = dr.GetString(i);
- break;
- case "CHILD_TABLE":
- relation.ChildTable = dr.GetString(i);
- break;
- case "CHILD_COLUMNS":
- relation.ChildColumns = dr.GetString(i);
- break;
- case "UNIQUE_CONSTRAINT_NAME":
- relation.UniqueConstraintName = dr.GetString(i);
- break;
- case "PARENT_SCHEMA":
- relation.ParentSchema = dr.GetString(i);
- break;
- case "PARENT_TABLE":
- relation.ParentTable = dr.GetString(i);
- break;
- case "PARENT_COLUMNS":
- relation.ParentColumns = dr.GetString(i);
- break;
- case "UPDATE_RULE":
- relation.UpdateRule = dr.GetString(i);
- break;
- case "DELETE_RULE":
- relation.DeleteRule = dr.GetString(i);
- break;
- default:
- break;
- }
-
- i++;
+ case "RELATION_NAME":
+ relation.RelationName = dr.GetString(i);
+ break;
+ case "CHILD_SCHEMA":
+ relation.ChildSchema = dr.GetString(i);
+ break;
+ case "CHILD_TABLE":
+ relation.ChildTable = dr.GetString(i);
+ break;
+ case "CHILD_COLUMNS":
+ relation.ChildColumns = dr.GetString(i);
+ break;
+ case "UNIQUE_CONSTRAINT_NAME":
+ relation.UniqueConstraintName = dr.GetString(i);
+ break;
+ case "PARENT_SCHEMA":
+ relation.ParentSchema = dr.GetString(i);
+ break;
+ case "PARENT_TABLE":
+ relation.ParentTable = dr.GetString(i);
+ break;
+ case "PARENT_COLUMNS":
+ relation.ParentColumns = dr.GetString(i);
+ break;
+ case "UPDATE_RULE":
+ relation.UpdateRule = dr.GetString(i);
+ break;
+ case "DELETE_RULE":
+ relation.DeleteRule = dr.GetString(i);
+ break;
+ default:
+ break;
}
- return relation;
+ i++;
}
- private static SqlColumnDetail LoadColumnDetail(SqlDataReader dr)
+ return relation;
+ }
+
+ private static SqlColumnDetail LoadColumnDetail(SqlDataReader dr)
+ {
+ var i = 0;
+ var detail = new SqlColumnDetail();
+ while (i < dr.FieldCount)
{
- var i = 0;
- var detail = new SqlColumnDetail();
- while (i < dr.FieldCount)
+ switch (dr.GetName(i))
{
- switch (dr.GetName(i))
- {
- case "TABLE_SCHEMA":
- detail.TableSchema = dr.GetString(i);
- break;
- case "TABLE_NAME":
- detail.TableName = dr.GetString(i);
- break;
- case "COLUMN_NAME":
- detail.ColumnName = dr.GetString(i);
- break;
- case "ORDINAL_POSITION":
- detail.OrdinalPosition = dr.GetInt32(i);
- break;
- case "COLUMN_DEFAULT":
- detail.ColumnDefault = dr.GetNullableString(i);
- break;
- case "IS_NULLABLE":
- detail.IsNullable = !dr.IsDBNull(i) && dr.GetString(i) == "YES";
- break;
- case "DATA_TYPE":
- detail.DataType = dr.GetString(i);
- break;
- case "CHARACTER_MAXIMUM_LENGTH":
- detail.CharacterMaximumLength = dr.GetNullableInt32(i);
- break;
- case "CHARACTER_OCTET_LENGTH":
- detail.CharacterOctetLength = dr.GetNullableInt32(i);
- break;
- case "NUMERIC_PRECISION":
- detail.NumericPrecision = dr.GetNullableByte(i);
- break;
- case "NUMERIC_PRECISION_RADIX":
- detail.NumericPrecisionRadix = dr.GetNullableInt16(i);
- break;
- case "NUMERIC_SCALE":
- detail.NumericScale = dr.GetNullableInt32(i);
- break;
- case "DATETIME_PRECISION":
- detail.DatetimePrecision = dr.GetNullableInt16(i);
- break;
- case "CHARACTER_SET_NAME":
- detail.CharacterSetName = dr.GetNullableString(i);
- break;
- case "COLLATION_NAME":
- detail.CollationName = dr.GetNullableString(i);
- break;
- case "DOMAIN_SCHEMA":
- detail.DomainSchema = dr.GetNullableString(i);
- break;
- case "DOMAIN_NAME":
- detail.DomainName = dr.GetNullableString(i);
- break;
- case "IS_FULL_TEXT_INDEXED":
- detail.IsFullTextIndexed = dr.GetNullableInt32AsBoolean(i);
- break;
- case "IS_COMPUTED":
- detail.IsComputed = dr.GetNullableInt32AsBoolean(i);
- break;
- case "IS_IDENTITY":
- detail.IsIdentity = dr.GetNullableInt32AsBoolean(i);
- break;
- case "IDENTITY_SEED":
- detail.IdentitySeed = dr.GetNullableDecimal(i);
- break;
- case "IDENTITY_INCREMENT":
- detail.IdentityIncrement = dr.GetNullableDecimal(i);
- break;
- case "IS_SPARSE":
- detail.IsSparse = dr.GetNullableInt32AsBoolean(i);
- break;
- case "IS_COLUMN_SET":
- detail.IsColumnSet = dr.GetNullableInt32AsBoolean(i);
- break;
- case "IS_ROW_GUID":
- detail.IsRowGuid = dr.GetNullableInt32AsBoolean(i);
- break;
- default:
- break;
- }
-
- i++;
+ case "TABLE_SCHEMA":
+ detail.TableSchema = dr.GetString(i);
+ break;
+ case "TABLE_NAME":
+ detail.TableName = dr.GetString(i);
+ break;
+ case "COLUMN_NAME":
+ detail.ColumnName = dr.GetString(i);
+ break;
+ case "ORDINAL_POSITION":
+ detail.OrdinalPosition = dr.GetInt32(i);
+ break;
+ case "COLUMN_DEFAULT":
+ detail.ColumnDefault = dr.GetNullableString(i);
+ break;
+ case "IS_NULLABLE":
+ detail.IsNullable = !dr.IsDBNull(i) && dr.GetString(i) == "YES";
+ break;
+ case "DATA_TYPE":
+ detail.DataType = dr.GetString(i);
+ break;
+ case "CHARACTER_MAXIMUM_LENGTH":
+ detail.CharacterMaximumLength = dr.GetNullableInt32(i);
+ break;
+ case "CHARACTER_OCTET_LENGTH":
+ detail.CharacterOctetLength = dr.GetNullableInt32(i);
+ break;
+ case "NUMERIC_PRECISION":
+ detail.NumericPrecision = dr.GetNullableByte(i);
+ break;
+ case "NUMERIC_PRECISION_RADIX":
+ detail.NumericPrecisionRadix = dr.GetNullableInt16(i);
+ break;
+ case "NUMERIC_SCALE":
+ detail.NumericScale = dr.GetNullableInt32(i);
+ break;
+ case "DATETIME_PRECISION":
+ detail.DatetimePrecision = dr.GetNullableInt16(i);
+ break;
+ case "CHARACTER_SET_NAME":
+ detail.CharacterSetName = dr.GetNullableString(i);
+ break;
+ case "COLLATION_NAME":
+ detail.CollationName = dr.GetNullableString(i);
+ break;
+ case "DOMAIN_SCHEMA":
+ detail.DomainSchema = dr.GetNullableString(i);
+ break;
+ case "DOMAIN_NAME":
+ detail.DomainName = dr.GetNullableString(i);
+ break;
+ case "IS_FULL_TEXT_INDEXED":
+ detail.IsFullTextIndexed = dr.GetNullableInt32AsBoolean(i);
+ break;
+ case "IS_COMPUTED":
+ detail.IsComputed = dr.GetNullableInt32AsBoolean(i);
+ break;
+ case "IS_IDENTITY":
+ detail.IsIdentity = dr.GetNullableInt32AsBoolean(i);
+ break;
+ case "IDENTITY_SEED":
+ detail.IdentitySeed = dr.GetNullableDecimal(i);
+ break;
+ case "IDENTITY_INCREMENT":
+ detail.IdentityIncrement = dr.GetNullableDecimal(i);
+ break;
+ case "IS_SPARSE":
+ detail.IsSparse = dr.GetNullableInt32AsBoolean(i);
+ break;
+ case "IS_COLUMN_SET":
+ detail.IsColumnSet = dr.GetNullableInt32AsBoolean(i);
+ break;
+ case "IS_ROW_GUID":
+ detail.IsRowGuid = dr.GetNullableInt32AsBoolean(i);
+ break;
+ default:
+ break;
}
- return detail;
+ i++;
}
- private static SqlUserType LoadUserType(SqlDataReader dr)
+ return detail;
+ }
+
+ private static SqlUserType LoadUserType(SqlDataReader dr)
+ {
+ var i = 0;
+ var userType = new SqlUserType();
+ while (i < dr.FieldCount)
{
- var i = 0;
- var userType = new SqlUserType();
- while (i < dr.FieldCount)
+ switch (dr.GetName(i))
{
- switch (dr.GetName(i))
- {
- case "custom_type_name":
- userType.CustomTypeName = dr.GetString(i);
- break;
- case "schema_name":
- userType.SchemaName = dr.GetString(i);
- break;
- case "underlying_type_name":
- userType.UnderlyingTypeName = dr.GetString(i);
- break;
- case "precision":
- userType.Precision = dr.GetNullableInt32(i);
- break;
- case "scale":
- userType.Scale = dr.GetNullableInt32(i);
- break;
- case "max_length":
- userType.MaxLength = dr.GetNullableInt32(i);
- break;
- case "is_nullable":
- userType.IsNullable = dr.GetInt32AsBoolean(i);
- break;
- case "collation_name":
- userType.CollationName = dr.GetNullableString(i);
- break;
- case "is_assembly_type":
- userType.IsAssemblyType = dr.GetInt32AsBoolean(i);
- break;
- default:
- break;
- }
-
- i++;
+ case "custom_type_name":
+ userType.CustomTypeName = dr.GetString(i);
+ break;
+ case "schema_name":
+ userType.SchemaName = dr.GetString(i);
+ break;
+ case "underlying_type_name":
+ userType.UnderlyingTypeName = dr.GetString(i);
+ break;
+ case "precision":
+ userType.Precision = dr.GetNullableInt32(i);
+ break;
+ case "scale":
+ userType.Scale = dr.GetNullableInt32(i);
+ break;
+ case "max_length":
+ userType.MaxLength = dr.GetNullableInt32(i);
+ break;
+ case "is_nullable":
+ userType.IsNullable = dr.GetInt32AsBoolean(i);
+ break;
+ case "collation_name":
+ userType.CollationName = dr.GetNullableString(i);
+ break;
+ case "is_assembly_type":
+ userType.IsAssemblyType = dr.GetInt32AsBoolean(i);
+ break;
+ default:
+ break;
}
- return userType;
+ i++;
}
- private static SqlPermission LoadPermission(SqlDataReader dr)
+ return userType;
+ }
+
+ private static SqlPermission LoadPermission(SqlDataReader dr)
+ {
+ var i = 0;
+ var permission = new SqlPermission();
+ while (i < dr.FieldCount)
{
- var i = 0;
- var permission = new SqlPermission();
- while (i < dr.FieldCount)
+ switch (dr.GetName(i))
{
- switch (dr.GetName(i))
- {
- case "USER_NAME":
- permission.UserName = dr.GetString(i);
- break;
- case "ROLE_NAME":
- permission.RoleName = dr.GetNullableString(i);
- break;
- case "PERMISSION_TYPE":
- permission.PermissionType = dr.GetNullableString(i);
- break;
- case "PERMISSION_STATE":
- permission.PermissionState = dr.GetNullableString(i);
- break;
- case "OBJECT_TYPE":
- permission.ObjectType = dr.GetNullableString(i);
- break;
- case "OBJECT_NAME":
- permission.ObjectName = dr.GetNullableString(i);
- break;
- case "COLUMN_NAME":
- permission.ColumnName = dr.GetNullableString(i);
- break;
- case "OBJECT_SCHEMA":
- permission.ObjectSchema = dr.GetNullableString(i);
- break;
- default:
- break;
- }
-
- i++;
+ case "USER_NAME":
+ permission.UserName = dr.GetString(i);
+ break;
+ case "ROLE_NAME":
+ permission.RoleName = dr.GetNullableString(i);
+ break;
+ case "PERMISSION_TYPE":
+ permission.PermissionType = dr.GetNullableString(i);
+ break;
+ case "PERMISSION_STATE":
+ permission.PermissionState = dr.GetNullableString(i);
+ break;
+ case "OBJECT_TYPE":
+ permission.ObjectType = dr.GetNullableString(i);
+ break;
+ case "OBJECT_NAME":
+ permission.ObjectName = dr.GetNullableString(i);
+ break;
+ case "COLUMN_NAME":
+ permission.ColumnName = dr.GetNullableString(i);
+ break;
+ case "OBJECT_SCHEMA":
+ permission.ObjectSchema = dr.GetNullableString(i);
+ break;
+ default:
+ break;
}
- return permission;
+ i++;
}
- private static SqlExtendedProperty LoadExtendedProperty(SqlDataReader dr)
+ return permission;
+ }
+
+ private static SqlExtendedProperty LoadExtendedProperty(SqlDataReader dr)
+ {
+ var i = 0;
+ var property = new SqlExtendedProperty();
+ while (i < dr.FieldCount)
{
- var i = 0;
- var property = new SqlExtendedProperty();
- while (i < dr.FieldCount)
+ switch (dr.GetName(i))
{
- switch (dr.GetName(i))
- {
- case "PROPERTY_TYPE":
- property.PropertyType = dr.GetString(i);
- break;
- case "OBJECT_NAME":
- property.ObjectName = dr.GetNullableString(i);
- break;
- case "OBJECT_SCHEMA":
- property.ObjectSchema = dr.GetNullableString(i);
- break;
- case "COLUMN_NAME":
- property.ColumnName = dr.GetNullableString(i);
- break;
- case "PROPERTY_NAME":
- property.PropertyName = dr.GetString(i);
- break;
- case "PROPERTY_VALUE":
- property.PropertyValue = dr.GetNullableString(i);
- break;
- case "INDEX_NAME":
- property.IndexName = dr.GetNullableString(i);
- break;
- case "TABLE_NAME":
- property.TableName = dr.GetNullableString(i);
- break;
- case "TABLE_SCHEMA":
- property.TableSchema = dr.GetNullableString(i);
- break;
- default:
- break;
- }
-
- i++;
+ case "PROPERTY_TYPE":
+ property.PropertyType = dr.GetString(i);
+ break;
+ case "OBJECT_NAME":
+ property.ObjectName = dr.GetNullableString(i);
+ break;
+ case "OBJECT_SCHEMA":
+ property.ObjectSchema = dr.GetNullableString(i);
+ break;
+ case "COLUMN_NAME":
+ property.ColumnName = dr.GetNullableString(i);
+ break;
+ case "PROPERTY_NAME":
+ property.PropertyName = dr.GetString(i);
+ break;
+ case "PROPERTY_VALUE":
+ property.PropertyValue = dr.GetNullableString(i);
+ break;
+ case "INDEX_NAME":
+ property.IndexName = dr.GetNullableString(i);
+ break;
+ case "TABLE_NAME":
+ property.TableName = dr.GetNullableString(i);
+ break;
+ case "TABLE_SCHEMA":
+ property.TableSchema = dr.GetNullableString(i);
+ break;
+ default:
+ break;
}
- return property;
+ i++;
}
- private static SqlTrigger LoadTrigger(SqlDataReader dr)
+ return property;
+ }
+
+ private static SqlTrigger LoadTrigger(SqlDataReader dr)
+ {
+ var i = 0;
+ var trigger = new SqlTrigger();
+ while (i < dr.FieldCount)
{
- var i = 0;
- var trigger = new SqlTrigger();
- while (i < dr.FieldCount)
+ switch (dr.GetName(i))
{
- switch (dr.GetName(i))
- {
- case "TRIGGER_NAME":
- trigger.TriggerName = dr.GetString(i);
- break;
- case "TRIGGER_OWNER":
- trigger.TriggerOwner = dr.GetNullableString(i);
- break;
- case "TABLE_SCHEMA":
- trigger.TableSchema = dr.GetNullableString(i);
- break;
- case "TABLE_NAME":
- trigger.TableName = dr.GetNullableString(i);
- break;
- case "IS_UPDATE":
- trigger.IsUpdate = dr.GetInt32AsBoolean(i);
- break;
- case "IS_DELETE":
- trigger.IsDelete = dr.GetInt32AsBoolean(i);
- break;
- case "IS_INSERT":
- trigger.IsInsert = dr.GetInt32AsBoolean(i);
- break;
- case "IS_AFTER":
- trigger.IsAfter = dr.GetInt32AsBoolean(i);
- break;
- case "IS_INSTEAD_OF":
- trigger.IsInsteadOf = dr.GetInt32AsBoolean(i);
- break;
- case "IS_DISABLED":
- trigger.IsDisabled = dr.GetInt32AsBoolean(i);
- break;
- case "TRIGGER_CONTENT":
- trigger.TriggerContent = dr.GetString(i);
- break;
- default:
- break;
- }
-
- i++;
+ case "TRIGGER_NAME":
+ trigger.TriggerName = dr.GetString(i);
+ break;
+ case "TRIGGER_OWNER":
+ trigger.TriggerOwner = dr.GetNullableString(i);
+ break;
+ case "TABLE_SCHEMA":
+ trigger.TableSchema = dr.GetNullableString(i);
+ break;
+ case "TABLE_NAME":
+ trigger.TableName = dr.GetNullableString(i);
+ break;
+ case "IS_UPDATE":
+ trigger.IsUpdate = dr.GetInt32AsBoolean(i);
+ break;
+ case "IS_DELETE":
+ trigger.IsDelete = dr.GetInt32AsBoolean(i);
+ break;
+ case "IS_INSERT":
+ trigger.IsInsert = dr.GetInt32AsBoolean(i);
+ break;
+ case "IS_AFTER":
+ trigger.IsAfter = dr.GetInt32AsBoolean(i);
+ break;
+ case "IS_INSTEAD_OF":
+ trigger.IsInsteadOf = dr.GetInt32AsBoolean(i);
+ break;
+ case "IS_DISABLED":
+ trigger.IsDisabled = dr.GetInt32AsBoolean(i);
+ break;
+ case "TRIGGER_CONTENT":
+ trigger.TriggerContent = dr.GetString(i);
+ break;
+ default:
+ break;
}
- return trigger;
+ i++;
}
- private Task[] RequiredItemTasks()
- {
- var tasks = new List() { this.LoadRelationsAsync(), this.LoadColumnDetailsAsync() };
+ return trigger;
+ }
- if (this.options.CompareUserTypes)
- {
- tasks.Add(this.LoadUserTypesAsync());
- }
+ [GeneratedRegex("located on (.*)$")] private static partial Regex FileGroupRegex();
- if (this.options.ComparePermissions)
- {
- tasks.AddRange(new Task[] { this.LoadRolePermissionsAsync(), this.LoadUserPermissionsAsync() });
- }
+ private Task[] RequiredItemTasks()
+ {
+ var tasks = new List() { this.LoadRelationsAsync(), this.LoadColumnDetailsAsync() };
- if (this.options.CompareProperties)
- {
- tasks.Add(this.LoadExtendedPropertiesAsync());
- }
+ if (this.options.CompareUserTypes)
+ {
+ tasks.Add(this.LoadUserTypesAsync());
+ }
- if (this.options.CompareTriggers)
- {
- tasks.Add(this.LoadTriggersAsync());
- }
+ if (this.options.ComparePermissions)
+ {
+ tasks.AddRange(new Task[] { this.LoadRolePermissionsAsync(), this.LoadUserPermissionsAsync() });
+ }
- if (this.options.CompareSynonyms)
- {
- tasks.Add(this.LoadSynonymsAsync());
- }
+ if (this.options.CompareProperties)
+ {
+ tasks.Add(this.LoadExtendedPropertiesAsync());
+ }
- if (this.options.CompareObjects)
- {
- tasks.AddRange(new Task[] { this.LoadViewsAsync(), this.LoadUserRoutinesAsync(), this.LoadUserRoutineDefinitionsAsync() });
- }
+ if (this.options.CompareTriggers)
+ {
+ tasks.Add(this.LoadTriggersAsync());
+ }
- if (this.options.CompareIndexes)
- {
- foreach (var fullyQualifiedTableName in this.Tables.Keys)
- {
- tasks.Add(this.LoadIndexesAsync(fullyQualifiedTableName));
- }
- }
+ if (this.options.CompareSynonyms)
+ {
+ tasks.Add(this.LoadSynonymsAsync());
+ }
- return tasks.ToArray();
+ if (this.options.CompareObjects)
+ {
+ tasks.AddRange(new Task[] { this.LoadViewsAsync(), this.LoadUserRoutinesAsync(), this.LoadUserRoutineDefinitionsAsync() });
}
- private Task[] DependentItemTasks()
+ if (this.options.CompareIndexes)
{
- var tasks = new List();
- if (this.options.CompareObjects)
+ foreach (var fullyQualifiedTableName in this.Tables.Keys)
{
- tasks.Add(this.LoadUserRoutineDefinitionsAsync());
+ tasks.Add(this.LoadIndexesAsync(fullyQualifiedTableName));
}
+ }
+
+ return [.. tasks];
+ }
+
+ private Task[] DependentItemTasks()
+ {
+ var tasks = new List();
+ if (this.options.CompareObjects)
+ {
+ tasks.Add(this.LoadUserRoutineDefinitionsAsync());
+ }
- if (this.options.CompareIndexes)
+ if (this.options.CompareIndexes)
+ {
+ foreach (var fullyQualifiedTableName in this.Tables.Keys)
{
- foreach (var fullyQualifiedTableName in this.Tables.Keys)
+ foreach (var index in this.Tables[fullyQualifiedTableName].Indexes)
{
- foreach (var index in this.Tables[fullyQualifiedTableName].Indexes)
- {
- tasks.Add(this.LoadIncludedColumnsForIndexAsync(index));
- }
+ tasks.Add(this.LoadIncludedColumnsForIndexAsync(index));
}
}
-
- return tasks.ToArray();
}
- private async Task LoadFullyQualifiedTableNamesAsync()
+ return tasks.ToArray();
+ }
+
+ private async Task LoadFullyQualifiedTableNamesAsync()
+ {
+ this.RaiseStatusChanged("Reading tables");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("TableNames"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading tables");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("TableNames"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
- {
- this.Tables.Add($"[{dr.GetString(0)}].[{dr.GetString(1)}]", new SqlTable());
- }
+ this.Tables.Add($"[{dr.GetString(0)}].[{dr.GetString(1)}]", new SqlTable());
}
+ }
- private async Task LoadIndexesAsync(string fullyQualifiedTableName)
+ private async Task LoadIndexesAsync(string fullyQualifiedTableName)
+ {
+ this.RaiseStatusChanged($"Reading indexes for table {fullyQualifiedTableName}");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand("sp_helpindex", connection);
+ command.CommandType = CommandType.StoredProcedure;
+ command.Parameters.AddWithValue("@objname", fullyQualifiedTableName);
+
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged($"Reading indexes for table {fullyQualifiedTableName}");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand("sp_helpindex", connection);
- command.CommandType = CommandType.StoredProcedure;
- command.Parameters.AddWithValue("@objname", fullyQualifiedTableName);
+ var index = LoadIndex(dr);
+ index.TableSchema = fullyQualifiedTableName.GetSchemaName();
+ index.TableName = fullyQualifiedTableName.GetObjectName();
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
- {
- var index = LoadIndex(dr);
- index.TableSchema = fullyQualifiedTableName.GetSchemaName();
- index.TableName = fullyQualifiedTableName.GetObjectName();
+ this.Tables[fullyQualifiedTableName].Indexes.Add(index);
+ }
+ }
- this.Tables[fullyQualifiedTableName].Indexes.Add(index);
+ private async Task LoadIncludedColumnsForIndexAsync(SqlIndex index)
+ {
+ this.RaiseStatusChanged($"Reading index included columns for {index.IndexName}");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("IncludedColumnsForIndex"), connection);
+ command.Parameters.AddWithValue("@TableName", index.TableName);
+ command.Parameters.AddWithValue("@IndexName", index.IndexName);
+ command.Parameters.AddWithValue("@TableSchema", index.TableSchema);
+
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
+ {
+ if (dr.GetBoolean(3))
+ {
+ index.IncludedColumns.Add(dr.GetString(1), dr.GetBoolean(2));
}
}
+ }
- private async Task LoadIncludedColumnsForIndexAsync(SqlIndex index)
+ private async Task LoadRelationsAsync()
+ {
+ this.RaiseStatusChanged("Reading relations");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("Relations"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged($"Reading index included columns for {index.IndexName}");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("IncludedColumnsForIndex"), connection);
- command.Parameters.AddWithValue("@TableName", index.TableName);
- command.Parameters.AddWithValue("@IndexName", index.IndexName);
- command.Parameters.AddWithValue("@TableSchema", index.TableSchema);
+ var relation = LoadRelation(dr);
+ var fullyQualifiedChildTable = relation.ChildTable.PrependSchemaName(relation.ChildSchema);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
+ if (this.Tables.TryGetValue(fullyQualifiedChildTable, out var table))
{
- if (dr.GetBoolean(3))
- {
- index.IncludedColumns.Add(dr.GetString(1), dr.GetBoolean(2));
- }
+ table.Relations.Add(relation);
}
}
+ }
- private async Task LoadRelationsAsync()
+ private async Task LoadColumnDetailsAsync()
+ {
+ this.RaiseStatusChanged("Reading column details");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("ColumnDetails"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading relations");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("Relations"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
- {
- var relation = LoadRelation(dr);
- var fullyQualifiedChildTable = relation.ChildTable.PrependSchemaName(relation.ChildSchema);
+ var detail = LoadColumnDetail(dr);
+ var fullyQualifiedTableName = detail.TableName.PrependSchemaName(detail.TableSchema);
- if (this.Tables.TryGetValue(fullyQualifiedChildTable, out var table))
- {
- table.Relations.Add(relation);
- }
+ if (this.Tables.TryGetValue(fullyQualifiedTableName, out var table))
+ {
+ table.ColumnDetails.Add(detail);
}
}
+ }
- private async Task LoadColumnDetailsAsync()
+ private async Task LoadUserTypesAsync()
+ {
+ this.RaiseStatusChanged("Reading user types");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("UserTypes"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading column details");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("ColumnDetails"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
- {
- var detail = LoadColumnDetail(dr);
- var fullyQualifiedTableName = detail.TableName.PrependSchemaName(detail.TableSchema);
-
- if (this.Tables.TryGetValue(fullyQualifiedTableName, out var table))
- {
- table.ColumnDetails.Add(detail);
- }
- }
+ var userType = LoadUserType(dr);
+ this.UserTypes.Add(userType.CustomTypeName.PrependSchemaName(userType.SchemaName), userType);
}
+ }
- private async Task LoadUserTypesAsync()
+ private async Task LoadRolePermissionsAsync()
+ {
+ this.RaiseStatusChanged("Reading role permissions");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("RolePermissions"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading user types");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("UserTypes"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
- {
- var userType = LoadUserType(dr);
- this.UserTypes.Add(userType.CustomTypeName.PrependSchemaName(userType.SchemaName), userType);
- }
+ this.Permissions.Add(LoadPermission(dr));
}
+ }
- private async Task LoadRolePermissionsAsync()
+ private async Task LoadUserPermissionsAsync()
+ {
+ this.RaiseStatusChanged("Reading user permissions");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("UserPermissions"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading role permissions");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("RolePermissions"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
- {
- this.Permissions.Add(LoadPermission(dr));
- }
+ this.Permissions.Add(LoadPermission(dr));
}
+ }
- private async Task LoadUserPermissionsAsync()
+ private async Task LoadExtendedPropertiesAsync()
+ {
+ this.RaiseStatusChanged("Reading extended properties");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("ExtendedProperties"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading user permissions");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("UserPermissions"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
- {
- this.Permissions.Add(LoadPermission(dr));
- }
+ this.ExtendedProperties.Add(LoadExtendedProperty(dr));
}
+ }
- private async Task LoadExtendedPropertiesAsync()
+ private async Task LoadTriggersAsync()
+ {
+ this.RaiseStatusChanged("Reading triggers");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("Triggers"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading extended properties");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("ExtendedProperties"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
+ var trigger = LoadTrigger(dr);
+ var fullyQualifiedTableName = trigger.TableName.PrependSchemaName(trigger.TableSchema);
+
+ if (this.Tables.TryGetValue(fullyQualifiedTableName, out var table))
{
- this.ExtendedProperties.Add(LoadExtendedProperty(dr));
+ table.Triggers.Add(trigger);
}
}
+ }
- private async Task LoadTriggersAsync()
+ private async Task LoadSynonymsAsync()
+ {
+ this.RaiseStatusChanged("Reading synonyms");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("Synonyms"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading triggers");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("Triggers"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
+ var i = 0;
+ var name = string.Empty;
+ var def = string.Empty;
+ while (i < dr.FieldCount)
{
- var trigger = LoadTrigger(dr);
- var fullyQualifiedTableName = trigger.TableName.PrependSchemaName(trigger.TableSchema);
-
- if (this.Tables.TryGetValue(fullyQualifiedTableName, out var table))
+ switch (dr.GetName(i))
{
- table.Triggers.Add(trigger);
+ case "SYNONYM_NAME":
+ name = dr.GetString(i);
+ break;
+ case "BASE_OBJECT_NAME":
+ def = dr.GetString(i);
+ break;
}
+
+ i++;
}
+
+ this.Synonyms.Add(name, def);
}
+ }
- private async Task LoadSynonymsAsync()
+ private async Task LoadViewsAsync()
+ {
+ this.RaiseStatusChanged("Reading views");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("Views"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading synonyms");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("Synonyms"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
+ var i = 0;
+ var name = string.Empty;
+ var schema = string.Empty;
+ var def = string.Empty;
+ while (i < dr.FieldCount)
{
- var i = 0;
- var name = string.Empty;
- var def = string.Empty;
- while (i < dr.FieldCount)
+ switch (dr.GetName(i))
{
- switch (dr.GetName(i))
- {
- case "SYNONYM_NAME":
- name = dr.GetString(i);
- break;
- case "BASE_OBJECT_NAME":
- def = dr.GetString(i);
- break;
- }
-
- i++;
+ case "VIEW_NAME":
+ name = dr.GetString(i);
+ break;
+ case "TABLE_SCHEMA":
+ schema = dr.GetString(i);
+ break;
+ case "VIEW_DEFINITION":
+ def = dr.GetString(i);
+ break;
}
- this.Synonyms.Add(name, def);
+ i++;
}
+
+ this.Views.Add(name.PrependSchemaName(schema), def);
}
+ }
- private async Task LoadViewsAsync()
+ private async Task LoadUserRoutinesAsync()
+ {
+ this.RaiseStatusChanged("Reading user routines");
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("UserRoutines"), connection);
+ await connection.OpenAsync();
+ using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
+ while (await dr.ReadAsync())
{
- this.RaiseStatusChanged("Reading views");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("Views"), connection);
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
+ var routine = new SqlUserRoutine();
+ var name = string.Empty;
+ var schema = string.Empty;
+ var i = 0;
+ while (i < dr.FieldCount)
{
- var i = 0;
- var name = string.Empty;
- var schema = string.Empty;
- var def = string.Empty;
- while (i < dr.FieldCount)
+ switch (dr.GetName(i))
{
- switch (dr.GetName(i))
- {
- case "VIEW_NAME":
- name = dr.GetString(i);
- break;
- case "TABLE_SCHEMA":
- schema = dr.GetString(i);
- break;
- case "VIEW_DEFINITION":
- def = dr.GetString(i);
- break;
- }
-
- i++;
+ case "ROUTINE_NAME":
+ name = dr.GetString(i);
+ break;
+ case "ROUTINE_SCHEMA":
+ schema = dr.GetString(i);
+ break;
+ case "ROUTINE_TYPE":
+ routine.RoutineType = dr.GetString(i);
+ break;
+ default:
+ break;
}
- this.Views.Add(name.PrependSchemaName(schema), def);
+ i++;
}
+
+ this.UserRoutines.Add(name.PrependSchemaName(schema), routine);
}
+ }
- private async Task LoadUserRoutinesAsync()
+ private async Task LoadUserRoutineDefinitionsAsync()
+ {
+ using var connection = new SqlConnection(this.connectionString);
+ using var command = new SqlCommand(LoadQueryFromResource("UserRoutineDefinitions"), connection);
+ command.Parameters.Add("@routinename", SqlDbType.VarChar, 128);
+ var sb = new StringBuilder();
+ foreach (var routine in this.UserRoutines.Keys)
{
- this.RaiseStatusChanged("Reading user routines");
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("UserRoutines"), connection);
+ this.RaiseStatusChanged($"Reading routine definition {Array.IndexOf([.. this.UserRoutines.Keys], routine) + 1} of {this.UserRoutines.Count}");
+
+ command.Parameters["@routinename"].Value = routine.GetObjectName();
await connection.OpenAsync();
using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
while (await dr.ReadAsync())
{
- var routine = new SqlUserRoutine();
- var name = string.Empty;
- var schema = string.Empty;
- var i = 0;
- while (i < dr.FieldCount)
- {
- switch (dr.GetName(i))
- {
- case "ROUTINE_NAME":
- name = dr.GetString(i);
- break;
- case "ROUTINE_SCHEMA":
- schema = dr.GetString(i);
- break;
- case "ROUTINE_TYPE":
- routine.RoutineType = dr.GetString(i);
- break;
- default:
- break;
- }
-
- i++;
- }
-
- this.UserRoutines.Add(name.PrependSchemaName(schema), routine);
+ sb.Append(dr.GetString(0));
}
- }
- private async Task LoadUserRoutineDefinitionsAsync()
- {
- using var connection = new SqlConnection(this.connectionString);
- using var command = new SqlCommand(LoadQueryFromResource("UserRoutineDefinitions"), connection);
- command.Parameters.Add("@routinename", SqlDbType.VarChar, 128);
- var sb = new StringBuilder();
- foreach (var routine in this.UserRoutines.Keys)
- {
- this.RaiseStatusChanged($"Reading routine definition {Array.IndexOf(this.UserRoutines.Keys.ToArray(), routine) + 1} of {this.UserRoutines.Count}");
-
- command.Parameters["@routinename"].Value = routine.GetObjectName();
- await connection.OpenAsync();
- using var dr = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
- while (await dr.ReadAsync())
- {
- sb.Append(dr.GetString(0));
- }
-
- this.UserRoutines[routine].RoutineDefinition = sb.ToString();
- sb.Clear();
- }
+ this.UserRoutines[routine].RoutineDefinition = sb.ToString();
+ sb.Clear();
}
}
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlExtendedProperty.cs b/src/QuickCompareModel/DatabaseSchema/SqlExtendedProperty.cs
index 82c8708..a5ebb52 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlExtendedProperty.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlExtendedProperty.cs
@@ -2,56 +2,55 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
+namespace QuickCompareModel.DatabaseSchema;
+
+using QuickCompareModel.DatabaseSchema.Enums;
+
+///
+/// Class representing SQL extended property.
+///
+public class SqlExtendedProperty
{
- using QuickCompareModel.DatabaseSchema.Enums;
-
- ///
- /// Class representing SQL extended property.
- ///
- public class SqlExtendedProperty
- {
- /// Gets or sets the property type.
- public string PropertyType { get; set; }
-
- /// Gets or sets the object name.
- public string ObjectName { get; set; }
-
- /// Gets or sets the object schema.
- public string ObjectSchema { get; set; }
-
- /// Gets or sets the column name.
- public string ColumnName { get; set; }
-
- /// Gets or sets the property name.
- public string PropertyName { get; set; }
-
- /// Gets or sets the property value.
- public string PropertyValue { get; set; }
-
- /// Gets or sets the table name.
- public string TableName { get; set; }
-
- /// Gets or sets the index name.
- public string IndexName { get; set; }
-
- /// Gets or sets the table schema.
- public string TableSchema { get; set; }
-
- /// Gets the full ID.
- public string FullId => !string.IsNullOrEmpty(this.ObjectName)
- ? string.IsNullOrEmpty(this.ColumnName)
- ? $"[{this.ObjectName}].[{this.PropertyName}].[{this.Type}]"
- : $"[{this.ObjectName}].[{this.PropertyName}].[{this.ColumnName}].[{this.Type}]"
- : this.PropertyName;
-
- /// Gets the target .
- public PropertyObjectType Type => this.PropertyType != "INDEX"
- ? !string.IsNullOrEmpty(this.TableName)
- ? string.IsNullOrEmpty(this.ColumnName) ? PropertyObjectType.Table : PropertyObjectType.TableColumn
- : this.PropertyType != "DATABASE"
- ? string.IsNullOrEmpty(this.ColumnName) ? PropertyObjectType.Routine : PropertyObjectType.RoutineColumn
- : PropertyObjectType.Database
- : PropertyObjectType.Index;
- }
+ /// Gets or sets the property type.
+ public string PropertyType { get; set; }
+
+ /// Gets or sets the object name.
+ public string ObjectName { get; set; }
+
+ /// Gets or sets the object schema.
+ public string ObjectSchema { get; set; }
+
+ /// Gets or sets the column name.
+ public string ColumnName { get; set; }
+
+ /// Gets or sets the property name.
+ public string PropertyName { get; set; }
+
+ /// Gets or sets the property value.
+ public string PropertyValue { get; set; }
+
+ /// Gets or sets the table name.
+ public string TableName { get; set; }
+
+ /// Gets or sets the index name.
+ public string IndexName { get; set; }
+
+ /// Gets or sets the table schema.
+ public string TableSchema { get; set; }
+
+ /// Gets the full ID.
+ public string FullId => !string.IsNullOrEmpty(this.ObjectName)
+ ? string.IsNullOrEmpty(this.ColumnName)
+ ? $"[{this.ObjectName}].[{this.PropertyName}].[{this.Type}]"
+ : $"[{this.ObjectName}].[{this.PropertyName}].[{this.ColumnName}].[{this.Type}]"
+ : this.PropertyName;
+
+ /// Gets the target .
+ public PropertyObjectType Type => this.PropertyType != "INDEX"
+ ? !string.IsNullOrEmpty(this.TableName)
+ ? string.IsNullOrEmpty(this.ColumnName) ? PropertyObjectType.Table : PropertyObjectType.TableColumn
+ : this.PropertyType != "DATABASE"
+ ? string.IsNullOrEmpty(this.ColumnName) ? PropertyObjectType.Routine : PropertyObjectType.RoutineColumn
+ : PropertyObjectType.Database
+ : PropertyObjectType.Index;
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlIndex.cs b/src/QuickCompareModel/DatabaseSchema/SqlIndex.cs
index b6ba5d6..a9239ca 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlIndex.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlIndex.cs
@@ -2,93 +2,92 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
-{
- using System.Collections.Generic;
- using System.Text;
+namespace QuickCompareModel.DatabaseSchema;
- ///
- /// Class to represent an index in the database.
- ///
- public class SqlIndex
- {
- /// Gets or sets a value indicating whether is primary key.
- public bool IsPrimaryKey { get; set; }
+using System.Collections.Generic;
+using System.Text;
- /// Gets or sets the table schema.
- public string TableSchema { get; set; }
+///
+/// Class to represent an index in the database.
+///
+public class SqlIndex
+{
+ /// Gets or sets a value indicating whether is primary key.
+ public bool IsPrimaryKey { get; set; }
- /// Gets or sets the table name.
- public string TableName { get; set; }
+ /// Gets or sets the table schema.
+ public string TableSchema { get; set; }
- /// Gets or sets the index name.
- public string IndexName { get; set; }
+ /// Gets or sets the table name.
+ public string TableName { get; set; }
- /// Gets or sets a value indicating whether is clustered.
- public bool Clustered { get; set; }
+ /// Gets or sets the index name.
+ public string IndexName { get; set; }
- /// Gets or sets a value indicating whether is unique.
- public bool Unique { get; set; }
+ /// Gets or sets a value indicating whether is clustered.
+ public bool Clustered { get; set; }
- /// Gets or sets a value indicating whether is unique key.
- public bool IsUniqueKey { get; set; }
+ /// Gets or sets a value indicating whether is unique.
+ public bool Unique { get; set; }
- /// Gets or sets the index columns.
- public Dictionary> IndexColumns { get; set; }
+ /// Gets or sets a value indicating whether is unique key.
+ public bool IsUniqueKey { get; set; }
- /// Gets or sets the file group.
- public string FileGroup { get; set; }
+ /// Gets or sets the index columns.
+ public Dictionary> IndexColumns { get; set; }
- /// Gets or sets the columns.
- public Dictionary Columns { get; set; } = new Dictionary();
+ /// Gets or sets the file group.
+ public string FileGroup { get; set; }
- /// Gets or sets the included columns.
- public Dictionary IncludedColumns { get; set; } = new Dictionary();
+ /// Gets or sets the columns.
+ public Dictionary Columns { get; set; } = [];
- /// Gets the full ID.
- public string FullId => $"[{this.TableSchema}].[{this.TableName}].[{this.IndexName}]";
+ /// Gets or sets the included columns.
+ public Dictionary IncludedColumns { get; set; } = [];
- /// Gets the columns as a string.
- public string ColumnsToString => FlagListToString(this.Columns);
+ /// Gets the full ID.
+ public string FullId => $"[{this.TableSchema}].[{this.TableName}].[{this.IndexName}]";
- /// Gets the included columns as a string.
- public string IncludedColumnsToString => FlagListToString(this.IncludedColumns);
+ /// Gets the columns as a string.
+ public string ColumnsToString => FlagListToString(this.Columns);
- /// Gets the item type.
- public string ItemType => !this.IsPrimaryKey ? this.IsUniqueKey ? "Unique key" : "Index" : "Primary key";
+ /// Gets the included columns as a string.
+ public string IncludedColumnsToString => FlagListToString(this.IncludedColumns);
- /// Sets the columns value from a given string.
- /// Comma-separated list of column names.
- public void SetColumnsFromString(string value)
- {
- var columnNames = value.Split(',');
- foreach (var columnName in columnNames)
- {
- if (columnName.Contains("(-)"))
- {
- this.Columns.Add(columnName.Replace("(-)", string.Empty).Trim(), false);
- }
- else
- {
- this.Columns.Add(columnName.Trim(), true);
- }
- }
- }
+ /// Gets the item type.
+ public string ItemType => !this.IsPrimaryKey ? this.IsUniqueKey ? "Unique key" : "Index" : "Primary key";
- private static string FlagListToString(Dictionary flagList)
+ /// Sets the columns value from a given string.
+ /// Comma-separated list of column names.
+ public void SetColumnsFromString(string value)
+ {
+ var columnNames = value.Split(',');
+ foreach (var columnName in columnNames)
{
- if (flagList == null)
+ if (columnName.Contains("(-)"))
{
- return string.Empty;
+ this.Columns.Add(columnName.Replace("(-)", string.Empty).Trim(), false);
}
-
- var sb = new StringBuilder();
- foreach (var pair in flagList)
+ else
{
- sb.AppendLine($"{pair.Key}, {pair.Value}");
+ this.Columns.Add(columnName.Trim(), true);
}
+ }
+ }
+
+ private static string FlagListToString(Dictionary flagList)
+ {
+ if (flagList == null)
+ {
+ return string.Empty;
+ }
- return sb.ToString();
+ var sb = new StringBuilder();
+ foreach (var pair in flagList)
+ {
+ sb.AppendLine($"{pair.Key}, {pair.Value}");
}
+
+ return sb.ToString();
}
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlPermission.cs b/src/QuickCompareModel/DatabaseSchema/SqlPermission.cs
index 04de8a2..614093d 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlPermission.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlPermission.cs
@@ -2,65 +2,64 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
-{
- using QuickCompareModel.DatabaseSchema.Enums;
+namespace QuickCompareModel.DatabaseSchema;
- ///
- /// Class to represent a permission in the database.
- ///
- public class SqlPermission
- {
- /// Gets or sets the role name.
- public string RoleName { get; set; }
+using QuickCompareModel.DatabaseSchema.Enums;
- /// Gets or sets the user name.
- public string UserName { get; set; }
+///
+/// Class to represent a permission in the database.
+///
+public class SqlPermission
+{
+ /// Gets or sets the role name.
+ public string RoleName { get; set; }
- /// Gets or sets the permission type.
- public string PermissionType { get; set; }
+ /// Gets or sets the user name.
+ public string UserName { get; set; }
- /// Gets or sets the permission state.
- public string PermissionState { get; set; }
+ /// Gets or sets the permission type.
+ public string PermissionType { get; set; }
- /// Gets or sets the object type.
- public string ObjectType { get; set; }
+ /// Gets or sets the permission state.
+ public string PermissionState { get; set; }
- /// Gets or sets the object name.
- public string ObjectName { get; set; }
+ /// Gets or sets the object type.
+ public string ObjectType { get; set; }
- /// Gets or sets the column name.
- public string ColumnName { get; set; }
+ /// Gets or sets the object name.
+ public string ObjectName { get; set; }
- /// Gets or sets the object schema.
- public string ObjectSchema { get; set; }
+ /// Gets or sets the column name.
+ public string ColumnName { get; set; }
- /// Gets the full ID.
- public string FullId => $"[{this.RoleName}].[{this.UserName}].[{this.PermissionType}].[{this.PermissionState}].[{this.ObjectType}].[{this.ObjectName}].[{this.ColumnName}]";
+ /// Gets or sets the object schema.
+ public string ObjectSchema { get; set; }
- /// Gets the type.
- public PermissionObjectType Type => this.ObjectType switch
- {
- "SQL_STORED_PROCEDURE" => PermissionObjectType.SqlStoredProcedure,
- "USER_TABLE" => PermissionObjectType.UserTable,
- "SYSTEM_TABLE" => PermissionObjectType.SystemTable,
- "SYNONYM" => PermissionObjectType.Synonym,
- "VIEW" => PermissionObjectType.View,
- "SQL_SCALAR_FUNCTION" => PermissionObjectType.SqlFunction,
- "SQL_TABLE_VALUED_FUNCTION" => PermissionObjectType.SqlFunction,
- "SQL_INLINE_TABLE_VALUED_FUNCTION" => PermissionObjectType.SqlFunction,
- "DATABASE" => PermissionObjectType.Database,
- _ => PermissionObjectType.Unknown,
- };
+ /// Gets the full ID.
+ public string FullId => $"[{this.RoleName}].[{this.UserName}].[{this.PermissionType}].[{this.PermissionState}].[{this.ObjectType}].[{this.ObjectName}].[{this.ColumnName}]";
+
+ /// Gets the type.
+ public PermissionObjectType Type => this.ObjectType switch
+ {
+ "SQL_STORED_PROCEDURE" => PermissionObjectType.SqlStoredProcedure,
+ "USER_TABLE" => PermissionObjectType.UserTable,
+ "SYSTEM_TABLE" => PermissionObjectType.SystemTable,
+ "SYNONYM" => PermissionObjectType.Synonym,
+ "VIEW" => PermissionObjectType.View,
+ "SQL_SCALAR_FUNCTION" => PermissionObjectType.SqlFunction,
+ "SQL_TABLE_VALUED_FUNCTION" => PermissionObjectType.SqlFunction,
+ "SQL_INLINE_TABLE_VALUED_FUNCTION" => PermissionObjectType.SqlFunction,
+ "DATABASE" => PermissionObjectType.Database,
+ _ => PermissionObjectType.Unknown,
+ };
- private string TargetName => string.IsNullOrEmpty(this.RoleName) ? this.UserName : this.RoleName;
+ private string TargetName => string.IsNullOrEmpty(this.RoleName) ? this.UserName : this.RoleName;
- private string TargetType => string.IsNullOrEmpty(this.RoleName) ? "user" : "role";
+ private string TargetType => string.IsNullOrEmpty(this.RoleName) ? "user" : "role";
- /// Generates a text description of the difference.
- /// Description of the difference.
- public override string ToString() => this.PermissionType == "REFERENCES"
- ? $"REFERENCES column: [{this.ColumnName}] {(this.PermissionState == "GRANT" ? string.Empty : "DENIED ")}for {this.TargetType}: [{this.TargetName}]"
- : $"[{this.PermissionType}] {(this.PermissionState == "GRANT" ? string.Empty : "DENIED ")}for {this.TargetType}: [{this.TargetName}]";
- }
+ /// Generates a text description of the difference.
+ /// Description of the difference.
+ public override string ToString() => this.PermissionType == "REFERENCES"
+ ? $"REFERENCES column: [{this.ColumnName}] {(this.PermissionState == "GRANT" ? string.Empty : "DENIED ")}for {this.TargetType}: [{this.TargetName}]"
+ : $"[{this.PermissionType}] {(this.PermissionState == "GRANT" ? string.Empty : "DENIED ")}for {this.TargetType}: [{this.TargetName}]";
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlRelation.cs b/src/QuickCompareModel/DatabaseSchema/SqlRelation.cs
index 1f529fe..3b9fc48 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlRelation.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlRelation.cs
@@ -2,41 +2,40 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
+namespace QuickCompareModel.DatabaseSchema;
+
+///
+/// Class to represent a relationship in the database.
+///
+public class SqlRelation
{
- ///
- /// Class to represent a relationship in the database.
- ///
- public class SqlRelation
- {
- /// Gets or sets the relation nName.
- public string RelationName { get; set; }
+ /// Gets or sets the relation nName.
+ public string RelationName { get; set; }
- /// Gets or sets the child schema.
- public string ChildSchema { get; set; }
+ /// Gets or sets the child schema.
+ public string ChildSchema { get; set; }
- /// Gets or sets the child table.
- public string ChildTable { get; set; }
+ /// Gets or sets the child table.
+ public string ChildTable { get; set; }
- /// Gets or sets the child columns.
- public string ChildColumns { get; set; }
+ /// Gets or sets the child columns.
+ public string ChildColumns { get; set; }
- /// Gets or sets the unique-constraint name.
- public string UniqueConstraintName { get; set; }
+ /// Gets or sets the unique-constraint name.
+ public string UniqueConstraintName { get; set; }
- /// Gets or sets the parent schema.
- public string ParentSchema { get; set; }
+ /// Gets or sets the parent schema.
+ public string ParentSchema { get; set; }
- /// Gets or sets the parent table.
- public string ParentTable { get; set; }
+ /// Gets or sets the parent table.
+ public string ParentTable { get; set; }
- /// Gets or sets the parent columns.
- public string ParentColumns { get; set; }
+ /// Gets or sets the parent columns.
+ public string ParentColumns { get; set; }
- /// Gets or sets the update rule.
- public string UpdateRule { get; set; }
+ /// Gets or sets the update rule.
+ public string UpdateRule { get; set; }
- /// Gets or sets the delete rule.
- public string DeleteRule { get; set; }
- }
+ /// Gets or sets the delete rule.
+ public string DeleteRule { get; set; }
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlTable.cs b/src/QuickCompareModel/DatabaseSchema/SqlTable.cs
index 6d5a44b..9257a64 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlTable.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlTable.cs
@@ -2,31 +2,30 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
-{
- using System.Collections.Generic;
+namespace QuickCompareModel.DatabaseSchema;
+
+using System.Collections.Generic;
- ///
- /// Class to represent a table in the database.
- ///
- public class SqlTable
- {
- /// Gets or sets the column details.
- public List ColumnDetails { get; set; } = new List();
+///
+/// Class to represent a table in the database.
+///
+public class SqlTable
+{
+ /// Gets or sets the column details.
+ public List ColumnDetails { get; set; } = [];
- /// Gets or sets the relations.
- public List Relations { get; set; } = new List();
+ /// Gets or sets the relations.
+ public List Relations { get; set; } = [];
- /// Gets or sets the indexes.
- public List Indexes { get; set; } = new List();
+ /// Gets or sets the indexes.
+ public List Indexes { get; set; } = [];
- /// Gets or sets the triggers.
- public List Triggers { get; set; } = new List();
+ /// Gets or sets the triggers.
+ public List Triggers { get; set; } = [];
- /// Gets a value indicating whether column has unique index.
- /// Name of the column.
- /// True if has a unique index.
- public bool ColumnHasUniqueIndex(string columnName) =>
- this.Indexes.Exists(x => x.Unique && x.Columns.ContainsKey(columnName) && x.Columns.Count == 1);
- }
+ /// Gets a value indicating whether column has unique index.
+ /// Name of the column.
+ /// True if has a unique index.
+ public bool ColumnHasUniqueIndex(string columnName) =>
+ this.Indexes.Exists(x => x.Unique && x.Columns.ContainsKey(columnName) && x.Columns.Count == 1);
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlTrigger.cs b/src/QuickCompareModel/DatabaseSchema/SqlTrigger.cs
index a4c6b81..55022b9 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlTrigger.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlTrigger.cs
@@ -2,47 +2,46 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
+namespace QuickCompareModel.DatabaseSchema;
+
+///
+/// Class to represent a trigger in the database.
+///
+public class SqlTrigger
{
- ///
- /// Class to represent a trigger in the database.
- ///
- public class SqlTrigger
- {
- /// Gets or sets the file group.
- public string FileGroup { get; set; }
+ /// Gets or sets the file group.
+ public string FileGroup { get; set; }
- /// Gets or sets the trigger name.
- public string TriggerName { get; set; }
+ /// Gets or sets the trigger name.
+ public string TriggerName { get; set; }
- /// Gets or sets the trigger owner.
- public string TriggerOwner { get; set; }
+ /// Gets or sets the trigger owner.
+ public string TriggerOwner { get; set; }
- /// Gets or sets the table schema.
- public string TableSchema { get; set; }
+ /// Gets or sets the table schema.
+ public string TableSchema { get; set; }
- /// Gets or sets the table name.
- public string TableName { get; set; }
+ /// Gets or sets the table name.
+ public string TableName { get; set; }
- /// Gets or sets a value indicating whether is update.
- public bool IsUpdate { get; set; }
+ /// Gets or sets a value indicating whether is update.
+ public bool IsUpdate { get; set; }
- /// Gets or sets a value indicating whether is delete.
- public bool IsDelete { get; set; }
+ /// Gets or sets a value indicating whether is delete.
+ public bool IsDelete { get; set; }
- /// Gets or sets a value indicating whether is insert.
- public bool IsInsert { get; set; }
+ /// Gets or sets a value indicating whether is insert.
+ public bool IsInsert { get; set; }
- /// Gets or sets a value indicating whether is after.
- public bool IsAfter { get; set; }
+ /// Gets or sets a value indicating whether is after.
+ public bool IsAfter { get; set; }
- /// Gets or sets a value indicating whether is instead of.
- public bool IsInsteadOf { get; set; }
+ /// Gets or sets a value indicating whether is instead of.
+ public bool IsInsteadOf { get; set; }
- /// Gets or sets a value indicating whether is disabled.
- public bool IsDisabled { get; set; }
+ /// Gets or sets a value indicating whether is disabled.
+ public bool IsDisabled { get; set; }
- /// Gets or sets the trigger content.
- public string TriggerContent { get; set; }
- }
+ /// Gets or sets the trigger content.
+ public string TriggerContent { get; set; }
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlUserRoutine.cs b/src/QuickCompareModel/DatabaseSchema/SqlUserRoutine.cs
index bff14fe..1481df5 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlUserRoutine.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlUserRoutine.cs
@@ -2,17 +2,16 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
+namespace QuickCompareModel.DatabaseSchema;
+
+///
+/// Class to represent a user function or procedure in the database.
+///
+public class SqlUserRoutine
{
- ///
- /// Class to represent a user function or procedure in the database.
- ///
- public class SqlUserRoutine
- {
- /// Gets or sets the routine type.
- public string RoutineType { get; set; }
+ /// Gets or sets the routine type.
+ public string RoutineType { get; set; }
- /// Gets or sets the routine definition.
- public string RoutineDefinition { get; set; }
- }
+ /// Gets or sets the routine definition.
+ public string RoutineDefinition { get; set; }
}
diff --git a/src/QuickCompareModel/DatabaseSchema/SqlUserType.cs b/src/QuickCompareModel/DatabaseSchema/SqlUserType.cs
index 9b08e7e..498da2f 100644
--- a/src/QuickCompareModel/DatabaseSchema/SqlUserType.cs
+++ b/src/QuickCompareModel/DatabaseSchema/SqlUserType.cs
@@ -2,38 +2,37 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel.DatabaseSchema
+namespace QuickCompareModel.DatabaseSchema;
+
+///
+/// Class to represent a custom type in the database.
+///
+public class SqlUserType
{
- ///
- /// Class to represent a custom type in the database.
- ///
- public class SqlUserType
- {
- /// Gets or sets the custom type name.
- public string CustomTypeName { get; set; }
+ /// Gets or sets the custom type name.
+ public string CustomTypeName { get; set; }
- /// Gets or sets the schema name.
- public string SchemaName { get; set; }
+ /// Gets or sets the schema name.
+ public string SchemaName { get; set; }
- /// Gets or sets the underlying type name.
- public string UnderlyingTypeName { get; set; }
+ /// Gets or sets the underlying type name.
+ public string UnderlyingTypeName { get; set; }
- /// Gets or sets the precision.
- public int? Precision { get; set; }
+ /// Gets or sets the precision.
+ public int? Precision { get; set; }
- /// Gets or sets the scale.
- public int? Scale { get; set; }
+ /// Gets or sets the scale.
+ public int? Scale { get; set; }
- /// Gets or sets the max length.
- public int? MaxLength { get; set; }
+ /// Gets or sets the max length.
+ public int? MaxLength { get; set; }
- /// Gets or sets a value indicating whether is nullable.
- public bool IsNullable { get; set; }
+ /// Gets or sets a value indicating whether is nullable.
+ public bool IsNullable { get; set; }
- /// Gets or sets the collation name.
- public string CollationName { get; set; }
+ /// Gets or sets the collation name.
+ public string CollationName { get; set; }
- /// Gets or sets a value indicating whether is assembly type.
- public bool IsAssemblyType { get; set; }
- }
+ /// Gets or sets a value indicating whether is assembly type.
+ public bool IsAssemblyType { get; set; }
}
diff --git a/src/QuickCompareModel/DifferenceBuilder.cs b/src/QuickCompareModel/DifferenceBuilder.cs
index 0856025..8e2ed88 100644
--- a/src/QuickCompareModel/DifferenceBuilder.cs
+++ b/src/QuickCompareModel/DifferenceBuilder.cs
@@ -2,956 +2,950 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel
+namespace QuickCompareModel;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Options;
+using QuickCompareModel.DatabaseDifferences;
+using QuickCompareModel.DatabaseSchema;
+using QuickCompareModel.DatabaseSchema.Enums;
+using QuickCompareModel.Models;
+
+/// Class responsible for building a set of differences between two database instances.
+/// Option settings for the database comparison.
+public class DifferenceBuilder(IOptions options) : IDifferenceBuilder
{
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.Extensions.Options;
- using QuickCompareModel.DatabaseDifferences;
- using QuickCompareModel.DatabaseSchema;
- using QuickCompareModel.DatabaseSchema.Enums;
-
- /// Class responsible for building a set of differences between two database instances.
- public class DifferenceBuilder : IDifferenceBuilder
+ ///
+ /// Initialises a new instance of the class with ready instances.
+ ///
+ /// Option settings for the database comparison.
+ /// Instance of representing the first database to compare.
+ /// Instance of representing the second database to compare.
+ public DifferenceBuilder(IOptions options, SqlDatabase database1, SqlDatabase database2)
+ : this(options)
{
- ///
- /// Initialises a new instance of the class.
- ///
- /// Option settings for the database comparison.
- public DifferenceBuilder(IOptions options) =>
- this.Options = options.Value ?? throw new ArgumentNullException(nameof(options));
+ this.Database1 = database1;
+ this.Database2 = database2;
+ }
- ///
- /// Initialises a new instance of the class with ready instances.
- ///
- /// Option settings for the database comparison.
- /// Instance of representing the first database to compare.
- /// Instance of representing the second database to compare.
- public DifferenceBuilder(IOptions options, SqlDatabase database1, SqlDatabase database2)
- : this(options)
- {
- this.Database1 = database1;
- this.Database2 = database2;
- }
+ ///
+ public event EventHandler ComparisonStatusChanged;
- ///
- public event EventHandler ComparisonStatusChanged;
+ ///
+ public QuickCompareOptions Options { get; set; } = options.Value ?? throw new ArgumentNullException(nameof(options));
- ///
- public QuickCompareOptions Options { get; set; }
+ ///
+ public SqlDatabase Database1 { get; set; }
- ///
- public SqlDatabase Database1 { get; set; }
+ ///
+ public SqlDatabase Database2 { get; set; }
- ///
- public SqlDatabase Database2 { get; set; }
+ ///
+ public Differences Differences { get; set; }
- ///
- public Differences Differences { get; set; }
+ ///
+ public Dictionary DefinitionDifferences { get; set; } = [];
- ///
- public Dictionary DefinitionDifferences { get; set; } = new Dictionary();
+ ///
+ public async Task BuildDifferencesAsync()
+ {
+ if (this.Database1 == null)
+ {
+ await this.LoadDatabaseSchemas();
+ }
- ///
- public async Task BuildDifferencesAsync()
+ this.Differences = new Differences
{
- if (this.Database1 == null)
- {
- await this.LoadDatabaseSchemas();
- }
+ Database1 = this.Database1.FriendlyName,
+ Database2 = this.Database2.FriendlyName,
+ };
- this.Differences = new Differences
- {
- Database1 = this.Database1.FriendlyName,
- Database2 = this.Database2.FriendlyName,
- };
+ this.RaiseStatusChanged("Inspecting differences");
- this.RaiseStatusChanged("Inspecting differences");
+ if (this.Options.CompareProperties)
+ {
+ this.InspectDatabaseExtendedProperties();
+ }
- if (this.Options.CompareProperties)
- {
- this.InspectDatabaseExtendedProperties();
- }
+ if (this.Options.ComparePermissions)
+ {
+ this.InspectDatabasePermissions();
+ }
- if (this.Options.ComparePermissions)
- {
- this.InspectDatabasePermissions();
- }
+ this.InspectTables();
+ this.InspectTableDifferences();
- this.InspectTables();
- this.InspectTableDifferences();
+ if (this.Options.CompareUserTypes)
+ {
+ this.InspectUserTypes();
+ }
- if (this.Options.CompareUserTypes)
- {
- this.InspectUserTypes();
- }
+ if (this.Options.CompareSynonyms)
+ {
+ this.InspectSynonyms();
+ }
- if (this.Options.CompareSynonyms)
- {
- this.InspectSynonyms();
- }
+ if (this.Options.CompareObjects)
+ {
+ this.InspectViews();
+ this.InspectRoutines();
+ }
- if (this.Options.CompareObjects)
- {
- this.InspectViews();
- this.InspectRoutines();
- }
+ this.RaiseStatusChanged("Difference inspection completed...");
+ }
- this.RaiseStatusChanged("Difference inspection completed...");
+ /// Raise the status changed event.
+ /// Current status message.
+ protected virtual void RaiseStatusChanged(string message) =>
+ this.ComparisonStatusChanged?.Invoke(this, new StatusChangedEventArgs(message));
+
+ /// Raise the status changed event.
+ /// Current status message.
+ /// Specified database instance.
+ protected virtual void RaiseStatusChanged(string message, DatabaseInstance databaseInstance) =>
+ this.ComparisonStatusChanged?.Invoke(this, new StatusChangedEventArgs(message, databaseInstance));
+
+ private async Task LoadDatabaseSchemas()
+ {
+ if (string.IsNullOrEmpty(this.Options.ConnectionString1) || string.IsNullOrEmpty(this.Options.ConnectionString2))
+ {
+ throw new InvalidOperationException("Connection strings must be set");
+ }
+
+ this.Database1 = new SqlDatabase(this.Options.ConnectionString1, this.Options);
+ this.Database2 = new SqlDatabase(this.Options.ConnectionString2, this.Options);
+
+ if (this.Database1.FriendlyName.Equals(this.Database2.FriendlyName, StringComparison.CurrentCultureIgnoreCase))
+ {
+ throw new InvalidOperationException("Connection strings must target different database instances");
}
- /// Raise the status changed event.
- /// Current status message.
- protected virtual void RaiseStatusChanged(string message) =>
- this.ComparisonStatusChanged?.Invoke(this, new StatusChangedEventArgs(message));
+ this.Database1.LoaderStatusChanged += (object sender, StatusChangedEventArgs e) =>
+ this.RaiseStatusChanged(e.StatusMessage, DatabaseInstance.Database1);
- /// Raise the status changed event.
- /// Current status message.
- /// Specified database instance.
- protected virtual void RaiseStatusChanged(string message, DatabaseInstance databaseInstance) =>
- this.ComparisonStatusChanged?.Invoke(this, new StatusChangedEventArgs(message, databaseInstance));
+ this.Database2.LoaderStatusChanged += (object sender, StatusChangedEventArgs e) =>
+ this.RaiseStatusChanged(e.StatusMessage, DatabaseInstance.Database2);
- private async Task LoadDatabaseSchemas()
+ await Task.WhenAll(this.Database1.PopulateSchemaModelAsync(), this.Database2.PopulateSchemaModelAsync());
+ }
+
+ private void InspectDatabaseExtendedProperties()
+ {
+ foreach (var property1 in this.Database1.ExtendedProperties.Where(x => x.Type == PropertyObjectType.Database))
{
- if (string.IsNullOrEmpty(this.Options.ConnectionString1) || string.IsNullOrEmpty(this.Options.ConnectionString2))
+ var diff = new ExtendedPropertyDifference(true, false);
+
+ var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
+ if (property2 != null)
{
- throw new InvalidOperationException("Connection strings must be set");
+ diff.ExistsInDatabase2 = true;
+ diff.Value1 = property1.PropertyValue;
+ diff.Value2 = property2.PropertyValue;
}
- this.Database1 = new SqlDatabase(this.Options.ConnectionString1, this.Options);
- this.Database2 = new SqlDatabase(this.Options.ConnectionString2, this.Options);
+ this.Differences.ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
+ }
- if (this.Database1.FriendlyName.ToLower() == this.Database2.FriendlyName.ToLower())
- {
- throw new InvalidOperationException("Connection strings must target different database instances");
- }
+ foreach (var property2 in this.Database2.ExtendedProperties.Where(x => x.Type == PropertyObjectType.Database && !this.Differences.ExtendedPropertyDifferences.ContainsKey(x.PropertyName)))
+ {
+ this.Differences.ExtendedPropertyDifferences.Add(property2.PropertyName, new ExtendedPropertyDifference(false, true));
+ }
+ }
+
+ private void InspectDatabasePermissions()
+ {
+ foreach (var permission1 in this.Database1.Permissions.Where(x => x.Type == PermissionObjectType.Database))
+ {
+ this.Differences.PermissionDifferences.Add(
+ permission1.ToString(),
+ new BaseDifference(true, this.Database2.Permissions.Exists(x => x.FullId == permission1.FullId)));
+ }
- this.Database1.LoaderStatusChanged += (object sender, StatusChangedEventArgs e) =>
- this.RaiseStatusChanged(e.StatusMessage, DatabaseInstance.Database1);
+ foreach (var permission2 in this.Database2.Permissions.Where(x => x.Type == PermissionObjectType.Database && !this.Differences.PermissionDifferences.ContainsKey(x.ToString())))
+ {
+ this.Differences.PermissionDifferences.Add(permission2.ToString(), new BaseDifference(false, true));
+ }
+ }
- this.Database2.LoaderStatusChanged += (object sender, StatusChangedEventArgs e) =>
- this.RaiseStatusChanged(e.StatusMessage, DatabaseInstance.Database2);
+ private void InspectTables()
+ {
+ foreach (var table1 in this.Database1.Tables.Keys)
+ {
+ this.Differences.TableDifferences.Add(table1, new TableDifference(true, this.Database2.Tables.Keys.Any(x => x == table1)));
+ }
- await Task.WhenAll(this.Database1.PopulateSchemaModelAsync(), this.Database2.PopulateSchemaModelAsync());
+ foreach (var table2 in this.Database2.Tables.Keys.Where(x => !this.Differences.TableDifferences.ContainsKey(x)))
+ {
+ this.Differences.TableDifferences.Add(table2, new TableDifference(false, true));
}
+ }
- private void InspectDatabaseExtendedProperties()
+ private void InspectTableDifferences()
+ {
+ foreach (var fullyQualifiedTableName in this.Differences.TableDifferences.Keys.Where(x => this.Differences.TableDifferences[x].ExistsInBothDatabases))
{
- foreach (var property1 in this.Database1.ExtendedProperties.Where(x => x.Type == PropertyObjectType.Database))
+ if (this.Options.CompareColumns)
{
- var diff = new ExtendedPropertyDifference(true, false);
+ this.InspectTableColumns(fullyQualifiedTableName);
+ }
- var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
- if (property2 != null)
- {
- diff.ExistsInDatabase2 = true;
- diff.Value1 = property1.PropertyValue;
- diff.Value2 = property2.PropertyValue;
- }
+ if (this.Options.CompareIndexes)
+ {
+ this.InspectIndexes(fullyQualifiedTableName);
+ }
- this.Differences.ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
+ if (this.Options.CompareRelations)
+ {
+ this.InspectRelations(fullyQualifiedTableName);
}
- foreach (var property2 in this.Database2.ExtendedProperties.Where(x => x.Type == PropertyObjectType.Database && !this.Differences.ExtendedPropertyDifferences.ContainsKey(x.PropertyName)))
+ if (this.Options.ComparePermissions)
{
- this.Differences.ExtendedPropertyDifferences.Add(property2.PropertyName, new ExtendedPropertyDifference(false, true));
+ this.InspectTablePermissions(fullyQualifiedTableName);
}
- }
- private void InspectDatabasePermissions()
- {
- foreach (var permission1 in this.Database1.Permissions.Where(x => x.Type == PermissionObjectType.Database))
+ if (this.Options.CompareProperties)
{
- this.Differences.PermissionDifferences.Add(
- permission1.ToString(),
- new BaseDifference(true, this.Database2.Permissions.Exists(x => x.FullId == permission1.FullId)));
+ this.InspectTableProperties(fullyQualifiedTableName);
}
- foreach (var permission2 in this.Database2.Permissions.Where(x => x.Type == PermissionObjectType.Database && !this.Differences.PermissionDifferences.ContainsKey(x.ToString())))
+ if (this.Options.CompareTriggers)
{
- this.Differences.PermissionDifferences.Add(permission2.ToString(), new BaseDifference(false, true));
+ this.InspectTriggers(fullyQualifiedTableName);
}
}
+ }
- private void InspectTables()
+ private void InspectTableColumns(string fullyQualifiedTableName)
+ {
+ foreach (var column1 in this.Database1.Tables[fullyQualifiedTableName].ColumnDetails)
{
- foreach (var table1 in this.Database1.Tables.Keys)
- {
- this.Differences.TableDifferences.Add(table1, new TableDifference(true, this.Database2.Tables.Keys.Any(x => x == table1)));
- }
+ var diff = new ItemWithPropertiesDifference(true, false);
- foreach (var table2 in this.Database2.Tables.Keys.Where(x => !this.Differences.TableDifferences.ContainsKey(x)))
+ var column2 = this.Database2.Tables[fullyQualifiedTableName].ColumnDetails.FirstOrDefault(x => x.ColumnName == column1.ColumnName);
+ if (column2 != null)
{
- this.Differences.TableDifferences.Add(table2, new TableDifference(false, true));
+ this.InspectColumns(fullyQualifiedTableName, diff, column1, column2);
}
+
+ this.Differences.TableDifferences[fullyQualifiedTableName].ColumnDifferences.Add(column1.ColumnName, diff);
}
- private void InspectTableDifferences()
+ foreach (var column2 in this.Database2.Tables[fullyQualifiedTableName].ColumnDetails.Where(x => !this.Differences.TableDifferences[fullyQualifiedTableName].ColumnDifferences.ContainsKey(x.ColumnName)))
{
- foreach (var fullyQualifiedTableName in this.Differences.TableDifferences.Keys.Where(x => this.Differences.TableDifferences[x].ExistsInBothDatabases))
- {
- if (this.Options.CompareColumns)
- {
- this.InspectTableColumns(fullyQualifiedTableName);
- }
+ this.Differences.TableDifferences[fullyQualifiedTableName].ColumnDifferences.Add(column2.ColumnName, new ItemWithPropertiesDifference(false, true));
+ }
+ }
- if (this.Options.CompareIndexes)
- {
- this.InspectIndexes(fullyQualifiedTableName);
- }
+ private void InspectColumns(string fullyQualifiedTableName, ItemWithPropertiesDifference diff, SqlColumnDetail column1, SqlColumnDetail column2)
+ {
+ if (this.Options.CompareOrdinalPositions && column2.OrdinalPosition != column1.OrdinalPosition)
+ {
+ diff.Differences.Add($"has different ordinal position - is {column1.OrdinalPosition} in database 1 and is {column2.OrdinalPosition} in database 2");
+ }
- if (this.Options.CompareRelations)
- {
- this.InspectRelations(fullyQualifiedTableName);
- }
+ if (column2.ColumnDefault != column1.ColumnDefault)
+ {
+ diff.Differences.Add($"has different default value - is {column1.ColumnDefault} in database 1 and is {column2.ColumnDefault} in database 2");
+ }
- if (this.Options.ComparePermissions)
- {
- this.InspectTablePermissions(fullyQualifiedTableName);
- }
+ if (column2.IsNullable != column1.IsNullable)
+ {
+ diff.Differences.Add($"is {(column1.IsNullable ? string.Empty : "not ")}allowed null in database 1 and is {(column2.IsNullable ? string.Empty : "not ")}allowed null in database 2");
+ }
- if (this.Options.CompareProperties)
- {
- this.InspectTableProperties(fullyQualifiedTableName);
- }
+ if (column2.DataType != column1.DataType)
+ {
+ diff.Differences.Add($"has different data type - is {column1.DataType} in database 1 and is {column2.DataType} in database 2");
+ }
- if (this.Options.CompareTriggers)
- {
- this.InspectTriggers(fullyQualifiedTableName);
- }
- }
+ if (column2.CharacterMaximumLength != column1.CharacterMaximumLength)
+ {
+ diff.Differences.Add($"has different max length - is {(column1.CharacterMaximumLength.HasValue ? column1.CharacterMaximumLength.Value.ToString("n0") : "NULL")} in database 1 and is {(column2.CharacterMaximumLength.HasValue ? column2.CharacterMaximumLength.Value.ToString("n0") : "NULL")} in database 2");
}
- private void InspectTableColumns(string fullyQualifiedTableName)
+ if (column2.CharacterOctetLength != column1.CharacterOctetLength)
{
- foreach (var column1 in this.Database1.Tables[fullyQualifiedTableName].ColumnDetails)
- {
- var diff = new ItemWithPropertiesDifference(true, false);
+ diff.Differences.Add($"has different character octet length - is {(column1.CharacterOctetLength.HasValue ? column1.CharacterOctetLength.Value.ToString("n0") : "NULL")} in database 1 and is {(column2.CharacterOctetLength.HasValue ? column2.CharacterOctetLength.Value.ToString("n0") : "NULL")} in database 2");
+ }
- var column2 = this.Database2.Tables[fullyQualifiedTableName].ColumnDetails.FirstOrDefault(x => x.ColumnName == column1.ColumnName);
- if (column2 != null)
- {
- this.InspectColumns(fullyQualifiedTableName, diff, column1, column2);
- }
+ if (column2.NumericPrecision != column1.NumericPrecision)
+ {
+ diff.Differences.Add($"has different numeric precision - is {(column1.NumericPrecision.HasValue ? column1.NumericPrecision.Value.ToString() : "NULL")} in database 1 and is {(column2.NumericPrecision.HasValue ? column2.NumericPrecision.Value.ToString() : "NULL")} in database 2");
+ }
- this.Differences.TableDifferences[fullyQualifiedTableName].ColumnDifferences.Add(column1.ColumnName, diff);
- }
+ if (column2.NumericPrecisionRadix != column1.NumericPrecisionRadix)
+ {
+ diff.Differences.Add($"has different numeric precision radix - is {(column1.NumericPrecisionRadix.HasValue ? column1.NumericPrecisionRadix.Value.ToString() : "NULL")} in database 1 and is {(column2.NumericPrecisionRadix.HasValue ? column2.NumericPrecisionRadix.Value.ToString() : "NULL")} in database 2");
+ }
- foreach (var column2 in this.Database2.Tables[fullyQualifiedTableName].ColumnDetails.Where(x => !this.Differences.TableDifferences[fullyQualifiedTableName].ColumnDifferences.ContainsKey(x.ColumnName)))
- {
- this.Differences.TableDifferences[fullyQualifiedTableName].ColumnDifferences.Add(column2.ColumnName, new ItemWithPropertiesDifference(false, true));
- }
+ if (column2.NumericScale != column1.NumericScale)
+ {
+ diff.Differences.Add($"has different numeric scale - is {(column1.NumericScale.HasValue ? column1.NumericScale.Value.ToString() : "NULL")} in database 1 and is {(column2.NumericScale.HasValue ? column2.NumericScale.Value.ToString() : "NULL")} in database 2");
}
- private void InspectColumns(string fullyQualifiedTableName, ItemWithPropertiesDifference diff, SqlColumnDetail column1, SqlColumnDetail column2)
+ if (column2.DatetimePrecision != column1.DatetimePrecision)
{
- if (this.Options.CompareOrdinalPositions && column2.OrdinalPosition != column1.OrdinalPosition)
- {
- diff.Differences.Add($"has different ordinal position - is {column1.OrdinalPosition} in database 1 and is {column2.OrdinalPosition} in database 2");
- }
+ diff.Differences.Add($"has different datetime precision - is {(column1.DatetimePrecision.HasValue ? column1.DatetimePrecision.Value.ToString() : "NULL")} in database 1 and is {(column2.DatetimePrecision.HasValue ? column2.DatetimePrecision.Value.ToString() : "NULL")} in database 2");
+ }
- if (column2.ColumnDefault != column1.ColumnDefault)
- {
- diff.Differences.Add($"has different default value - is {column1.ColumnDefault} in database 1 and is {column2.ColumnDefault} in database 2");
- }
+ if (column2.CharacterSetName != column1.CharacterSetName)
+ {
+ diff.Differences.Add($"has different character set - is {(string.IsNullOrEmpty(column1.CharacterSetName) ? "NULL" : column1.CharacterSetName)} in database 1 and is {(string.IsNullOrEmpty(column2.CharacterSetName) ? "NULL" : column2.CharacterSetName)} in database 2");
+ }
- if (column2.IsNullable != column1.IsNullable)
- {
- diff.Differences.Add($"is {(column1.IsNullable ? string.Empty : "not ")}allowed null in database 1 and is {(column2.IsNullable ? string.Empty : "not ")}allowed null in database 2");
- }
+ if (this.Options.CompareCollation && column2.CollationName != column1.CollationName)
+ {
+ diff.Differences.Add($"has different collation - is {(string.IsNullOrEmpty(column1.CollationName) ? "NULL" : column1.CollationName)} in database 1 and is {(string.IsNullOrEmpty(column2.CollationName) ? "NULL" : column2.CollationName)} in database 2");
+ }
- if (column2.DataType != column1.DataType)
- {
- diff.Differences.Add($"has different data type - is {column1.DataType} in database 1 and is {column2.DataType} in database 2");
- }
+ if (column2.IsFullTextIndexed != column1.IsFullTextIndexed)
+ {
+ diff.Differences.Add($"is{(column1.IsFullTextIndexed ? string.Empty : " not")} full-text indexed in database 1 and is{(column2.IsFullTextIndexed ? string.Empty : " not")} full-text indexed in database 2");
+ }
- if (column2.CharacterMaximumLength != column1.CharacterMaximumLength)
- {
- diff.Differences.Add($"has different max length - is {(column1.CharacterMaximumLength.HasValue ? column1.CharacterMaximumLength.Value.ToString("n0") : "NULL")} in database 1 and is {(column2.CharacterMaximumLength.HasValue ? column2.CharacterMaximumLength.Value.ToString("n0") : "NULL")} in database 2");
- }
+ if (column2.IsComputed != column1.IsComputed)
+ {
+ diff.Differences.Add($"is{(column1.IsComputed ? string.Empty : " not")} computed in database 1 and is{(column2.IsComputed ? string.Empty : " not")} computed in database 2");
+ }
- if (column2.CharacterOctetLength != column1.CharacterOctetLength)
- {
- diff.Differences.Add($"has different character octet length - is {(column1.CharacterOctetLength.HasValue ? column1.CharacterOctetLength.Value.ToString("n0") : "NULL")} in database 1 and is {(column2.CharacterOctetLength.HasValue ? column2.CharacterOctetLength.Value.ToString("n0") : "NULL")} in database 2");
- }
+ if (column2.IsIdentity != column1.IsIdentity)
+ {
+ diff.Differences.Add($"is{(column1.IsIdentity ? string.Empty : " not")} an identity column in database 1 and is{(column2.IsIdentity ? string.Empty : " not")} an identity column in database 2");
+ }
- if (column2.NumericPrecision != column1.NumericPrecision)
+ if (column2.IsIdentity && column1.IsIdentity)
+ {
+ if (column2.IdentitySeed != column1.IdentitySeed)
{
- diff.Differences.Add($"has different numeric precision - is {(column1.NumericPrecision.HasValue ? column1.NumericPrecision.Value.ToString() : "NULL")} in database 1 and is {(column2.NumericPrecision.HasValue ? column2.NumericPrecision.Value.ToString() : "NULL")} in database 2");
+ diff.Differences.Add($"has different identity seed - is [{column1.IdentitySeed}] in database 1 and is [{column2.IdentitySeed}] in database 2");
}
- if (column2.NumericPrecisionRadix != column1.NumericPrecisionRadix)
+ if (column2.IdentityIncrement != column1.IdentityIncrement)
{
- diff.Differences.Add($"has different numeric precision radix - is {(column1.NumericPrecisionRadix.HasValue ? column1.NumericPrecisionRadix.Value.ToString() : "NULL")} in database 1 and is {(column2.NumericPrecisionRadix.HasValue ? column2.NumericPrecisionRadix.Value.ToString() : "NULL")} in database 2");
+ diff.Differences.Add($"has different identity increment - is [{column1.IdentityIncrement}] in database 1 and is [{column2.IdentityIncrement}] in database 2");
}
+ }
- if (column2.NumericScale != column1.NumericScale)
- {
- diff.Differences.Add($"has different numeric scale - is {(column1.NumericScale.HasValue ? column1.NumericScale.Value.ToString() : "NULL")} in database 1 and is {(column2.NumericScale.HasValue ? column2.NumericScale.Value.ToString() : "NULL")} in database 2");
- }
+ if (column2.IsSparse != column1.IsSparse)
+ {
+ diff.Differences.Add($"is{(column1.IsSparse ? string.Empty : " not")} sparse in database 1 and is{(column2.IsSparse ? string.Empty : " not")} sparse in database 2");
+ }
- if (column2.DatetimePrecision != column1.DatetimePrecision)
- {
- diff.Differences.Add($"has different datetime precision - is {(column1.DatetimePrecision.HasValue ? column1.DatetimePrecision.Value.ToString() : "NULL")} in database 1 and is {(column2.DatetimePrecision.HasValue ? column2.DatetimePrecision.Value.ToString() : "NULL")} in database 2");
- }
+ if (column2.IsColumnSet != column1.IsColumnSet)
+ {
+ diff.Differences.Add($"is{(column1.IsColumnSet ? string.Empty : " not")} a column-set in database 1 and is{(column2.IsColumnSet ? string.Empty : " not")} a column-set in database 2");
+ }
- if (column2.CharacterSetName != column1.CharacterSetName)
- {
- diff.Differences.Add($"has different character set - is {(string.IsNullOrEmpty(column1.CharacterSetName) ? "NULL" : column1.CharacterSetName)} in database 1 and is {(string.IsNullOrEmpty(column2.CharacterSetName) ? "NULL" : column2.CharacterSetName)} in database 2");
- }
+ if (column2.IsRowGuid != column1.IsRowGuid)
+ {
+ diff.Differences.Add($"is{(column1.IsRowGuid ? string.Empty : " not")} a row-guid in database 1 and is{(column2.IsRowGuid ? string.Empty : " not")} a row-guid in database 2");
+ }
- if (this.Options.CompareCollation && column2.CollationName != column1.CollationName)
- {
- diff.Differences.Add($"has different collation - is {(string.IsNullOrEmpty(column1.CollationName) ? "NULL" : column1.CollationName)} in database 1 and is {(string.IsNullOrEmpty(column2.CollationName) ? "NULL" : column2.CollationName)} in database 2");
- }
+ if (column2.DomainName.PrependSchemaName(column2.DomainSchema) != column1.DomainName.PrependSchemaName(column1.DomainSchema))
+ {
+ diff.Differences.Add($"has different custom datatype - is {(string.IsNullOrEmpty(column1.DomainName) ? "NULL" : column1.DomainName.PrependSchemaName(column1.DomainSchema))} in database 1 and is {(string.IsNullOrEmpty(column2.DomainName) ? "NULL" : column2.DomainName.PrependSchemaName(column2.DomainSchema))} in database 2");
+ }
- if (column2.IsFullTextIndexed != column1.IsFullTextIndexed)
- {
- diff.Differences.Add($"is{(column1.IsFullTextIndexed ? string.Empty : " not")} full-text indexed in database 1 and is{(column2.IsFullTextIndexed ? string.Empty : " not")} full-text indexed in database 2");
- }
+ if (this.Database2.Tables[fullyQualifiedTableName].ColumnHasUniqueIndex(column2.ColumnName) != this.Database1.Tables[fullyQualifiedTableName].ColumnHasUniqueIndex(column1.ColumnName))
+ {
+ diff.Differences.Add($"{(this.Database1.Tables[fullyQualifiedTableName].ColumnHasUniqueIndex(column1.ColumnName) ? "has" : "does not have")} a unique constraint in database 1 and {(this.Database2.Tables[fullyQualifiedTableName].ColumnHasUniqueIndex(column2.ColumnName) ? "has" : "does not have")} a unique constraint in database 2");
+ }
- if (column2.IsComputed != column1.IsComputed)
- {
- diff.Differences.Add($"is{(column1.IsComputed ? string.Empty : " not")} computed in database 1 and is{(column2.IsComputed ? string.Empty : " not")} computed in database 2");
- }
+ if (this.Options.CompareProperties)
+ {
+ this.InspectColumnProperties(fullyQualifiedTableName, column2.ColumnName, diff);
+ }
+
+ diff.ExistsInDatabase2 = true;
+ }
+
+ private void InspectColumnProperties(string fullyQualifiedTableName, string columnName, ItemWithPropertiesDifference columnDiff)
+ {
+ var hasFoundColumn1Description = false;
+
+ foreach (var property1 in this.Database1.ExtendedProperties.Where(x => x.Type == PropertyObjectType.TableColumn && x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName && x.ColumnName == columnName))
+ {
+ var diff = new ExtendedPropertyDifference(true, false);
- if (column2.IsIdentity != column1.IsIdentity)
+ var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
+ if (property2 != null)
{
- diff.Differences.Add($"is{(column1.IsIdentity ? string.Empty : " not")} an identity column in database 1 and is{(column2.IsIdentity ? string.Empty : " not")} an identity column in database 2");
+ diff.ExistsInDatabase2 = true;
+ diff.Value1 = property1.PropertyValue;
+ diff.Value2 = property2.PropertyValue;
}
- if (column2.IsIdentity && column1.IsIdentity)
+ if (property1.PropertyName == "MS_Description")
{
- if (column2.IdentitySeed != column1.IdentitySeed)
+ hasFoundColumn1Description = true;
+ if (!diff.ExistsInDatabase2)
{
- diff.Differences.Add($"has different identity seed - is [{column1.IdentitySeed}] in database 1 and is [{column2.IdentitySeed}] in database 2");
+ columnDiff.Differences.Add("description exists in database 1 and does not exist in database 2");
}
-
- if (column2.IdentityIncrement != column1.IdentityIncrement)
+ else if (diff.Value1 != diff.Value2)
{
- diff.Differences.Add($"has different identity increment - is [{column1.IdentityIncrement}] in database 1 and is [{column2.IdentityIncrement}] in database 2");
+ columnDiff.Differences.Add($"has different description - is [{diff.Value1}] in database 1 and is [{diff.Value2}] in database 2");
}
}
-
- if (column2.IsSparse != column1.IsSparse)
- {
- diff.Differences.Add($"is{(column1.IsSparse ? string.Empty : " not")} sparse in database 1 and is{(column2.IsSparse ? string.Empty : " not")} sparse in database 2");
- }
-
- if (column2.IsColumnSet != column1.IsColumnSet)
- {
- diff.Differences.Add($"is{(column1.IsColumnSet ? string.Empty : " not")} a column-set in database 1 and is{(column2.IsColumnSet ? string.Empty : " not")} a column-set in database 2");
- }
-
- if (column2.IsRowGuid != column1.IsRowGuid)
- {
- diff.Differences.Add($"is{(column1.IsRowGuid ? string.Empty : " not")} a row-guid in database 1 and is{(column2.IsRowGuid ? string.Empty : " not")} a row-guid in database 2");
- }
-
- if (column2.DomainName.PrependSchemaName(column2.DomainSchema) != column1.DomainName.PrependSchemaName(column1.DomainSchema))
+ else
{
- diff.Differences.Add($"has different custom datatype - is {(string.IsNullOrEmpty(column1.DomainName) ? "NULL" : column1.DomainName.PrependSchemaName(column1.DomainSchema))} in database 1 and is {(string.IsNullOrEmpty(column2.DomainName) ? "NULL" : column2.DomainName.PrependSchemaName(column2.DomainSchema))} in database 2");
+ columnDiff.ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
}
+ }
- if (this.Database2.Tables[fullyQualifiedTableName].ColumnHasUniqueIndex(column2.ColumnName) != this.Database1.Tables[fullyQualifiedTableName].ColumnHasUniqueIndex(column1.ColumnName))
+ foreach (var property2 in this.Database2.ExtendedProperties.Where(x => x.Type == PropertyObjectType.TableColumn && x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName && x.ColumnName == columnName))
+ {
+ if (property2.PropertyName == "MS_Description")
{
- diff.Differences.Add($"{(this.Database1.Tables[fullyQualifiedTableName].ColumnHasUniqueIndex(column1.ColumnName) ? "has" : "does not have")} a unique constraint in database 1 and {(this.Database2.Tables[fullyQualifiedTableName].ColumnHasUniqueIndex(column2.ColumnName) ? "has" : "does not have")} a unique constraint in database 2");
+ if (!hasFoundColumn1Description)
+ {
+ columnDiff.Differences.Add("description exists in database 2 and does not exist in database 1");
+ }
}
-
- if (this.Options.CompareProperties)
+ else if (!columnDiff.ExtendedPropertyDifferences.ContainsKey(property2.PropertyName))
{
- this.InspectColumnProperties(fullyQualifiedTableName, column2.ColumnName, diff);
+ columnDiff.ExtendedPropertyDifferences.Add(property2.PropertyName, new ExtendedPropertyDifference(false, true));
}
-
- diff.ExistsInDatabase2 = true;
}
+ }
- private void InspectColumnProperties(string fullyQualifiedTableName, string columnName, ItemWithPropertiesDifference columnDiff)
+ private void InspectIndexes(string fullyQualifiedTableName)
+ {
+ foreach (var index1 in this.Database1.Tables[fullyQualifiedTableName].Indexes)
{
- var hasFoundColumn1Description = false;
+ var diff = new ItemWithPropertiesDifference(true, false, index1.ItemType);
- foreach (var property1 in this.Database1.ExtendedProperties.Where(x => x.Type == PropertyObjectType.TableColumn && x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName && x.ColumnName == columnName))
+ var index2 = this.Database2.Tables[fullyQualifiedTableName].Indexes.FirstOrDefault(x => x.FullId == index1.FullId);
+ if (index2 != null)
{
- var diff = new ExtendedPropertyDifference(true, false);
-
- var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
- if (property2 != null)
+ if (index2.Clustered != index1.Clustered)
{
- diff.ExistsInDatabase2 = true;
- diff.Value1 = property1.PropertyValue;
- diff.Value2 = property2.PropertyValue;
+ diff.Differences.Add($"has different clustering - is{(index1.Clustered ? string.Empty : " not")} clustered in database 1 and is{(index2.Clustered ? string.Empty : " not")} clustered in database 2");
}
- if (property1.PropertyName == "MS_Description")
+ if (index2.Unique != index1.Unique)
{
- hasFoundColumn1Description = true;
- if (!diff.ExistsInDatabase2)
- {
- columnDiff.Differences.Add("description exists in database 1 and does not exist in database 2");
- }
- else if (diff.Value1 != diff.Value2)
- {
- columnDiff.Differences.Add($"has different description - is [{diff.Value1}] in database 1 and is [{diff.Value2}] in database 2");
- }
+ diff.Differences.Add($"has different uniqueness - is{(index1.Unique ? string.Empty : " not")} unique in database 1 and is{(index2.Unique ? string.Empty : " not")} unique in database 2");
}
- else
+
+ if (index2.IsUniqueKey != index1.IsUniqueKey)
{
- columnDiff.ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
+ diff.Differences.Add($"has different type - {(index1.IsUniqueKey ? "unique key" : "index")} in database 1 and {(index2.Unique ? string.Empty : " not")} in database 2");
}
- }
- foreach (var property2 in this.Database2.ExtendedProperties.Where(x => x.Type == PropertyObjectType.TableColumn && x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName && x.ColumnName == columnName))
- {
- if (property2.PropertyName == "MS_Description")
+ if (index2.IsPrimaryKey != index1.IsPrimaryKey)
{
- if (!hasFoundColumn1Description)
- {
- columnDiff.Differences.Add("description exists in database 2 and does not exist in database 1");
- }
+ diff.Differences.Add($"has different primary - is{(index1.IsPrimaryKey ? string.Empty : " not")} a primary key in database 1 and is{(index2.IsPrimaryKey ? string.Empty : " not")} a primary key in database 2");
}
- else if (!columnDiff.ExtendedPropertyDifferences.ContainsKey(property2.PropertyName))
+
+ if (index2.FileGroup != index1.FileGroup)
{
- columnDiff.ExtendedPropertyDifferences.Add(property2.PropertyName, new ExtendedPropertyDifference(false, true));
+ diff.Differences.Add($"has different filegroup - [{index1.FileGroup}] in database 1 and [{index2.FileGroup}] in database 2");
}
- }
- }
- private void InspectIndexes(string fullyQualifiedTableName)
- {
- foreach (var index1 in this.Database1.Tables[fullyQualifiedTableName].Indexes)
- {
- var diff = new ItemWithPropertiesDifference(true, false, index1.ItemType);
-
- var index2 = this.Database2.Tables[fullyQualifiedTableName].Indexes.FirstOrDefault(x => x.FullId == index1.FullId);
- if (index2 != null)
+ if (index2.ColumnsToString != index1.ColumnsToString)
{
- if (index2.Clustered != index1.Clustered)
- {
- diff.Differences.Add($"has different clustering - is{(index1.Clustered ? string.Empty : " not")} clustered in database 1 and is{(index2.Clustered ? string.Empty : " not")} clustered in database 2");
- }
-
- if (index2.Unique != index1.Unique)
- {
- diff.Differences.Add($"has different uniqueness - is{(index1.Unique ? string.Empty : " not")} unique in database 1 and is{(index2.Unique ? string.Empty : " not")} unique in database 2");
- }
-
- if (index2.IsUniqueKey != index1.IsUniqueKey)
- {
- diff.Differences.Add($"has different type - {(index1.IsUniqueKey ? "unique key" : "index")} in database 1 and {(index2.Unique ? string.Empty : " not")} in database 2");
- }
-
- if (index2.IsPrimaryKey != index1.IsPrimaryKey)
+ foreach (var column in index1.Columns.Keys)
{
- diff.Differences.Add($"has different primary - is{(index1.IsPrimaryKey ? string.Empty : " not")} a primary key in database 1 and is{(index2.IsPrimaryKey ? string.Empty : " not")} a primary key in database 2");
- }
-
- if (index2.FileGroup != index1.FileGroup)
- {
- diff.Differences.Add($"has different filegroup - [{index1.FileGroup}] in database 1 and [{index2.FileGroup}] in database 2");
- }
-
- if (index2.ColumnsToString != index1.ColumnsToString)
- {
- foreach (var column in index1.Columns.Keys)
+ if (index2.Columns.TryGetValue(column, out bool value))
{
- if (index2.Columns.TryGetValue(column, out bool value))
- {
- if (index1.Columns[column] != value)
- {
- diff.Differences.Add($"[{column}] has different ordering - {(index1.Columns[column] ? "a" : "de")}scending on database 1 and {(value ? "a" : "de")}scending on database 2");
- }
- }
- else
+ if (index1.Columns[column] != value)
{
- diff.Differences.Add($"[{column}] column does not exist in database 2 index");
+ diff.Differences.Add($"[{column}] has different ordering - {(index1.Columns[column] ? "a" : "de")}scending on database 1 and {(value ? "a" : "de")}scending on database 2");
}
}
-
- foreach (var column in index2.Columns.Keys.Where(x => !index1.Columns.ContainsKey(x)))
+ else
{
- diff.Differences.Add($"[{column}] column does not exist in database 1 index");
+ diff.Differences.Add($"[{column}] column does not exist in database 2 index");
}
}
- if (index2.IncludedColumnsToString != index1.IncludedColumnsToString)
+ foreach (var column in index2.Columns.Keys.Where(x => !index1.Columns.ContainsKey(x)))
+ {
+ diff.Differences.Add($"[{column}] column does not exist in database 1 index");
+ }
+ }
+
+ if (index2.IncludedColumnsToString != index1.IncludedColumnsToString)
+ {
+ foreach (var column in index1.IncludedColumns.Keys)
{
- foreach (var column in index1.IncludedColumns.Keys)
+ if (index2.IncludedColumns.TryGetValue(column, out bool value))
{
- if (index2.IncludedColumns.TryGetValue(column, out bool value))
- {
- if (index1.IncludedColumns[column] != value)
- {
- diff.Differences.Add($"[{column}] \"included column\" has different ordering - {(index1.IncludedColumns[column] ? "a" : "de")}scending on database 1 and {(value ? "a" : "de")}scending on database 2");
- }
- }
- else
+ if (index1.IncludedColumns[column] != value)
{
- diff.Differences.Add($"[{column}] \"included column\" does not exist in database 2 index");
+ diff.Differences.Add($"[{column}] \"included column\" has different ordering - {(index1.IncludedColumns[column] ? "a" : "de")}scending on database 1 and {(value ? "a" : "de")}scending on database 2");
}
}
-
- foreach (var column in index2.IncludedColumns.Keys.Where(x => !index1.IncludedColumns.ContainsKey(x)))
+ else
{
- diff.Differences.Add($"[{column}] \"included column\" does not exist in database 1 index");
+ diff.Differences.Add($"[{column}] \"included column\" does not exist in database 2 index");
}
}
- if (this.Options.CompareProperties)
+ foreach (var column in index2.IncludedColumns.Keys.Where(x => !index1.IncludedColumns.ContainsKey(x)))
{
- this.InspectIndexProperties(fullyQualifiedTableName, index2.IndexName, diff);
+ diff.Differences.Add($"[{column}] \"included column\" does not exist in database 1 index");
}
+ }
- diff.ExistsInDatabase2 = true;
+ if (this.Options.CompareProperties)
+ {
+ this.InspectIndexProperties(fullyQualifiedTableName, index2.IndexName, diff);
}
- this.Differences.TableDifferences[fullyQualifiedTableName].IndexDifferences.Add(index1.IndexName, diff);
+ diff.ExistsInDatabase2 = true;
}
- foreach (var index in this.Database2.Tables[fullyQualifiedTableName].Indexes.Where(x =>
- !this.Differences.TableDifferences[fullyQualifiedTableName].IndexDifferences.ContainsKey(x.IndexName)))
- {
- this.Differences.TableDifferences[fullyQualifiedTableName].IndexDifferences.Add(index.IndexName, new ItemWithPropertiesDifference(false, true, index.ItemType));
- }
+ this.Differences.TableDifferences[fullyQualifiedTableName].IndexDifferences.Add(index1.IndexName, diff);
}
- private void InspectIndexProperties(string fullyQualifiedTableName, string indexName, ItemWithPropertiesDifference indexDiff)
+ foreach (var index in this.Database2.Tables[fullyQualifiedTableName].Indexes.Where(x =>
+ !this.Differences.TableDifferences[fullyQualifiedTableName].IndexDifferences.ContainsKey(x.IndexName)))
{
- foreach (var property1 in this.Database1.ExtendedProperties)
- {
- var propertyTableName = property1.TableName.PrependSchemaName(property1.TableSchema);
- if (property1.Type == PropertyObjectType.Index && propertyTableName == fullyQualifiedTableName && property1.IndexName == indexName)
- {
- var diff = new ExtendedPropertyDifference(true, false);
- var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
- if (property2 != null)
- {
- diff.ExistsInDatabase2 = true;
- diff.Value1 = property1.PropertyValue;
- diff.Value2 = property2.PropertyValue;
- }
+ this.Differences.TableDifferences[fullyQualifiedTableName].IndexDifferences.Add(index.IndexName, new ItemWithPropertiesDifference(false, true, index.ItemType));
+ }
+ }
- indexDiff.ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
+ private void InspectIndexProperties(string fullyQualifiedTableName, string indexName, ItemWithPropertiesDifference indexDiff)
+ {
+ foreach (var property1 in this.Database1.ExtendedProperties)
+ {
+ var propertyTableName = property1.TableName.PrependSchemaName(property1.TableSchema);
+ if (property1.Type == PropertyObjectType.Index && propertyTableName == fullyQualifiedTableName && property1.IndexName == indexName)
+ {
+ var diff = new ExtendedPropertyDifference(true, false);
+ var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
+ if (property2 != null)
+ {
+ diff.ExistsInDatabase2 = true;
+ diff.Value1 = property1.PropertyValue;
+ diff.Value2 = property2.PropertyValue;
}
- }
- foreach (var property in this.Database2.ExtendedProperties.Where(x =>
- x.PropertyType == "INDEX" &&
- x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName &&
- x.IndexName == indexName &&
- !indexDiff.ExtendedPropertyDifferences.ContainsKey(x.PropertyName)))
- {
- indexDiff.ExtendedPropertyDifferences.Add(property.PropertyName, new ExtendedPropertyDifference(false, true));
+ indexDiff.ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
}
}
- private void InspectRelations(string fullyQualifiedTableName)
+ foreach (var property in this.Database2.ExtendedProperties.Where(x =>
+ x.PropertyType == "INDEX" &&
+ x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName &&
+ x.IndexName == indexName &&
+ !indexDiff.ExtendedPropertyDifferences.ContainsKey(x.PropertyName)))
{
- foreach (var relation1 in this.Database1.Tables[fullyQualifiedTableName].Relations)
- {
- var diff = new ItemDifference(true, false);
+ indexDiff.ExtendedPropertyDifferences.Add(property.PropertyName, new ExtendedPropertyDifference(false, true));
+ }
+ }
- var relation2 = this.Database2.Tables[fullyQualifiedTableName].Relations.FirstOrDefault(x => x.RelationName == relation1.RelationName);
- if (relation2 != null)
- {
- if (relation2.ChildColumns != relation1.ChildColumns)
- {
- diff.Differences.Add($"has different child column list - is \"{relation1.ChildColumns}\" in database 1 and is \"{relation2.ChildColumns}\" in database 2");
- }
+ private void InspectRelations(string fullyQualifiedTableName)
+ {
+ foreach (var relation1 in this.Database1.Tables[fullyQualifiedTableName].Relations)
+ {
+ var diff = new ItemDifference(true, false);
- if (relation2.ParentColumns != relation1.ParentColumns)
- {
- diff.Differences.Add($"has different parent column list - is \"{relation1.ParentColumns}\" in database 1 and is \"{relation2.ParentColumns}\" in database 2");
- }
+ var relation2 = this.Database2.Tables[fullyQualifiedTableName].Relations.FirstOrDefault(x => x.RelationName == relation1.RelationName);
+ if (relation2 != null)
+ {
+ if (relation2.ChildColumns != relation1.ChildColumns)
+ {
+ diff.Differences.Add($"has different child column list - is \"{relation1.ChildColumns}\" in database 1 and is \"{relation2.ChildColumns}\" in database 2");
+ }
- if (relation2.DeleteRule != relation1.DeleteRule)
- {
- diff.Differences.Add($"has different delete rule - is \"{relation1.DeleteRule}\" in database 1 and is \"{relation2.DeleteRule}\" in database 2");
- }
+ if (relation2.ParentColumns != relation1.ParentColumns)
+ {
+ diff.Differences.Add($"has different parent column list - is \"{relation1.ParentColumns}\" in database 1 and is \"{relation2.ParentColumns}\" in database 2");
+ }
- if (relation2.UpdateRule != relation1.UpdateRule)
- {
- diff.Differences.Add($"has different update rule - is \"{relation1.UpdateRule}\" in database 1 and is \"{relation2.UpdateRule}\" in database 2");
- }
+ if (relation2.DeleteRule != relation1.DeleteRule)
+ {
+ diff.Differences.Add($"has different delete rule - is \"{relation1.DeleteRule}\" in database 1 and is \"{relation2.DeleteRule}\" in database 2");
+ }
- diff.ExistsInDatabase2 = true;
+ if (relation2.UpdateRule != relation1.UpdateRule)
+ {
+ diff.Differences.Add($"has different update rule - is \"{relation1.UpdateRule}\" in database 1 and is \"{relation2.UpdateRule}\" in database 2");
}
- this.Differences.TableDifferences[fullyQualifiedTableName].RelationshipDifferences.Add(relation1.RelationName, diff);
+ diff.ExistsInDatabase2 = true;
}
- foreach (var relation in this.Database2.Tables[fullyQualifiedTableName].Relations.Where(x => !this.Differences.TableDifferences[fullyQualifiedTableName].RelationshipDifferences.ContainsKey(x.RelationName)))
- {
- this.Differences.TableDifferences[fullyQualifiedTableName].RelationshipDifferences.Add(relation.RelationName, new ItemDifference(false, true));
- }
+ this.Differences.TableDifferences[fullyQualifiedTableName].RelationshipDifferences.Add(relation1.RelationName, diff);
}
- private void InspectTablePermissions(string fullyQualifiedTableName)
+ foreach (var relation in this.Database2.Tables[fullyQualifiedTableName].Relations.Where(x => !this.Differences.TableDifferences[fullyQualifiedTableName].RelationshipDifferences.ContainsKey(x.RelationName)))
{
- foreach (var permission1 in this.Database1.Permissions)
- {
- var permissionTableName = permission1.ObjectName.PrependSchemaName(permission1.ObjectSchema);
- if (permission1.Type == PermissionObjectType.UserTable && permissionTableName == fullyQualifiedTableName)
- {
- this.Differences.TableDifferences[fullyQualifiedTableName].PermissionDifferences.Add(
- permission1.ToString(),
- new BaseDifference(true, this.Database2.Permissions.Exists(x => x.FullId == permission1.FullId)));
- }
- }
+ this.Differences.TableDifferences[fullyQualifiedTableName].RelationshipDifferences.Add(relation.RelationName, new ItemDifference(false, true));
+ }
+ }
- foreach (var permission in this.Database2.Permissions.Where(x =>
- x.ObjectType == "USER_TABLE" &&
- x.ObjectName.PrependSchemaName(x.ObjectSchema) == fullyQualifiedTableName &&
- !this.Differences.TableDifferences[fullyQualifiedTableName].PermissionDifferences.ContainsKey(x.ToString())))
+ private void InspectTablePermissions(string fullyQualifiedTableName)
+ {
+ foreach (var permission1 in this.Database1.Permissions)
+ {
+ var permissionTableName = permission1.ObjectName.PrependSchemaName(permission1.ObjectSchema);
+ if (permission1.Type == PermissionObjectType.UserTable && permissionTableName == fullyQualifiedTableName)
{
- this.Differences.TableDifferences[fullyQualifiedTableName].PermissionDifferences.Add(permission.ToString(), new ExtendedPropertyDifference(false, true));
+ this.Differences.TableDifferences[fullyQualifiedTableName].PermissionDifferences.Add(
+ permission1.ToString(),
+ new BaseDifference(true, this.Database2.Permissions.Exists(x => x.FullId == permission1.FullId)));
}
}
- private void InspectTableProperties(string fullyQualifiedTableName)
+ foreach (var permission in this.Database2.Permissions.Where(x =>
+ x.ObjectType == "USER_TABLE" &&
+ x.ObjectName.PrependSchemaName(x.ObjectSchema) == fullyQualifiedTableName &&
+ !this.Differences.TableDifferences[fullyQualifiedTableName].PermissionDifferences.ContainsKey(x.ToString())))
{
- foreach (var property1 in this.Database1.ExtendedProperties)
- {
- var propertyTableName = property1.TableName.PrependSchemaName(property1.TableSchema);
- if (property1.Type == PropertyObjectType.Table && propertyTableName == fullyQualifiedTableName)
- {
- var diff = new ExtendedPropertyDifference(true, false);
+ this.Differences.TableDifferences[fullyQualifiedTableName].PermissionDifferences.Add(permission.ToString(), new ExtendedPropertyDifference(false, true));
+ }
+ }
- var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
- if (property2 != null)
- {
- diff.ExistsInDatabase2 = true;
- diff.Value1 = property1.PropertyValue;
- diff.Value2 = property2.PropertyValue;
- }
+ private void InspectTableProperties(string fullyQualifiedTableName)
+ {
+ foreach (var property1 in this.Database1.ExtendedProperties)
+ {
+ var propertyTableName = property1.TableName.PrependSchemaName(property1.TableSchema);
+ if (property1.Type == PropertyObjectType.Table && propertyTableName == fullyQualifiedTableName)
+ {
+ var diff = new ExtendedPropertyDifference(true, false);
- this.Differences.TableDifferences[fullyQualifiedTableName].ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
+ var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
+ if (property2 != null)
+ {
+ diff.ExistsInDatabase2 = true;
+ diff.Value1 = property1.PropertyValue;
+ diff.Value2 = property2.PropertyValue;
}
- }
- foreach (var property in this.Database2.ExtendedProperties.Where(x =>
- x.ColumnName == null &&
- x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName &&
- !this.Differences.TableDifferences[fullyQualifiedTableName].ExtendedPropertyDifferences.ContainsKey(x.PropertyName)))
- {
- this.Differences.TableDifferences[fullyQualifiedTableName].ExtendedPropertyDifferences.Add(property.PropertyName, new ExtendedPropertyDifference(false, true));
+ this.Differences.TableDifferences[fullyQualifiedTableName].ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
}
}
- private void InspectTriggers(string fullyQualifiedTableName)
+ foreach (var property in this.Database2.ExtendedProperties.Where(x =>
+ x.ColumnName == null &&
+ x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName &&
+ !this.Differences.TableDifferences[fullyQualifiedTableName].ExtendedPropertyDifferences.ContainsKey(x.PropertyName)))
{
- foreach (var trigger1 in this.Database1.Tables[fullyQualifiedTableName].Triggers)
- {
- var diff = new ItemDifference(true, false);
+ this.Differences.TableDifferences[fullyQualifiedTableName].ExtendedPropertyDifferences.Add(property.PropertyName, new ExtendedPropertyDifference(false, true));
+ }
+ }
- var trigger2 = this.Database2.Tables[fullyQualifiedTableName].Triggers.FirstOrDefault(x => x.TriggerName == trigger1.TriggerName && x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName);
- if (trigger2 != null)
- {
- if (trigger2.FileGroup != trigger1.FileGroup)
- {
- diff.Differences.Add($"has different filegroup - is {trigger1.FileGroup} in database 1 and is {trigger2.FileGroup} in database 2");
- }
+ private void InspectTriggers(string fullyQualifiedTableName)
+ {
+ foreach (var trigger1 in this.Database1.Tables[fullyQualifiedTableName].Triggers)
+ {
+ var diff = new ItemDifference(true, false);
- if (trigger2.TriggerOwner != trigger1.TriggerOwner)
- {
- diff.Differences.Add($"has different owner - is {trigger1.TriggerOwner} in database 1 and is {trigger2.TriggerOwner} in database 2");
- }
+ var trigger2 = this.Database2.Tables[fullyQualifiedTableName].Triggers.FirstOrDefault(x => x.TriggerName == trigger1.TriggerName && x.TableName.PrependSchemaName(x.TableSchema) == fullyQualifiedTableName);
+ if (trigger2 != null)
+ {
+ if (trigger2.FileGroup != trigger1.FileGroup)
+ {
+ diff.Differences.Add($"has different filegroup - is {trigger1.FileGroup} in database 1 and is {trigger2.FileGroup} in database 2");
+ }
- if (trigger2.IsUpdate != trigger1.IsUpdate)
- {
- diff.Differences.Add($"has different update - is {(trigger1.IsUpdate ? string.Empty : "not ")}update in database 1 and is {(trigger2.IsUpdate ? string.Empty : "not ")}update in database 2");
- }
+ if (trigger2.TriggerOwner != trigger1.TriggerOwner)
+ {
+ diff.Differences.Add($"has different owner - is {trigger1.TriggerOwner} in database 1 and is {trigger2.TriggerOwner} in database 2");
+ }
- if (trigger2.IsDelete != trigger1.IsDelete)
- {
- diff.Differences.Add($"has different delete - is {(trigger1.IsDelete ? string.Empty : "not ")}delete in database 1 and is {(trigger2.IsDelete ? string.Empty : "not ")}delete in database 2");
- }
+ if (trigger2.IsUpdate != trigger1.IsUpdate)
+ {
+ diff.Differences.Add($"has different update - is {(trigger1.IsUpdate ? string.Empty : "not ")}update in database 1 and is {(trigger2.IsUpdate ? string.Empty : "not ")}update in database 2");
+ }
- if (trigger2.IsInsert != trigger1.IsInsert)
- {
- diff.Differences.Add($"has different insert - is {(trigger1.IsInsert ? string.Empty : "not ")}insert in database 1 and is {(trigger2.IsInsert ? string.Empty : "not ")}insert in database 2");
- }
+ if (trigger2.IsDelete != trigger1.IsDelete)
+ {
+ diff.Differences.Add($"has different delete - is {(trigger1.IsDelete ? string.Empty : "not ")}delete in database 1 and is {(trigger2.IsDelete ? string.Empty : "not ")}delete in database 2");
+ }
- if (trigger2.IsAfter != trigger1.IsAfter)
- {
- diff.Differences.Add($"has different after - is {(trigger1.IsAfter ? string.Empty : "not ")}after in database 1 and is {(trigger2.IsAfter ? string.Empty : "not ")}after in database 2");
- }
+ if (trigger2.IsInsert != trigger1.IsInsert)
+ {
+ diff.Differences.Add($"has different insert - is {(trigger1.IsInsert ? string.Empty : "not ")}insert in database 1 and is {(trigger2.IsInsert ? string.Empty : "not ")}insert in database 2");
+ }
- if (trigger2.IsInsteadOf != trigger1.IsInsteadOf)
- {
- diff.Differences.Add($"has different instead-of - is {(trigger1.IsInsteadOf ? string.Empty : "not ")}instead-of in database 1 and is {(trigger2.IsInsteadOf ? string.Empty : "not ")}instead-of in database 2");
- }
+ if (trigger2.IsAfter != trigger1.IsAfter)
+ {
+ diff.Differences.Add($"has different after - is {(trigger1.IsAfter ? string.Empty : "not ")}after in database 1 and is {(trigger2.IsAfter ? string.Empty : "not ")}after in database 2");
+ }
- if (trigger2.IsDisabled != trigger1.IsDisabled)
- {
- diff.Differences.Add($"has different disabled - is {(trigger1.IsDisabled ? string.Empty : "not ")}disabled in database 1 and is {(trigger2.IsDisabled ? string.Empty : "not ")}disabled in database 2");
- }
+ if (trigger2.IsInsteadOf != trigger1.IsInsteadOf)
+ {
+ diff.Differences.Add($"has different instead-of - is {(trigger1.IsInsteadOf ? string.Empty : "not ")}instead-of in database 1 and is {(trigger2.IsInsteadOf ? string.Empty : "not ")}instead-of in database 2");
+ }
- if (BaseDifference.CleanDefinitionText(trigger1.TriggerContent, true) != BaseDifference.CleanDefinitionText(trigger2.TriggerContent, true))
- {
- diff.Differences.Add("definitions are different");
- }
+ if (trigger2.IsDisabled != trigger1.IsDisabled)
+ {
+ diff.Differences.Add($"has different disabled - is {(trigger1.IsDisabled ? string.Empty : "not ")}disabled in database 1 and is {(trigger2.IsDisabled ? string.Empty : "not ")}disabled in database 2");
+ }
- diff.ExistsInDatabase2 = true;
+ if (BaseDifference.CleanDefinitionText(trigger1.TriggerContent, true) != BaseDifference.CleanDefinitionText(trigger2.TriggerContent, true))
+ {
+ diff.Differences.Add("definitions are different");
}
- this.Differences.TableDifferences[fullyQualifiedTableName].TriggerDifferences.Add(trigger1.TriggerName, diff);
+ diff.ExistsInDatabase2 = true;
}
- foreach (var trigger2 in this.Database2.Tables[fullyQualifiedTableName].Triggers.Where(x => !this.Differences.TableDifferences[fullyQualifiedTableName].TriggerDifferences.ContainsKey(x.TriggerName)))
- {
- this.Differences.TableDifferences[fullyQualifiedTableName].TriggerDifferences.Add(trigger2.TriggerName, new ItemDifference(false, true));
- }
+ this.Differences.TableDifferences[fullyQualifiedTableName].TriggerDifferences.Add(trigger1.TriggerName, diff);
}
- private void InspectUserTypes()
+ foreach (var trigger2 in this.Database2.Tables[fullyQualifiedTableName].Triggers.Where(x => !this.Differences.TableDifferences[fullyQualifiedTableName].TriggerDifferences.ContainsKey(x.TriggerName)))
{
- foreach (var userTypeName in this.Database1.UserTypes.Keys)
- {
- var diff = new ItemDifference(true, false);
+ this.Differences.TableDifferences[fullyQualifiedTableName].TriggerDifferences.Add(trigger2.TriggerName, new ItemDifference(false, true));
+ }
+ }
- var userType = this.Database2.UserTypes.FirstOrDefault(x => x.Key == userTypeName);
- if (!userType.Equals(default(KeyValuePair)))
- {
- var item1 = this.Database1.UserTypes[userTypeName];
- var item2 = this.Database2.UserTypes[userTypeName];
+ private void InspectUserTypes()
+ {
+ foreach (var userTypeName in this.Database1.UserTypes.Keys)
+ {
+ var diff = new ItemDifference(true, false);
- if (item1.UnderlyingTypeName != item2.UnderlyingTypeName)
- {
- diff.Differences.Add($"has different underlying type - is {item1.UnderlyingTypeName} in database 1 and is {item2.UnderlyingTypeName} in database 2");
- }
+ var userType = this.Database2.UserTypes.FirstOrDefault(x => x.Key == userTypeName);
+ if (!userType.Equals(default(KeyValuePair)))
+ {
+ var item1 = this.Database1.UserTypes[userTypeName];
+ var item2 = this.Database2.UserTypes[userTypeName];
- if (item1.Precision != item2.Precision)
- {
- diff.Differences.Add($"has different precision - is {(item1.Precision.HasValue ? item1.Precision.Value.ToString() : "NULL")} in database 1 and is {(item2.Precision.HasValue ? item2.Precision.Value.ToString() : "NULL")} in database 2");
- }
+ if (item1.UnderlyingTypeName != item2.UnderlyingTypeName)
+ {
+ diff.Differences.Add($"has different underlying type - is {item1.UnderlyingTypeName} in database 1 and is {item2.UnderlyingTypeName} in database 2");
+ }
- if (item1.Scale != item2.Scale)
- {
- diff.Differences.Add($"has different scale - is {(item1.Scale.HasValue ? item1.Scale.Value.ToString() : "NULL")} in database 1 and is {(item2.Scale.HasValue ? item2.Scale.Value.ToString() : "NULL")} in database 2");
- }
+ if (item1.Precision != item2.Precision)
+ {
+ diff.Differences.Add($"has different precision - is {(item1.Precision.HasValue ? item1.Precision.Value.ToString() : "NULL")} in database 1 and is {(item2.Precision.HasValue ? item2.Precision.Value.ToString() : "NULL")} in database 2");
+ }
- if (item1.MaxLength != item2.MaxLength)
- {
- diff.Differences.Add($"has different max length - is {(item1.MaxLength.HasValue ? item1.MaxLength.Value.ToString() : "NULL")} in database 1 and is {(item2.MaxLength.HasValue ? item2.MaxLength.Value.ToString() : "NULL")} in database 2");
- }
+ if (item1.Scale != item2.Scale)
+ {
+ diff.Differences.Add($"has different scale - is {(item1.Scale.HasValue ? item1.Scale.Value.ToString() : "NULL")} in database 1 and is {(item2.Scale.HasValue ? item2.Scale.Value.ToString() : "NULL")} in database 2");
+ }
- if (item1.IsNullable != item2.IsNullable)
- {
- diff.Differences.Add($"is{(item1.IsNullable ? string.Empty : " not")} nullable in database 1 and is{(item2.IsNullable ? string.Empty : " not")} nullable in database 2");
- }
+ if (item1.MaxLength != item2.MaxLength)
+ {
+ diff.Differences.Add($"has different max length - is {(item1.MaxLength.HasValue ? item1.MaxLength.Value.ToString() : "NULL")} in database 1 and is {(item2.MaxLength.HasValue ? item2.MaxLength.Value.ToString() : "NULL")} in database 2");
+ }
- if (item1.CollationName != item2.CollationName)
- {
- diff.Differences.Add($"has different collation - is {(string.IsNullOrEmpty(item1.CollationName) ? "NULL" : item1.CollationName)} in database 1 and is {(string.IsNullOrEmpty(item2.CollationName) ? "NULL" : item2.CollationName)} in database 2");
- }
+ if (item1.IsNullable != item2.IsNullable)
+ {
+ diff.Differences.Add($"is{(item1.IsNullable ? string.Empty : " not")} nullable in database 1 and is{(item2.IsNullable ? string.Empty : " not")} nullable in database 2");
+ }
- if (item1.IsAssemblyType != item2.IsAssemblyType)
- {
- diff.Differences.Add($"is{(item1.IsAssemblyType ? string.Empty : " not")} assembly type in database 1 and is{(item2.IsAssemblyType ? string.Empty : " not")} assembly type in database 2");
- }
+ if (item1.CollationName != item2.CollationName)
+ {
+ diff.Differences.Add($"has different collation - is {(string.IsNullOrEmpty(item1.CollationName) ? "NULL" : item1.CollationName)} in database 1 and is {(string.IsNullOrEmpty(item2.CollationName) ? "NULL" : item2.CollationName)} in database 2");
+ }
- diff.ExistsInDatabase2 = true;
+ if (item1.IsAssemblyType != item2.IsAssemblyType)
+ {
+ diff.Differences.Add($"is{(item1.IsAssemblyType ? string.Empty : " not")} assembly type in database 1 and is{(item2.IsAssemblyType ? string.Empty : " not")} assembly type in database 2");
}
- this.Differences.UserTypeDifferences.Add(userTypeName, diff);
+ diff.ExistsInDatabase2 = true;
}
- foreach (var userType in this.Database2.UserTypes.Where(x => !this.Differences.UserTypeDifferences.ContainsKey(x.Key)))
- {
- this.Differences.UserTypeDifferences.Add(userType.Key, new ItemDifference(false, true));
- }
+ this.Differences.UserTypeDifferences.Add(userTypeName, diff);
}
- private void InspectSynonyms()
+ foreach (var userType in this.Database2.UserTypes.Where(x => !this.Differences.UserTypeDifferences.ContainsKey(x.Key)))
{
- foreach (var synonymName in this.Database1.Synonyms.Keys)
- {
- var diff = new DatabaseObjectDifference(true, false);
-
- var synonym = this.Database2.Synonyms.FirstOrDefault(x => x.Key == synonymName);
- if (!synonym.Equals(default(KeyValuePair)))
- {
- if (this.Options.CompareProperties)
- {
- this.InspectObjectProperties(synonymName, diff);
- }
+ this.Differences.UserTypeDifferences.Add(userType.Key, new ItemDifference(false, true));
+ }
+ }
- if (this.Options.ComparePermissions)
- {
- this.InspectObjectPermissions(synonymName, PermissionObjectType.Synonym, diff);
- }
+ private void InspectSynonyms()
+ {
+ foreach (var synonymName in this.Database1.Synonyms.Keys)
+ {
+ var diff = new DatabaseObjectDifference(true, false);
- diff.ObjectDefinition1 = this.Database1.Synonyms[synonymName];
- diff.ObjectDefinition2 = this.Database2.Synonyms[synonymName];
+ var synonym = this.Database2.Synonyms.FirstOrDefault(x => x.Key == synonymName);
+ if (!synonym.Equals(default(KeyValuePair)))
+ {
+ if (this.Options.CompareProperties)
+ {
+ this.InspectObjectProperties(synonymName, diff);
+ }
- diff.ExistsInDatabase2 = true;
+ if (this.Options.ComparePermissions)
+ {
+ this.InspectObjectPermissions(synonymName, PermissionObjectType.Synonym, diff);
}
- this.Differences.SynonymDifferences.Add(synonymName, diff);
- }
+ diff.ObjectDefinition1 = this.Database1.Synonyms[synonymName];
+ diff.ObjectDefinition2 = this.Database2.Synonyms[synonymName];
- foreach (var synonym in this.Database2.Synonyms.Where(x => !this.Differences.SynonymDifferences.ContainsKey(x.Key)))
- {
- this.Differences.SynonymDifferences.Add(synonym.Key, new DatabaseObjectDifference(false, true));
+ diff.ExistsInDatabase2 = true;
}
+
+ this.Differences.SynonymDifferences.Add(synonymName, diff);
}
- private void InspectViews()
+ foreach (var synonym in this.Database2.Synonyms.Where(x => !this.Differences.SynonymDifferences.ContainsKey(x.Key)))
{
- foreach (var viewName in this.Database1.Views.Keys)
- {
- var diff = new DatabaseObjectDifference(true, false);
+ this.Differences.SynonymDifferences.Add(synonym.Key, new DatabaseObjectDifference(false, true));
+ }
+ }
- var view = this.Database2.Views.FirstOrDefault(x => x.Key == viewName);
- if (!view.Equals(default(KeyValuePair)))
- {
- if (this.Options.CompareProperties)
- {
- this.InspectObjectProperties(viewName, diff);
- }
+ private void InspectViews()
+ {
+ foreach (var viewName in this.Database1.Views.Keys)
+ {
+ var diff = new DatabaseObjectDifference(true, false);
- if (this.Options.ComparePermissions)
- {
- this.InspectObjectPermissions(viewName, PermissionObjectType.View, diff);
- }
+ var view = this.Database2.Views.FirstOrDefault(x => x.Key == viewName);
+ if (!view.Equals(default(KeyValuePair)))
+ {
+ if (this.Options.CompareProperties)
+ {
+ this.InspectObjectProperties(viewName, diff);
+ }
- diff.ObjectDefinition1 = this.Database1.Views[viewName];
- diff.ObjectDefinition2 = view.Value;
+ if (this.Options.ComparePermissions)
+ {
+ this.InspectObjectPermissions(viewName, PermissionObjectType.View, diff);
+ }
- if (diff.DefinitionsAreDifferent)
- {
- this.DefinitionDifferences.Add(viewName, (diff.ObjectDefinition1, diff.ObjectDefinition2));
- }
+ diff.ObjectDefinition1 = this.Database1.Views[viewName];
+ diff.ObjectDefinition2 = view.Value;
- diff.ExistsInDatabase2 = true;
+ if (diff.DefinitionsAreDifferent)
+ {
+ this.DefinitionDifferences.Add(viewName, (diff.ObjectDefinition1, diff.ObjectDefinition2));
}
- this.Differences.ViewDifferences.Add(viewName, diff);
+ diff.ExistsInDatabase2 = true;
}
- foreach (var view in this.Database2.Views.Where(x => !this.Differences.ViewDifferences.ContainsKey(x.Key)))
- {
- this.Differences.ViewDifferences.Add(view.Key, new DatabaseObjectDifference(false, true));
- }
+ this.Differences.ViewDifferences.Add(viewName, diff);
}
- private void InspectRoutines()
+ foreach (var view in this.Database2.Views.Where(x => !this.Differences.ViewDifferences.ContainsKey(x.Key)))
{
- foreach (var routineName in this.Database1.UserRoutines.Keys)
- {
- var diff = new DatabaseObjectDifference(true, false);
- var isFunction = this.Database1.UserRoutines[routineName].RoutineType.ToLower() == "function";
-
- var routine = this.Database2.UserRoutines.FirstOrDefault(x => x.Key == routineName);
- if (!routine.Equals(default(KeyValuePair)))
- {
- if (this.Options.CompareProperties)
- {
- this.InspectObjectProperties(routineName, diff);
- }
-
- if (this.Options.ComparePermissions)
- {
- this.InspectObjectPermissions(routineName, isFunction ? PermissionObjectType.SqlFunction : PermissionObjectType.SqlStoredProcedure, diff);
- }
-
- diff.ObjectDefinition1 = this.Database1.UserRoutines[routineName].RoutineDefinition;
- diff.ObjectDefinition2 = routine.Value.RoutineDefinition;
+ this.Differences.ViewDifferences.Add(view.Key, new DatabaseObjectDifference(false, true));
+ }
+ }
- if (diff.DefinitionsAreDifferent)
- {
- this.DefinitionDifferences.Add(routineName, (diff.ObjectDefinition1, diff.ObjectDefinition2));
- }
+ private void InspectRoutines()
+ {
+ foreach (var routineName in this.Database1.UserRoutines.Keys)
+ {
+ var diff = new DatabaseObjectDifference(true, false);
+ var isFunction = this.Database1.UserRoutines[routineName].RoutineType.Equals("function", StringComparison.CurrentCultureIgnoreCase);
- diff.ExistsInDatabase2 = true;
+ var routine = this.Database2.UserRoutines.FirstOrDefault(x => x.Key == routineName);
+ if (!routine.Equals(default(KeyValuePair)))
+ {
+ if (this.Options.CompareProperties)
+ {
+ this.InspectObjectProperties(routineName, diff);
}
- if (isFunction)
+ if (this.Options.ComparePermissions)
{
- this.Differences.FunctionDifferences.Add(routineName, diff);
+ this.InspectObjectPermissions(routineName, isFunction ? PermissionObjectType.SqlFunction : PermissionObjectType.SqlStoredProcedure, diff);
}
- else
+
+ diff.ObjectDefinition1 = this.Database1.UserRoutines[routineName].RoutineDefinition;
+ diff.ObjectDefinition2 = routine.Value.RoutineDefinition;
+
+ if (diff.DefinitionsAreDifferent)
{
- this.Differences.StoredProcedureDifferences.Add(routineName, diff);
+ this.DefinitionDifferences.Add(routineName, (diff.ObjectDefinition1, diff.ObjectDefinition2));
}
+
+ diff.ExistsInDatabase2 = true;
+ }
+
+ if (isFunction)
+ {
+ this.Differences.FunctionDifferences.Add(routineName, diff);
+ }
+ else
+ {
+ this.Differences.StoredProcedureDifferences.Add(routineName, diff);
}
+ }
- foreach (var routineName in this.Database2.UserRoutines.Keys)
+ foreach (var routineName in this.Database2.UserRoutines.Keys)
+ {
+ if (this.Database2.UserRoutines[routineName].RoutineType.Equals("function", StringComparison.CurrentCultureIgnoreCase))
{
- if (this.Database2.UserRoutines[routineName].RoutineType.ToLower() == "function")
+ if (!this.Differences.FunctionDifferences.ContainsKey(routineName))
{
- if (!this.Differences.FunctionDifferences.ContainsKey(routineName))
- {
- this.Differences.FunctionDifferences.Add(routineName, new DatabaseObjectDifference(false, true));
- }
+ this.Differences.FunctionDifferences.Add(routineName, new DatabaseObjectDifference(false, true));
}
- else
+ }
+ else
+ {
+ if (!this.Differences.StoredProcedureDifferences.ContainsKey(routineName))
{
- if (!this.Differences.StoredProcedureDifferences.ContainsKey(routineName))
- {
- this.Differences.StoredProcedureDifferences.Add(routineName, new DatabaseObjectDifference(false, true));
- }
+ this.Differences.StoredProcedureDifferences.Add(routineName, new DatabaseObjectDifference(false, true));
}
}
}
+ }
- private void InspectObjectProperties(string fullyQualifiedObjectName, DatabaseObjectDifference objectDiff)
+ private void InspectObjectProperties(string fullyQualifiedObjectName, DatabaseObjectDifference objectDiff)
+ {
+ foreach (var property1 in this.Database1.ExtendedProperties)
{
- foreach (var property1 in this.Database1.ExtendedProperties)
+ var propertyObjectName = property1.ObjectName.PrependSchemaName(property1.ObjectSchema);
+ if (property1.Type == PropertyObjectType.Routine && propertyObjectName == fullyQualifiedObjectName)
{
- var propertyObjectName = property1.ObjectName.PrependSchemaName(property1.ObjectSchema);
- if (property1.Type == PropertyObjectType.Routine && propertyObjectName == fullyQualifiedObjectName)
- {
- var diff = new ExtendedPropertyDifference(true, false);
-
- var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
- if (property2 != null)
- {
- diff.ExistsInDatabase2 = true;
- diff.Value1 = property1.PropertyValue;
- diff.Value2 = property2.PropertyValue;
- }
+ var diff = new ExtendedPropertyDifference(true, false);
- objectDiff.ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
+ var property2 = this.Database2.ExtendedProperties.FirstOrDefault(x => x.FullId == property1.FullId);
+ if (property2 != null)
+ {
+ diff.ExistsInDatabase2 = true;
+ diff.Value1 = property1.PropertyValue;
+ diff.Value2 = property2.PropertyValue;
}
+
+ objectDiff.ExtendedPropertyDifferences.Add(property1.PropertyName, diff);
}
+ }
- foreach (var property2 in this.Database2.ExtendedProperties)
+ foreach (var property2 in this.Database2.ExtendedProperties)
+ {
+ var propertyObjectName = property2.ObjectName.PrependSchemaName(property2.ObjectSchema);
+ if (property2.Type == PropertyObjectType.Routine &&
+ propertyObjectName == fullyQualifiedObjectName &&
+ !objectDiff.ExtendedPropertyDifferences.ContainsKey(property2.PropertyName))
{
- var propertyObjectName = property2.ObjectName.PrependSchemaName(property2.ObjectSchema);
- if (property2.Type == PropertyObjectType.Routine &&
- propertyObjectName == fullyQualifiedObjectName &&
- !objectDiff.ExtendedPropertyDifferences.ContainsKey(property2.PropertyName))
- {
- objectDiff.ExtendedPropertyDifferences.Add(property2.PropertyName, new ExtendedPropertyDifference(false, true));
- }
+ objectDiff.ExtendedPropertyDifferences.Add(property2.PropertyName, new ExtendedPropertyDifference(false, true));
}
}
+ }
- private void InspectObjectPermissions(string fullyQualifiedObjectName, PermissionObjectType objectType, DatabaseObjectDifference objectDiff)
+ private void InspectObjectPermissions(string fullyQualifiedObjectName, PermissionObjectType objectType, DatabaseObjectDifference objectDiff)
+ {
+ foreach (var permission1 in this.Database1.Permissions)
{
- foreach (var permission1 in this.Database1.Permissions)
+ var permissionObjectName = permission1.ObjectName.PrependSchemaName(permission1.ObjectSchema);
+ if (permission1.Type == objectType && permissionObjectName == fullyQualifiedObjectName)
{
- var permissionObjectName = permission1.ObjectName.PrependSchemaName(permission1.ObjectSchema);
- if (permission1.Type == objectType && permissionObjectName == fullyQualifiedObjectName)
- {
- objectDiff.PermissionDifferences.Add(
- permission1.ToString(),
- new BaseDifference(true, this.Database2.Permissions.Exists(x => x.FullId == permission1.FullId)));
- }
+ objectDiff.PermissionDifferences.Add(
+ permission1.ToString(),
+ new BaseDifference(true, this.Database2.Permissions.Exists(x => x.FullId == permission1.FullId)));
}
+ }
- foreach (var permission2 in this.Database2.Permissions)
+ foreach (var permission2 in this.Database2.Permissions)
+ {
+ var permissionObjectName = permission2.ObjectName.PrependSchemaName(permission2.ObjectSchema);
+ if (permission2.Type == objectType &&
+ permissionObjectName == fullyQualifiedObjectName &&
+ !objectDiff.PermissionDifferences.ContainsKey(permission2.ToString()))
{
- var permissionObjectName = permission2.ObjectName.PrependSchemaName(permission2.ObjectSchema);
- if (permission2.Type == objectType &&
- permissionObjectName == fullyQualifiedObjectName &&
- !objectDiff.PermissionDifferences.ContainsKey(permission2.ToString()))
- {
- objectDiff.PermissionDifferences.Add(permission2.ToString(), new BaseDifference(false, true));
- }
+ objectDiff.PermissionDifferences.Add(permission2.ToString(), new BaseDifference(false, true));
}
}
}
diff --git a/src/QuickCompareModel/IDifferenceBuilder.cs b/src/QuickCompareModel/IDifferenceBuilder.cs
index 1bf3a51..a3395d4 100644
--- a/src/QuickCompareModel/IDifferenceBuilder.cs
+++ b/src/QuickCompareModel/IDifferenceBuilder.cs
@@ -2,39 +2,39 @@
// Copyright (c) Dan Ware. All rights reserved.
//
-namespace QuickCompareModel
+namespace QuickCompareModel;
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using QuickCompareModel.DatabaseDifferences;
+using QuickCompareModel.DatabaseSchema;
+using QuickCompareModel.Models;
+
+///
+/// Class responsible for building a set of differences between two database instances.
+///
+public interface IDifferenceBuilder
{
- using System;
- using System.Collections.Generic;
- using System.Threading.Tasks;
- using QuickCompareModel.DatabaseDifferences;
- using QuickCompareModel.DatabaseSchema;
-
- ///
- /// Class responsible for building a set of differences between two database instances.
- ///
- public interface IDifferenceBuilder
- {
- /// Handler for when the status message changes.
- event EventHandler ComparisonStatusChanged;
-
- /// Gets or sets the options for the comparison.
- QuickCompareOptions Options { get; set; }
-
- /// Gets or sets the model for database 1.
- SqlDatabase Database1 { get; set; }
-
- /// Gets or sets the model for database 2.
- SqlDatabase Database2 { get; set; }
-
- /// Gets or sets the model representing the differences between two databases.
- Differences Differences { get; set; }
-
- /// Gets or sets the dictionary of definitions that are different.
- Dictionary DefinitionDifferences { get; set; }
-
- /// Inspect two database schemas and build the model.
- /// A that represents the asynchronous operation.
- Task BuildDifferencesAsync();
- }
+ /// Handler for when the status message changes.
+ event EventHandler ComparisonStatusChanged;
+
+ /// Gets or sets the options for the comparison.
+ QuickCompareOptions Options { get; set; }
+
+ /// Gets or sets the model for database 1.
+ SqlDatabase Database1 { get; set; }
+
+ /// Gets or sets the model for database 2.
+ SqlDatabase Database2 { get; set; }
+
+ /// Gets or sets the model representing the differences between two databases.
+ Differences Differences { get; set; }
+
+ /// Gets or sets the dictionary of definitions that are different.
+ Dictionary DefinitionDifferences { get; set; }
+
+ /// Inspect two database schemas and build the model.
+ /// A that represents the asynchronous operation.
+ Task BuildDifferencesAsync();
}
\ No newline at end of file
diff --git a/src/QuickCompareModel/Models/DatabaseInstance.cs b/src/QuickCompareModel/Models/DatabaseInstance.cs
new file mode 100644
index 0000000..06386e5
--- /dev/null
+++ b/src/QuickCompareModel/Models/DatabaseInstance.cs
@@ -0,0 +1,18 @@
+//
+// Copyright (c) Dan Ware. All rights reserved.
+//
+
+namespace QuickCompareModel.Models;
+
+/// Enumeration to define which database is in scope.
+public enum DatabaseInstance
+{
+ /// Value is not defined.
+ Unknown,
+
+ /// The first database in the comparison.
+ Database1,
+
+ /// The second database in the comparison.
+ Database2,
+}
diff --git a/src/QuickCompareModel/Models/QuickCompareOptions.cs b/src/QuickCompareModel/Models/QuickCompareOptions.cs
new file mode 100644
index 0000000..ba3d426
--- /dev/null
+++ b/src/QuickCompareModel/Models/QuickCompareOptions.cs
@@ -0,0 +1,81 @@
+//
+// Copyright (c) Dan Ware. All rights reserved.
+//
+
+namespace QuickCompareModel.Models;
+
+///
+/// Settings for the database comparison.
+///
+public class QuickCompareOptions
+{
+ ///
+ /// Gets or sets the connection string for the first database.
+ ///
+ public string ConnectionString1 { get; set; }
+
+ ///
+ /// Gets or sets the connection string for the second database.
+ ///
+ public string ConnectionString2 { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to ignore remarks and comments.
+ ///
+ public bool IgnoreSqlComments { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare table columns.
+ ///
+ public bool CompareColumns { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare text collation.
+ ///
+ public bool CompareCollation { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare table relations.
+ ///
+ public bool CompareRelations { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare views/functions/procedures.
+ ///
+ public bool CompareObjects { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare indexes.
+ ///
+ public bool CompareIndexes { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare permissions.
+ ///
+ public bool ComparePermissions { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare extended properties.
+ ///
+ public bool CompareProperties { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare triggers.
+ ///
+ public bool CompareTriggers { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare synonyms.
+ ///
+ public bool CompareSynonyms { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare ordinal position of columns.
+ ///
+ public bool CompareOrdinalPositions { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to compare user types.
+ ///
+ public bool CompareUserTypes { get; set; } = true;
+}
diff --git a/src/QuickCompareModel/Models/StatusChangedEventArgs.cs b/src/QuickCompareModel/Models/StatusChangedEventArgs.cs
new file mode 100644
index 0000000..8072ab6
--- /dev/null
+++ b/src/QuickCompareModel/Models/StatusChangedEventArgs.cs
@@ -0,0 +1,27 @@
+//
+// Copyright (c) Dan Ware. All rights reserved.
+//
+
+namespace QuickCompareModel.Models;
+
+using System;
+
+/// Custom derivative of to contain a status message.
+/// Current status message.
+[Serializable]
+public class StatusChangedEventArgs(string statusMessage)
+ : EventArgs
+{
+ /// Initialises a new instance of the class.
+ /// Current status message.
+ /// The database in scope.
+ public StatusChangedEventArgs(string statusMessage, DatabaseInstance databaseInstance)
+ : this(statusMessage) => this.DatabaseInstance = databaseInstance;
+
+ /// Gets or sets the current status message.
+ public string StatusMessage { get; set; } = statusMessage;
+
+ /// Gets or sets the database in scope.
+ /// Default value is .
+ public DatabaseInstance DatabaseInstance { get; set; } = DatabaseInstance.Unknown;
+}
diff --git a/src/QuickCompareModel/QuickCompareModel.csproj b/src/QuickCompareModel/QuickCompareModel.csproj
index 3642737..93c4441 100644
--- a/src/QuickCompareModel/QuickCompareModel.csproj
+++ b/src/QuickCompareModel/QuickCompareModel.csproj
@@ -1,7 +1,7 @@
- netstandard2.1
+ net8.0
Dan Ware
QuickCompare
database compare;database comparison;database schema;schema checker;schema compare;schema comparison;database schema compare;database schema comparison
@@ -25,7 +25,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/QuickCompareModel/QuickCompareOptions.cs b/src/QuickCompareModel/QuickCompareOptions.cs
deleted file mode 100644
index 17a1fa1..0000000
--- a/src/QuickCompareModel/QuickCompareOptions.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// Copyright (c) Dan Ware. All rights reserved.
-//
-
-namespace QuickCompareModel
-{
- ///
- /// Settings for the database comparison.
- ///
- public class QuickCompareOptions
- {
- ///
- /// Gets or sets the connection string for the first database.
- ///
- public string ConnectionString1 { get; set; }
-
- ///
- /// Gets or sets the connection string for the second database.
- ///
- public string ConnectionString2 { get; set; }
-
- ///
- /// Gets or sets a value indicating whether to ignore remarks and comments.
- ///
- public bool IgnoreSqlComments { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare table columns.
- ///
- public bool CompareColumns { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare text collation.
- ///
- public bool CompareCollation { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare table relations.
- ///
- public bool CompareRelations { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare views/functions/procedures.
- ///
- public bool CompareObjects { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare indexes.
- ///
- public bool CompareIndexes { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare permissions.
- ///
- public bool ComparePermissions { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare extended properties.
- ///
- public bool CompareProperties { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare triggers.
- ///
- public bool CompareTriggers { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare synonyms.
- ///
- public bool CompareSynonyms { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare ordinal position of columns.
- ///
- public bool CompareOrdinalPositions { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to compare user types.
- ///
- public bool CompareUserTypes { get; set; } = true;
- }
-}
diff --git a/src/QuickCompareModel/StatusChangedEventArgs.cs b/src/QuickCompareModel/StatusChangedEventArgs.cs
deleted file mode 100644
index 3113638..0000000
--- a/src/QuickCompareModel/StatusChangedEventArgs.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) Dan Ware. All rights reserved.
-//
-
-namespace QuickCompareModel
-{
- using System;
-
- /// Custom derivative of to contain a status message.
- [Serializable]
- public class StatusChangedEventArgs : EventArgs
- {
- /// Initialises a new instance of the class.
- /// Current status message.
- public StatusChangedEventArgs(string statusMessage) => this.StatusMessage = statusMessage;
-
- /// Initialises a new instance of the class.
- /// Current status message.
- /// The database in scope.
- public StatusChangedEventArgs(string statusMessage, DatabaseInstance databaseInstance)
- : this(statusMessage) => this.DatabaseInstance = databaseInstance;
-
- /// Gets or sets the current status message.
- public string StatusMessage { get; set; }
-
- /// Gets or sets the database in scope.
- /// Default value is .
- public DatabaseInstance DatabaseInstance { get; set; } = DatabaseInstance.Unknown;
- }
-}
diff --git a/src/WinQuickCompare/App.xaml.cs b/src/WinQuickCompare/App.xaml.cs
index a1f3829..b9c57b0 100644
--- a/src/WinQuickCompare/App.xaml.cs
+++ b/src/WinQuickCompare/App.xaml.cs
@@ -40,8 +40,8 @@ private void AppDomain_UnhandledException(object sender, UnhandledExceptionEvent
private void ReadApplicationPropertiesFromFile()
{
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
- using IsolatedStorageFileStream stream = new (Filename, FileMode.OpenOrCreate, storage);
- using StreamReader reader = new (stream);
+ using IsolatedStorageFileStream stream = new(Filename, FileMode.OpenOrCreate, storage);
+ using StreamReader reader = new(stream);
while (!reader.EndOfStream)
{
this.SetPropertyFromLineOfText(reader.ReadLine());
@@ -51,15 +51,15 @@ private void ReadApplicationPropertiesFromFile()
private void SetPropertyFromLineOfText(string line)
{
string key = line[..line.IndexOf(',')];
- string value = line[(line.IndexOf(',') + 1) ..];
+ string value = line[(line.IndexOf(',') + 1)..];
this.Properties[key] = value;
}
private void WriteApplicationPropertiesToFile()
{
using IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
- using IsolatedStorageFileStream stream = new (Filename, FileMode.Create, storage);
- using StreamWriter writer = new (stream);
+ using IsolatedStorageFileStream stream = new(Filename, FileMode.Create, storage);
+ using StreamWriter writer = new(stream);
foreach (string key in this.Properties.Keys)
{
writer.WriteLine("{0},{1}", key, this.Properties[key]);
diff --git a/src/WinQuickCompare/MainWindow.xaml.cs b/src/WinQuickCompare/MainWindow.xaml.cs
index ebabe2b..32362aa 100644
--- a/src/WinQuickCompare/MainWindow.xaml.cs
+++ b/src/WinQuickCompare/MainWindow.xaml.cs
@@ -8,6 +8,7 @@ namespace QuickCompare;
using System.Windows;
using System.Windows.Controls;
using QuickCompareModel;
+using QuickCompareModel.Models;
/// Interaction logic for the main window.
public partial class MainWindow : Window
@@ -23,7 +24,7 @@ private async void ButtonRunComparison_Click(object sender, RoutedEventArgs e)
try
{
var context = (QuickCompareContext)this.FindResource(nameof(QuickCompareContext));
- DifferenceBuilder builder = new (context.OptionsFromProperties());
+ DifferenceBuilder builder = new(context.OptionsFromProperties());
builder.ComparisonStatusChanged += this.Comparison_StatusChanged;
await builder.BuildDifferencesAsync();
diff --git a/src/WinQuickCompare/QuickCompareContext.cs b/src/WinQuickCompare/QuickCompareContext.cs
index 5aed827..311a769 100644
--- a/src/WinQuickCompare/QuickCompareContext.cs
+++ b/src/WinQuickCompare/QuickCompareContext.cs
@@ -7,7 +7,7 @@ namespace QuickCompare;
using System.ComponentModel;
using System.Windows;
using Microsoft.Extensions.Options;
-using QuickCompareModel;
+using QuickCompareModel.Models;
///
/// View model class which uses application properties to persist form input between restarts.
@@ -112,7 +112,7 @@ public bool CompareUserTypes
/// Instance of .
public IOptions OptionsFromProperties()
{
- QuickCompareOptions settings = new ()
+ QuickCompareOptions settings = new()
{
ConnectionString1 = this.ConnectionString1,
ConnectionString2 = this.ConnectionString2,
@@ -138,7 +138,7 @@ protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
- PropertyChangedEventArgs e = new (propertyName);
+ PropertyChangedEventArgs e = new(propertyName);
this.PropertyChanged(this, e);
}
}
diff --git a/src/WinQuickCompare/WinQuickCompare.csproj b/src/WinQuickCompare/WinQuickCompare.csproj
index 55efdd9..c2c1e06 100644
--- a/src/WinQuickCompare/WinQuickCompare.csproj
+++ b/src/WinQuickCompare/WinQuickCompare.csproj
@@ -14,7 +14,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/QuickCompareTests/BaseDifferenceTests.cs b/test/QuickCompareTests/BaseDifferenceTests.cs
index 2489a94..e9e112f 100644
--- a/test/QuickCompareTests/BaseDifferenceTests.cs
+++ b/test/QuickCompareTests/BaseDifferenceTests.cs
@@ -29,7 +29,8 @@ public void CleanDefinitionText_Strips_SingleLineComments() =>
"-- Line comment\r\n" +
"SELECT * -- Inline comment\r\n" +
"FROM Table\r\n" +
- "-- Line comment", DoNotStripWhitespace)
+ "-- Line comment",
+ DoNotStripWhitespace)
.Should().Be("SELECT * \r\nFROM Table");
/// Test multi-line comments are stripped.
@@ -38,7 +39,8 @@ public void CleanDefinitionText_Strips_MultiLineComments() =>
BaseDifference.CleanDefinitionText(
"/******************\r\n" +
" ** Comment body **\r\n" +
- " ******************/ SELECT * FROM Table", DoNotStripWhitespace)
+ " ******************/ SELECT * FROM Table",
+ DoNotStripWhitespace)
.Should().Be("SELECT * FROM Table");
/// Test enclosed comments are stripped.
@@ -53,7 +55,8 @@ public void CleanDefinitionText_Strips_EnclosedComments() =>
public void CleanDefinitionText_Normalises_CommaWhitespace() =>
BaseDifference.CleanDefinitionText(
"SELECT ID , Name ,Email, Phone , FootSize\r" +
- ",Timestamp FROM Table", StripWhitespace)
+ ",Timestamp FROM Table",
+ StripWhitespace)
.Should().Be("SELECT ID, Name, Email, Phone, FootSize, Timestamp FROM Table");
/// Test whitespace gets condensed to a single space.
diff --git a/test/QuickCompareTests/QuickCompareTests.csproj b/test/QuickCompareTests/QuickCompareTests.csproj
index c47cf41..527a149 100644
--- a/test/QuickCompareTests/QuickCompareTests.csproj
+++ b/test/QuickCompareTests/QuickCompareTests.csproj
@@ -13,7 +13,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/QuickCompareTests/RelationCompareTests.cs b/test/QuickCompareTests/RelationCompareTests.cs
index aebb219..dcb26d3 100644
--- a/test/QuickCompareTests/RelationCompareTests.cs
+++ b/test/QuickCompareTests/RelationCompareTests.cs
@@ -4,6 +4,7 @@
namespace QuickCompareTests;
+using System.Threading.Tasks;
using FluentAssertions;
using QuickCompareModel.DatabaseSchema;
using Xunit;
@@ -17,8 +18,9 @@ public class RelationCompareTests
private const string TableName = "[dbo].[Table1]";
/// Test relation difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void RelationMissingFromDatabase1_IsReported()
+ public async Task RelationMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -28,7 +30,7 @@ public void RelationMissingFromDatabase1_IsReported()
builder.Database2.Tables[TableName].Relations.Add(new SqlRelation { RelationName = RelationName });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences[TableName]
@@ -43,8 +45,9 @@ public void RelationMissingFromDatabase1_IsReported()
}
/// Test relation difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void RelationMissingFromDatabase2_IsReported()
+ public async Task RelationMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -54,7 +57,7 @@ public void RelationMissingFromDatabase2_IsReported()
builder.Database2.Tables.Add(TableName, new SqlTable());
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences[TableName]
@@ -69,8 +72,9 @@ public void RelationMissingFromDatabase2_IsReported()
}
/// Test relation difference is not reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void RelationsInBothDatabases_AreNotReported()
+ public async Task RelationsInBothDatabases_AreNotReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -81,7 +85,7 @@ public void RelationsInBothDatabases_AreNotReported()
builder.Database2.Tables[TableName].Relations.Add(new SqlRelation { RelationName = RelationName });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences[TableName]
diff --git a/test/QuickCompareTests/StoredProcedureCompareTests.cs b/test/QuickCompareTests/StoredProcedureCompareTests.cs
index 5d354db..c838fd8 100644
--- a/test/QuickCompareTests/StoredProcedureCompareTests.cs
+++ b/test/QuickCompareTests/StoredProcedureCompareTests.cs
@@ -4,6 +4,7 @@
namespace QuickCompareTests;
+using System.Threading.Tasks;
using FluentAssertions;
using QuickCompareModel.DatabaseSchema;
using Xunit;
@@ -17,15 +18,16 @@ public class StoredProcedureCompareTests
private const string StoredProcedureRoutineType = "PROCEDURE";
/// Test stored procedure difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void StoredProcedureMissingFromDatabase1_IsReported()
+ public async Task StoredProcedureMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
builder.Database2.UserRoutines.Add(StoredProcedureName, new SqlUserRoutine { RoutineType = StoredProcedureRoutineType });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.StoredProcedureDifferences.Should().ContainKey(StoredProcedureName);
@@ -37,15 +39,16 @@ public void StoredProcedureMissingFromDatabase1_IsReported()
}
/// Test stored procedure difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void StoredProcedureMissingFromDatabase2_IsReported()
+ public async Task StoredProcedureMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
builder.Database1.UserRoutines.Add(StoredProcedureName, new SqlUserRoutine { RoutineType = StoredProcedureRoutineType });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.StoredProcedureDifferences.Should().ContainKey(StoredProcedureName);
@@ -57,8 +60,9 @@ public void StoredProcedureMissingFromDatabase2_IsReported()
}
/// Test stored procedure difference is not reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void StoredProceduresInBothDatabases_AreNotReported()
+ public async Task StoredProceduresInBothDatabases_AreNotReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -66,7 +70,7 @@ public void StoredProceduresInBothDatabases_AreNotReported()
builder.Database2.UserRoutines.Add(StoredProcedureName, new SqlUserRoutine { RoutineType = StoredProcedureRoutineType });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.StoredProcedureDifferences.Should().ContainKey(StoredProcedureName);
@@ -77,8 +81,9 @@ public void StoredProceduresInBothDatabases_AreNotReported()
}
/// Test stored procedure difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void StoredProcedureDefinitionDifference_IsReported()
+ public async Task StoredProcedureDefinitionDifference_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -86,7 +91,7 @@ public void StoredProcedureDefinitionDifference_IsReported()
builder.Database2.UserRoutines.Add(StoredProcedureName, new SqlUserRoutine { RoutineType = StoredProcedureRoutineType, RoutineDefinition = "bar" });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.StoredProcedureDifferences.Should().ContainKey(StoredProcedureName);
@@ -97,8 +102,9 @@ public void StoredProcedureDefinitionDifference_IsReported()
}
/// Test stored procedure difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void StoredProcedurePropertyMissingFromDatabase1_IsReported()
+ public async Task StoredProcedurePropertyMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -115,7 +121,7 @@ public void StoredProcedurePropertyMissingFromDatabase1_IsReported()
});
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.StoredProcedureDifferences.Should().ContainKey(StoredProcedureName);
@@ -127,8 +133,9 @@ public void StoredProcedurePropertyMissingFromDatabase1_IsReported()
}
/// Test stored procedure difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void StoredProcedurePropertyMissingFromDatabase2_IsReported()
+ public async Task StoredProcedurePropertyMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -145,7 +152,7 @@ public void StoredProcedurePropertyMissingFromDatabase2_IsReported()
});
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.StoredProcedureDifferences.Should().ContainKey(StoredProcedureName);
@@ -157,8 +164,9 @@ public void StoredProcedurePropertyMissingFromDatabase2_IsReported()
}
/// Test stored procedure difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void StoredProcedurePropertyDifference_IsReported()
+ public async Task StoredProcedurePropertyDifference_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -184,7 +192,7 @@ public void StoredProcedurePropertyDifference_IsReported()
});
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.StoredProcedureDifferences.Should().ContainKey(StoredProcedureName);
diff --git a/test/QuickCompareTests/SynonymCompareTests.cs b/test/QuickCompareTests/SynonymCompareTests.cs
index 6e4875a..757f858 100644
--- a/test/QuickCompareTests/SynonymCompareTests.cs
+++ b/test/QuickCompareTests/SynonymCompareTests.cs
@@ -4,6 +4,7 @@
namespace QuickCompareTests;
+using System.Threading.Tasks;
using FluentAssertions;
using Xunit;
@@ -13,8 +14,9 @@ namespace QuickCompareTests;
public class SynonymCompareTests
{
/// Test synonym difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void SynonymMissingFromDatabase1_IsReported()
+ public async Task SynonymMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -23,7 +25,7 @@ public void SynonymMissingFromDatabase1_IsReported()
builder.Database2.Synonyms.Add(synonymName, "foobar");
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.SynonymDifferences.Should().ContainKey(synonymName);
@@ -35,8 +37,9 @@ public void SynonymMissingFromDatabase1_IsReported()
}
/// Test synonym difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void SynonymMissingFromDatabase2_IsReported()
+ public async Task SynonymMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -45,7 +48,7 @@ public void SynonymMissingFromDatabase2_IsReported()
builder.Database1.Synonyms.Add(synonymName, "foobar");
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.SynonymDifferences.Should().ContainKey(synonymName);
@@ -57,8 +60,9 @@ public void SynonymMissingFromDatabase2_IsReported()
}
/// Test synonym difference is not reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void SynonymsInBothDatabases_AreNotReported()
+ public async Task SynonymsInBothDatabases_AreNotReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -68,7 +72,7 @@ public void SynonymsInBothDatabases_AreNotReported()
builder.Database2.Synonyms.Add(synonymName, "foobar");
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.SynonymDifferences.Should().ContainKey(synonymName);
diff --git a/test/QuickCompareTests/TableCompareTests.cs b/test/QuickCompareTests/TableCompareTests.cs
index 613872b..ad6721b 100644
--- a/test/QuickCompareTests/TableCompareTests.cs
+++ b/test/QuickCompareTests/TableCompareTests.cs
@@ -5,6 +5,7 @@
namespace QuickCompareTests;
using System.Collections.Generic;
+using System.Threading.Tasks;
using FluentAssertions;
using QuickCompareModel.DatabaseSchema;
using Xunit;
@@ -18,15 +19,16 @@ public class TableCompareTests
private const string TabIndent = " ";
/// Test table difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TableMissingFromDatabase1_IsReported()
+ public async Task TableMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
builder.Database2.Tables.Add(TableName, new SqlTable());
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -38,15 +40,16 @@ public void TableMissingFromDatabase1_IsReported()
}
/// Test table difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TableMissingFromDatabase2_IsReported()
+ public async Task TableMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
builder.Database1.Tables.Add(TableName, new SqlTable());
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -58,8 +61,9 @@ public void TableMissingFromDatabase2_IsReported()
}
/// Test table difference is not reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TablesInBothDatabases_AreNotReported()
+ public async Task TablesInBothDatabases_AreNotReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -67,7 +71,7 @@ public void TablesInBothDatabases_AreNotReported()
builder.Database2.Tables.Add(TableName, new SqlTable());
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -80,8 +84,9 @@ public void TablesInBothDatabases_AreNotReported()
}
/// Test table difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TablePropertyMissingFromDatabase1_IsReported()
+ public async Task TablePropertyMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -99,7 +104,7 @@ public void TablePropertyMissingFromDatabase1_IsReported()
});
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -117,8 +122,9 @@ public void TablePropertyMissingFromDatabase1_IsReported()
}
/// Test table difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TablePropertyMissingFromDatabase2_IsReported()
+ public async Task TablePropertyMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -136,7 +142,7 @@ public void TablePropertyMissingFromDatabase2_IsReported()
});
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -155,8 +161,9 @@ public void TablePropertyMissingFromDatabase2_IsReported()
}
/// Test table difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TablePropertyDifference_IsReported()
+ public async Task TablePropertyDifference_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -184,7 +191,7 @@ public void TablePropertyDifference_IsReported()
});
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -201,8 +208,9 @@ public void TablePropertyDifference_IsReported()
}
/// Test table difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TablePermissionMissingFromDatabase1_IsReported()
+ public async Task TablePermissionMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -219,7 +227,7 @@ public void TablePermissionMissingFromDatabase1_IsReported()
});
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -235,8 +243,9 @@ public void TablePermissionMissingFromDatabase1_IsReported()
}
/// Test table difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TablePermissionMissingFromDatabase2_IsReported()
+ public async Task TablePermissionMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -253,7 +262,7 @@ public void TablePermissionMissingFromDatabase2_IsReported()
});
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -269,8 +278,9 @@ public void TablePermissionMissingFromDatabase2_IsReported()
}
/// Test table difference is not reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TablePermissionInBothDatabases_IsNotReported()
+ public async Task TablePermissionInBothDatabases_IsNotReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -296,7 +306,7 @@ public void TablePermissionInBothDatabases_IsNotReported()
});
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -314,17 +324,18 @@ public void TablePermissionInBothDatabases_IsNotReported()
}
/// Test table difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TableColumn_WithSingleDifference_IsSingleLine()
+ public async Task TableColumn_WithSingleDifference_IsSingleLine()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
- builder.Database1.Tables.Add(TableName, new SqlTable { ColumnDetails = new List { new SqlColumnDetail { ColumnName = "foobar" } } });
+ builder.Database1.Tables.Add(TableName, new SqlTable { ColumnDetails = [new SqlColumnDetail { ColumnName = "foobar" }] });
builder.Database1.Tables[TableName].ColumnDetails[0].OrdinalPosition = 1;
- builder.Database2.Tables.Add(TableName, new SqlTable { ColumnDetails = new List { new SqlColumnDetail { ColumnName = "foobar" } } });
+ builder.Database2.Tables.Add(TableName, new SqlTable { ColumnDetails = [new SqlColumnDetail { ColumnName = "foobar" }] });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
@@ -337,18 +348,19 @@ public void TableColumn_WithSingleDifference_IsSingleLine()
}
/// Test table difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TableColumn_WithMultipleDifferences_IsMultipleLines()
+ public async Task TableColumn_WithMultipleDifferences_IsMultipleLines()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
- builder.Database1.Tables.Add(TableName, new SqlTable { ColumnDetails = new List { new SqlColumnDetail { ColumnName = "foobar" } } });
+ builder.Database1.Tables.Add(TableName, new SqlTable { ColumnDetails = [new SqlColumnDetail { ColumnName = "foobar" }] });
builder.Database1.Tables[TableName].ColumnDetails[0].OrdinalPosition = 1;
builder.Database1.Tables[TableName].ColumnDetails[0].NumericPrecision = 1;
- builder.Database2.Tables.Add(TableName, new SqlTable { ColumnDetails = new List { new SqlColumnDetail { ColumnName = "foobar" } } });
+ builder.Database2.Tables.Add(TableName, new SqlTable { ColumnDetails = [new SqlColumnDetail { ColumnName = "foobar" }] });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences.Should().ContainKey(TableName);
diff --git a/test/QuickCompareTests/TestHelper.cs b/test/QuickCompareTests/TestHelper.cs
index a9883a4..d83e1de 100644
--- a/test/QuickCompareTests/TestHelper.cs
+++ b/test/QuickCompareTests/TestHelper.cs
@@ -7,6 +7,7 @@ namespace QuickCompareTests;
using Microsoft.Extensions.Options;
using QuickCompareModel;
using QuickCompareModel.DatabaseSchema;
+using QuickCompareModel.Models;
///
/// Class to provide common setup methods for tests.
diff --git a/test/QuickCompareTests/TriggerCompareTests.cs b/test/QuickCompareTests/TriggerCompareTests.cs
index 30b7e60..66b74e1 100644
--- a/test/QuickCompareTests/TriggerCompareTests.cs
+++ b/test/QuickCompareTests/TriggerCompareTests.cs
@@ -4,6 +4,7 @@
namespace QuickCompareTests;
+using System.Threading.Tasks;
using FluentAssertions;
using QuickCompareModel.DatabaseSchema;
using Xunit;
@@ -14,8 +15,9 @@ namespace QuickCompareTests;
public class TriggerCompareTests
{
/// Test trigger difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TriggerMissingFromDatabase1_IsReported()
+ public async Task TriggerMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -27,7 +29,7 @@ public void TriggerMissingFromDatabase1_IsReported()
builder.Database2.Tables[tableName].Triggers.Add(new SqlTrigger { TriggerName = triggerName });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences[tableName]
@@ -42,8 +44,9 @@ public void TriggerMissingFromDatabase1_IsReported()
}
/// Test trigger difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TriggerMissingFromDatabase2_IsReported()
+ public async Task TriggerMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -55,7 +58,7 @@ public void TriggerMissingFromDatabase2_IsReported()
builder.Database2.Tables.Add(tableName, new SqlTable());
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences[tableName]
@@ -70,8 +73,9 @@ public void TriggerMissingFromDatabase2_IsReported()
}
/// Test trigger difference is not reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void TriggerInBothDatabases_IsNotReported()
+ public async Task TriggerInBothDatabases_IsNotReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -84,7 +88,7 @@ public void TriggerInBothDatabases_IsNotReported()
builder.Database2.Tables[tableName].Triggers.Add(new SqlTrigger { TriggerName = triggerName, TableName = tableName });
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.TableDifferences[tableName]
diff --git a/test/QuickCompareTests/UserTypeCompareTests.cs b/test/QuickCompareTests/UserTypeCompareTests.cs
index 7061144..7379651 100644
--- a/test/QuickCompareTests/UserTypeCompareTests.cs
+++ b/test/QuickCompareTests/UserTypeCompareTests.cs
@@ -4,6 +4,7 @@
namespace QuickCompareTests;
+using System.Threading.Tasks;
using FluentAssertions;
using QuickCompareModel.DatabaseSchema;
using Xunit;
@@ -14,8 +15,9 @@ namespace QuickCompareTests;
public class UserTypeCompareTests
{
/// Test user type difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void UserTypeMissingFromDatabase1_IsReported()
+ public async Task UserTypeMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -24,7 +26,7 @@ public void UserTypeMissingFromDatabase1_IsReported()
builder.Database2.UserTypes.Add(userTypeName, new SqlUserType());
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.UserTypeDifferences.Should().ContainKey(userTypeName);
@@ -36,8 +38,9 @@ public void UserTypeMissingFromDatabase1_IsReported()
}
/// Test user type difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void UserTypeMissingFromDatabase2_IsReported()
+ public async Task UserTypeMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -46,7 +49,7 @@ public void UserTypeMissingFromDatabase2_IsReported()
builder.Database1.UserTypes.Add(userTypeName, new SqlUserType());
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.UserTypeDifferences.Should().ContainKey(userTypeName);
@@ -58,8 +61,9 @@ public void UserTypeMissingFromDatabase2_IsReported()
}
/// Test user type difference is not reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void UserTypeInBothDatabases_IsNotReported()
+ public async Task UserTypeInBothDatabases_IsNotReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -69,7 +73,7 @@ public void UserTypeInBothDatabases_IsNotReported()
builder.Database2.UserTypes.Add(userTypeName, new SqlUserType());
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.UserTypeDifferences.Should().ContainKey(userTypeName);
@@ -81,48 +85,69 @@ public void UserTypeInBothDatabases_IsNotReported()
}
/// Test user type difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void UnderlyingTypeName_Difference_IsReported() =>
- ComparisonResultContainsValue(new SqlUserType { UnderlyingTypeName = "char" }, "underlying type")
- .Should().BeTrue();
+ public async Task UnderlyingTypeName_Difference_IsReported()
+ {
+ var result = await ComparisonResultContainsValue(new SqlUserType { UnderlyingTypeName = "char" }, "underlying type");
+ result.Should().BeTrue();
+ }
/// Test user type difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void Precision_Difference_IsReported() =>
- ComparisonResultContainsValue(new SqlUserType { Precision = 2 }, "precision")
- .Should().BeTrue();
+ public async Task Precision_Difference_IsReported()
+ {
+ var result = await ComparisonResultContainsValue(new SqlUserType { Precision = 2 }, "precision");
+ result.Should().BeTrue();
+ }
/// Test user type difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void Scale_Difference_IsReported() =>
- ComparisonResultContainsValue(new SqlUserType { Scale = 2 }, "scale")
- .Should().BeTrue();
+ public async Task Scale_Difference_IsReported()
+ {
+ var result = await ComparisonResultContainsValue(new SqlUserType { Scale = 2 }, "scale");
+ result.Should().BeTrue();
+ }
/// Test user type difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void MaxLength_Difference_IsReported() =>
- ComparisonResultContainsValue(new SqlUserType { MaxLength = 2 }, "max length")
- .Should().BeTrue();
+ public async Task MaxLength_Difference_IsReported()
+ {
+ var result = await ComparisonResultContainsValue(new SqlUserType { MaxLength = 2 }, "max length");
+ result.Should().BeTrue();
+ }
/// Test user type difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void IsNullable_Difference_IsReported() =>
- ComparisonResultContainsValue(new SqlUserType { IsNullable = true }, "nullable")
- .Should().BeTrue();
+ public async Task IsNullable_Difference_IsReported()
+ {
+ var result = await ComparisonResultContainsValue(new SqlUserType { IsNullable = true }, "nullable");
+ result.Should().BeTrue();
+ }
/// Test user type difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void CollationName_Difference_IsReported() =>
- ComparisonResultContainsValue(new SqlUserType { CollationName = "foobar" }, "collation")
- .Should().BeTrue();
+ public async Task CollationName_Difference_IsReported()
+ {
+ var result = await ComparisonResultContainsValue(new SqlUserType { CollationName = "foobar" }, "collation");
+ result.Should().BeTrue();
+ }
/// Test user type difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void IsAssemblyType_Difference_IsReported() =>
- ComparisonResultContainsValue(new SqlUserType { IsAssemblyType = true }, "assembly")
- .Should().BeTrue();
+ public async Task IsAssemblyType_Difference_IsReported()
+ {
+ var result = await ComparisonResultContainsValue(new SqlUserType { IsAssemblyType = true }, "assembly");
+ result.Should().BeTrue();
+ }
- private static bool ComparisonResultContainsValue(SqlUserType userType, string value)
+ private static async Task ComparisonResultContainsValue(SqlUserType userType, string value)
{
// Arrange
var userTypeName = "Type1";
@@ -132,7 +157,7 @@ private static bool ComparisonResultContainsValue(SqlUserType userType, string v
builder.Database2.UserTypes.Add(userTypeName, new SqlUserType());
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
var diff = builder.Differences.UserTypeDifferences[userTypeName];
diff --git a/test/QuickCompareTests/ViewCompareTests.cs b/test/QuickCompareTests/ViewCompareTests.cs
index a27b5b1..70848ef 100644
--- a/test/QuickCompareTests/ViewCompareTests.cs
+++ b/test/QuickCompareTests/ViewCompareTests.cs
@@ -4,6 +4,7 @@
namespace QuickCompareTests;
+using System.Threading.Tasks;
using FluentAssertions;
using Xunit;
@@ -13,8 +14,9 @@ namespace QuickCompareTests;
public class ViewCompareTests
{
/// Test view difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void ViewMissingFromDatabase1_IsReported()
+ public async Task ViewMissingFromDatabase1_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -23,7 +25,7 @@ public void ViewMissingFromDatabase1_IsReported()
builder.Database2.Views.Add(viewName, "foobar");
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.ViewDifferences.Should().ContainKey(viewName);
@@ -35,8 +37,9 @@ public void ViewMissingFromDatabase1_IsReported()
}
/// Test view difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void ViewMissingFromDatabase2_IsReported()
+ public async Task ViewMissingFromDatabase2_IsReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -45,7 +48,7 @@ public void ViewMissingFromDatabase2_IsReported()
builder.Database1.Views.Add(viewName, "foobar");
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.ViewDifferences.Should().ContainKey(viewName);
@@ -57,8 +60,9 @@ public void ViewMissingFromDatabase2_IsReported()
}
/// Test view difference is reported.
+ /// A representing the asynchronous unit test.
[Fact]
- public void ViewsInBothDatabases_AreNotReported()
+ public async Task ViewsInBothDatabases_AreNotReported()
{
// Arrange
var builder = TestHelper.GetBasicBuilder();
@@ -68,7 +72,7 @@ public void ViewsInBothDatabases_AreNotReported()
builder.Database2.Views.Add(viewName, "foobar");
// Act
- builder.BuildDifferencesAsync().Wait();
+ await builder.BuildDifferencesAsync();
// Assert
builder.Differences.ViewDifferences.Should().ContainKey(viewName);