-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
292 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using DaJet.Metadata.Model; | ||
using DaJet.Metadata.Services; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using System.IO; | ||
using System.Text; | ||
|
||
namespace DaJet.Metadata.ConfigDiff | ||
{ | ||
[TestClass] public sealed class ConfigDiff | ||
{ | ||
[TestMethod] public void TestDiff() | ||
{ | ||
IMetadataService metadata = new MetadataService(); | ||
IMetaDiffService metadiff = new MetaDiffService(); | ||
|
||
metadata | ||
.UseDatabaseProvider(DatabaseProvider.SQLServer) | ||
.UseConnectionString("Data Source=ZHICHKIN;Initial Catalog=cerberus;Integrated Security=True"); | ||
InfoBase ibOld = metadata.LoadInfoBase(); | ||
|
||
metadata | ||
.UseDatabaseProvider(DatabaseProvider.SQLServer) | ||
.UseConnectionString("Data Source=ZHICHKIN;Initial Catalog=cerberus_new;Integrated Security=True"); | ||
InfoBase ibNew = metadata.LoadInfoBase(); | ||
|
||
MetaDiff diff = metadiff.Compare(ibOld, ibNew); | ||
|
||
WriteDiffToFile(diff); | ||
} | ||
|
||
private void WriteDiffToFile(MetaDiff diff) | ||
{ | ||
using (StreamWriter stream = new StreamWriter(@"C:\temp\diff.txt", false, Encoding.UTF8)) | ||
{ | ||
WriteToFile(stream, diff, 0, string.Empty); | ||
} | ||
} | ||
private void WriteToFile(StreamWriter stream, MetaDiff diff, int level, string path) | ||
{ | ||
string indent = level == 0 ? string.Empty : "-".PadLeft(level * 4, '-'); | ||
//string thisPath = path + (string.IsNullOrEmpty(path) ? string.Empty : ".") + i.ToString(); | ||
stream.WriteLine(indent + "[" + level.ToString() + "] (" + diff.Difference.ToString() + ") " | ||
+ diff.Target.ToString() | ||
+ (diff.Target is MetadataProperty property ? " (" + property.PropertyType.ToString() + ")" : string.Empty)); | ||
|
||
foreach (var entry in diff.NewValues) | ||
{ | ||
indent = "-".PadLeft((level + 1) * 4, '-'); | ||
stream.WriteLine(indent + "[*] " + entry.Key + " = " + entry.Value.ToString()); | ||
} | ||
|
||
for (int i = 0; i < diff.Children.Count; i++) | ||
{ | ||
//thisPath = path + (string.IsNullOrEmpty(path) ? string.Empty : ".") + i.ToString(); | ||
WriteToFile(stream, diff.Children[i], level + 1, path); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace DaJet.Metadata.Model | ||
{ | ||
public enum DiffType | ||
{ | ||
///<summary>No difference (used just as a root of child differences)</summary> | ||
None, | ||
///<summary>New item to add</summary> | ||
Insert, | ||
///<summary>Some properties has been changed</summary> | ||
Update, | ||
///<summary>Target item to be deleted</summary> | ||
Delete | ||
} | ||
public sealed class MetaDiff | ||
{ | ||
public MetaDiff() { } | ||
public MetaDiff(MetaDiff parent, MetadataObject target, DiffType difference) | ||
{ | ||
Parent = parent; | ||
Target = target; | ||
Difference = difference; | ||
} | ||
public MetaDiff Parent { set; get; } | ||
public DiffType Difference { set; get; } | ||
public MetadataObject Target { set; get; } | ||
public List<MetaDiff> Children { get; } = new List<MetaDiff>(); | ||
public Dictionary<string, object> NewValues { get; } = new Dictionary<string, object>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
using DaJet.Metadata.Model; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace DaJet.Metadata.Services | ||
{ | ||
public interface IMetaDiffService | ||
{ | ||
MetaDiff Compare(InfoBase target, InfoBase source); | ||
} | ||
public sealed class MetaDiffService : IMetaDiffService | ||
{ | ||
public MetaDiff Compare(InfoBase target, InfoBase source) | ||
{ | ||
MetaDiff root = new MetaDiff(null, target, DiffType.None); | ||
CompareLists(root, target.Catalogs.Values.ToList(), source.Catalogs.Values.ToList()); | ||
CompareLists(root, target.Documents.Values.ToList(), source.Documents.Values.ToList()); | ||
CompareLists(root, target.Characteristics.Values.ToList(), source.Characteristics.Values.ToList()); | ||
CompareLists(root, target.InformationRegisters.Values.ToList(), source.InformationRegisters.Values.ToList()); | ||
CompareLists(root, target.AccumulationRegisters.Values.ToList(), source.AccumulationRegisters.Values.ToList()); | ||
return root; | ||
} | ||
private void CompareLists<T>(MetaDiff parent, List<T> target_list, List<T> source_list) where T : MetadataObject, IComparable | ||
{ | ||
int target_count = target_list.Count; | ||
int source_count = source_list.Count; | ||
int target_index = 0; | ||
int source_index = 0; | ||
int compareResult; | ||
|
||
if (target_count == 0 && source_count == 0) return; | ||
|
||
target_list.Sort(); | ||
source_list.Sort(); | ||
|
||
while (target_index < target_count) | ||
{ | ||
if (source_index < source_count) | ||
{ | ||
compareResult = target_list[target_index].CompareTo(source_list[source_index]); | ||
if (compareResult < 0) | ||
{ | ||
MetaDiff difference = new MetaDiff(parent, target_list[target_index], DiffType.Delete); | ||
parent.Children.Add(difference); | ||
SetUpdateDiffType(parent); | ||
AddChildren(difference); | ||
target_index++; | ||
} | ||
else if (compareResult == 0) | ||
{ | ||
MetaDiff difference = new MetaDiff(parent, target_list[target_index], DiffType.None); | ||
CompareListItems(difference, target_list[target_index], source_list[source_index]); | ||
if (difference.Difference == DiffType.Update) parent.Children.Add(difference); | ||
target_index++; | ||
source_index++; | ||
} | ||
else | ||
{ | ||
MetaDiff difference = new MetaDiff(parent, source_list[source_index], DiffType.Insert); | ||
parent.Children.Add(difference); | ||
SetUpdateDiffType(parent); | ||
AddChildren(difference); | ||
source_index++; | ||
} | ||
} | ||
else | ||
{ | ||
MetaDiff difference = new MetaDiff(parent, target_list[target_index], DiffType.Delete); | ||
parent.Children.Add(difference); | ||
SetUpdateDiffType(parent); | ||
AddChildren(difference); | ||
target_index++; | ||
} | ||
} | ||
while (source_index < source_count) | ||
{ | ||
MetaDiff difference = new MetaDiff(parent, source_list[source_index], DiffType.Insert); | ||
parent.Children.Add(difference); | ||
SetUpdateDiffType(parent); | ||
AddChildren(difference); | ||
source_index++; | ||
} | ||
} | ||
// Compare methods is used by Update difference | ||
private void CompareListItems(MetaDiff difference, MetadataObject target, MetadataObject source) | ||
{ | ||
if (target is ApplicationObject) | ||
{ | ||
CompareObjects(difference, (ApplicationObject)target, (ApplicationObject)source); | ||
} | ||
else if (typeof(MetadataProperty) == target.GetType()) | ||
{ | ||
CompareProperties(difference, (MetadataProperty)target, (MetadataProperty)source); | ||
} | ||
} | ||
private void CompareObjects(MetaDiff difference, ApplicationObject target, ApplicationObject source) | ||
{ | ||
//difference.NewValues.Clear(); | ||
//if (target.TypeCode != source.TypeCode) | ||
//{ | ||
// difference.NewValues.Add("TypeCode", source.TypeCode); | ||
//} | ||
//if (difference.NewValues.Count > 0) SetUpdateDiffType(difference); | ||
|
||
//if (target.Uuid == source.Uuid || target.FileName == source.FileName) | ||
//{ | ||
|
||
//} | ||
|
||
CompareLists(difference, target.Properties, source.Properties); | ||
CompareLists(difference, target.TableParts, source.TableParts); | ||
} | ||
private void CompareProperties(MetaDiff difference, MetadataProperty target, MetadataProperty source) | ||
{ | ||
difference.NewValues.Clear(); | ||
if (target.PropertyType.CanBeBoolean != source.PropertyType.CanBeBoolean | ||
|| target.PropertyType.CanBeString != source.PropertyType.CanBeString | ||
|| target.PropertyType.CanBeNumeric != source.PropertyType.CanBeNumeric | ||
|| target.PropertyType.CanBeDateTime != source.PropertyType.CanBeDateTime | ||
|| target.PropertyType.CanBeReference != source.PropertyType.CanBeReference | ||
|| target.PropertyType.IsUuid != source.PropertyType.IsUuid | ||
|| target.PropertyType.IsValueStorage != source.PropertyType.IsValueStorage | ||
|| target.PropertyType.IsMultipleType != source.PropertyType.IsMultipleType) | ||
{ | ||
difference.NewValues.Add("PropertyType", source.PropertyType); | ||
} | ||
if (difference.NewValues.Count > 0) SetUpdateDiffType(difference); | ||
} | ||
private void SetUpdateDiffType(MetaDiff difference) | ||
{ | ||
if (difference.Difference != DiffType.None) return; | ||
difference.Difference = DiffType.Update; | ||
MetaDiff parent = difference.Parent; | ||
while (parent != null) | ||
{ | ||
parent.Difference = DiffType.Update; | ||
parent = parent.Parent; | ||
} | ||
} | ||
// Add children is used by Insert and Delete differences | ||
private void AddChildren(MetaDiff difference) | ||
{ | ||
if (difference.Target is ApplicationObject) | ||
{ | ||
AddObjectChildren(difference); | ||
} | ||
} | ||
private void AddObjectChildren(MetaDiff difference) | ||
{ | ||
ApplicationObject target = (ApplicationObject)difference.Target; | ||
|
||
foreach (MetadataProperty child in target.Properties) | ||
{ | ||
MetaDiff diff = new MetaDiff(difference, child, difference.Difference); | ||
difference.Children.Add(diff); | ||
} | ||
foreach (TablePart child in target.TableParts) | ||
{ | ||
MetaDiff diff = new MetaDiff(difference, child, difference.Difference); | ||
difference.Children.Add(diff); | ||
AddObjectChildren(diff); | ||
} | ||
} | ||
} | ||
} |