Eric Svensen fixes: translations immutable & BiDi relax validation

This commit is contained in:
Christian Wade 2017-12-01 21:43:00 -08:00
parent f6f04dee4c
commit d86d6212c6
9 changed files with 95 additions and 42 deletions

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("4.0.0.16")]
[assembly: AssemblyFileVersion("4.0.0.16")]
[assembly: AssemblyVersion("4.0.0.18")]
[assembly: AssemblyFileVersion("4.0.0.18")]

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("4.0.0.16")]
[assembly: AssemblyFileVersion("4.0.0.16")]
[assembly: AssemblyVersion("4.0.0.18")]
[assembly: AssemblyFileVersion("4.0.0.18")]

View File

@ -287,7 +287,7 @@
<Compile Include="TabularCompare\UI\DiffMatchPatch.cs" />
<Compile Include="TabularCompare\OptionsInfo.cs" />
<Compile Include="TabularCompare\TabularMetadata\RelationshipLink.cs" />
<Compile Include="TabularCompare\TabularMetadata\RelationshipChain.cs" />
<Compile Include="TabularCompare\TabularMetadata\RelationshipChainsFromRoot.cs" />
<Compile Include="TabularCompare\SkipSelection.cs" />
<Compile Include="TabularCompare\SkipSelectionCollection.cs" />
<Compile Include="TabularCompare\UI\SynchronizedScrollRichTextBox.cs">

View File

@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("4.0.0.16")]
[assembly: AssemblyFileVersion("4.0.0.16")]
[assembly: AssemblyVersion("4.0.0.18")]
[assembly: AssemblyFileVersion("4.0.0.18")]

View File

@ -7,7 +7,7 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
/// <summary>
/// Represents a chain of RelationshipLink objects, used to detect ambiguity in relationship paths.
/// </summary>
public class RelationshipChain : List<RelationshipLink>
public class RelationshipChainsFromRoot : List<RelationshipLink>
{
/// <summary>
/// Find end table by name.
@ -49,9 +49,26 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
/// <returns>Boolean indicating if the end table was found.</returns>
public bool ContainsEndTableName(string endTableName)
{
foreach (RelationshipLink ReferencedTable in this)
foreach (RelationshipLink link in this)
{
if (ReferencedTable.EndTable.Name == endTableName)
if (link.EndTable.Name == endTableName)
{
return true;
}
}
return false;
}
/// <summary>
/// Check if chain of RelationshipLink objects contains an end table with specified name that is BiDi invoked.
/// </summary>
/// <param name="endTableName">Name of the end table.</param>
/// <returns>Boolean indicating if the BiDi invoked end table was found.</returns>
public bool ContainsBidiToEndTable(string endTableName)
{
foreach (RelationshipLink link in this)
{
if (link.EndTable.Name == endTableName && link.PrecedingPathBiDiInvoked)
{
return true;
}

View File

@ -14,7 +14,9 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
private Table _beginTable;
private Table _endTable;
private bool _root;
private bool _biDiInvoked;
private string _tablePath;
private bool _precedingPathBiDiInvoked;
private Relationship _filteringRelationship;
/// <summary>
@ -25,19 +27,23 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
/// <param name="root">Boolean indicating if the root link in a the relationship chain.</param>
/// <param name="precedingTablePath">Recursive path to the preceding table in the relationship chain.</param>
/// <param name="filteringRelationship">Relationship object for the relationship link.</param>
public RelationshipLink(Table beginTable, Table endTable, bool root, string precedingTablePath, Relationship filteringRelationship)
public RelationshipLink(Table beginTable, Table endTable, bool root, string precedingTablePath, bool precedingPathBiDiInvoked, Relationship filteringRelationship, bool biDiInvoked)
{
_beginTable = beginTable;
_endTable = endTable;
_root = root;
_biDiInvoked = biDiInvoked;
if (root)
{
//_tablePath = $"'{beginTable.Name}'->{(biDi ? "(BiDi)" : "")}'{endTable.Name}'";
_tablePath = $"'{beginTable.Name}'->'{endTable.Name}'";
}
else
{
//_tablePath = $"{precedingTablePath}->{(biDi ? "(BiDi)" : "")}'{endTable.Name}'";
_tablePath = $"{precedingTablePath}->'{endTable.Name}'";
}
_precedingPathBiDiInvoked = (precedingPathBiDiInvoked || biDiInvoked);
_filteringRelationship = filteringRelationship;
}
@ -56,11 +62,21 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
/// </summary>
public bool Root => _root;
/// <summary>
/// Boolean indicating if the relationship is BiDi and traversing from the many to the one side.
/// </summary>
public bool BiDiInvoked => _biDiInvoked;
/// <summary>
/// Recursive path to the preceding table in the relationship chain.
/// </summary>
public string TablePath => _tablePath;
/// <summary>
/// Boolean indicating if the relationship is BiDi and traversing from the many to the one side.
/// </summary>
public bool PrecedingPathBiDiInvoked => _precedingPathBiDiInvoked;
/// <summary>
/// Relationship object for the relationship link.
/// </summary>

View File

@ -586,13 +586,12 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
{
//beginTable might be the From or the To table in TOM Relationship object; it depends on CrossFilterDirection.
RelationshipChain referencedTableCollection = new RelationshipChain();
RelationshipChainsFromRoot referencedTableCollection = new RelationshipChainsFromRoot();
foreach (Relationship filteringRelationship in beginTable.FindFilteringRelationships())
{
// EndTable can be either the From or the To table of a Relationship object depending on CrossFilteringBehavior
string endTableName = filteringRelationship.TomRelationship.FromTable.Name == beginTable.Name ? filteringRelationship.TomRelationship.ToTable.Name : filteringRelationship.TomRelationship.FromTable.Name;
RelationshipLink rootLink = new RelationshipLink(beginTable, _tables.FindByName(endTableName), true, "", filteringRelationship);
string endTableName = GetEndTableName(beginTable, filteringRelationship, out bool biDi);
RelationshipLink rootLink = new RelationshipLink(beginTable, _tables.FindByName(endTableName), true, "", false, filteringRelationship, biDi);
ValidateLink(rootLink, referencedTableCollection);
}
}
@ -613,15 +612,19 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
}
}
private void ValidateLink(RelationshipLink link, RelationshipChain chain)
private void ValidateLink(RelationshipLink link, RelationshipChainsFromRoot chainsFromRoot)
{
if (chain.ContainsEndTableName(link.EndTable.Name))
if (
chainsFromRoot.ContainsEndTableName(link.EndTable.Name)
//&& !(link.PrecedingPathBiDiInvoked && !chainsFromRoot.ContainsBidiToEndTable(link.EndTable.Name))
//Fix 12/1/2017: we allow 1 ambiguous relationship path as long as only one of the paths is bidi invoked (2 bidis to the same table counts as ambiguous)
)
{
// If we are here, we have identified 2 active paths to get to the same table.
// So, the one that was already there in the target should win.
RelationshipLink otherLink = chain.FindByEndTableName(link.EndTable.Name);
string rootTableName = chain.FindRoot().BeginTable.Name;
RelationshipLink otherLink = chainsFromRoot.FindByEndTableName(link.EndTable.Name);
string rootTableName = chainsFromRoot.FindRoot().BeginTable.Name;
if (link.FilteringRelationship.CopiedFromSource)
{
@ -643,31 +646,47 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
ValidationMessageStatus.Warning));
//remove OTHER ONE from collection as no longer in filtering chain
chain.RemoveByEndTableName(otherLink.EndTable.Name);
chainsFromRoot.RemoveByEndTableName(otherLink.EndTable.Name);
}
}
if (link.FilteringRelationship.TomRelationship.IsActive) //If not, we must have just set it to false above
{
//Add the link to the chain and re-iterate ...
chain.Add(link);
chainsFromRoot.Add(link);
Table beginTable = link.EndTable; //EndTable is now the begin table as iterating next level ...
foreach (Relationship filteringRelationship in beginTable.FindFilteringRelationships())
{
// EndTable can be either the From or the To table of a Relationship object depending on direction of CrossFilteringBehavior
string endTableName = filteringRelationship.TomRelationship.FromTable.Name == beginTable.Name ? filteringRelationship.TomRelationship.ToTable.Name : filteringRelationship.TomRelationship.FromTable.Name;
string endTableName = GetEndTableName(beginTable, filteringRelationship, out bool biDi);
//Need to check if endTableName has already been covered by TablePath to avoid CrossFilteringBehavior leading both ways and never ending loop
if (!link.TablePath.Contains("'" + endTableName + "'"))
{
RelationshipLink newLink = new RelationshipLink(beginTable, _tables.FindByName(endTableName), false, link.TablePath, filteringRelationship);
ValidateLink(newLink, chain);
RelationshipLink newLink = new RelationshipLink(beginTable, _tables.FindByName(endTableName), false, link.TablePath, link.PrecedingPathBiDiInvoked, filteringRelationship, biDi);
ValidateLink(newLink, chainsFromRoot);
}
}
}
}
private string GetEndTableName(Table beginTable, Relationship filteringRelationship, out bool biDi)
{
string endTableName;
biDi = false;
if (filteringRelationship.TomRelationship.FromTable.Name == beginTable.Name)
{
endTableName = filteringRelationship.TomRelationship.ToTable.Name;
}
else
{
endTableName = filteringRelationship.TomRelationship.FromTable.Name;
biDi = true;
}
return endTableName;
}
#endregion
#region Variation Cleanup
@ -1251,20 +1270,6 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
break;
}
//todo delete
////Not sure why switch statement not stopping on "case ObjectType.Perspective:" above. Fudge below. Todo2: test with later build.
//if (namedObjectSource.ObjectType.ToString() == "Perspective")
//{
// foreach (Tom.Perspective tomPerspectiveTarget in tomCultureTarget.Model.Perspectives)
// {
// if (namedObjectSource.Name == tomPerspectiveTarget.Name)
// {
// namedObjectTarget = tomPerspectiveTarget;
// break;
// }
// }
//}
//If namedObjectTarget is null, the model object doesn't exist in target, so can ignore
if (namedObjectTarget != null)
{
@ -1275,6 +1280,11 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
if (translation.Object is NamedMetadataObject &&
((NamedMetadataObject)translation.Object).Name == namedObjectSource.Name &&
translation.Object.ObjectType == namedObjectSource.ObjectType &&
(
//check columns are both in same table (could have columns with same name in different tables)
!(translation.Object.Parent.ObjectType == ObjectType.Table && namedObjectSource.Parent.ObjectType == ObjectType.Table) ||
(((NamedMetadataObject)translation.Parent).Name == ((NamedMetadataObject)namedObjectSource.Parent).Name)
) &&
translation.Property == translationSource.Property
)
{
@ -1285,8 +1295,18 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
if (translationTarget != null)
{ //Translation already exists in cultureTarget for this object, so just ensure values match
//Also decouple from object in model and reset coupling
translationTarget.Object = namedObjectTarget;
//Also decouple from object in model and reset coupling if removed
if (translationTarget.Object.IsRemoved)
{
ObjectTranslation translationTargetReplacement = new ObjectTranslation();
translationTargetReplacement.Object = namedObjectTarget;
translationTargetReplacement.Property = translationSource.Property;
translationTargetReplacement.Value = translationSource.Value;
tomCultureTarget.ObjectTranslations.Remove(translationTarget);
tomCultureTarget.ObjectTranslations.Add(translationTargetReplacement);
translationTarget = translationTargetReplacement;
}
//translationTarget.Object = namedObjectTarget;
translationTarget.Value = translationSource.Value;
}
else

View File

@ -64,7 +64,7 @@ namespace BismNormalizer.TabularCompare.UI
// Cause edit mode to begin since edit mode is disabled to support
// expanding/collapsing
base.OnKeyDown(e);
if (!e.Handled)
if (!e.Handled && this.Rows.Count > 0)
{
if (e.KeyCode == Keys.F2 && this.CurrentCellAddress.X > -1 && this.CurrentCellAddress.Y >-1)
{

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="BismNormalizer.ea2aeb43-64a6-4dee-8816-099fb44513fa" Version="4.0.0.16" Language="en-US" Publisher="BISM Normalizer" />
<Identity Id="BismNormalizer.ea2aeb43-64a6-4dee-8816-099fb44513fa" Version="4.0.0.18" Language="en-US" Publisher="BISM Normalizer" />
<DisplayName>BISM Normalizer</DisplayName>
<Description xml:space="preserve">BISM Normalizer manages Analysis Services tabular models</Description>
<MoreInfo>http://bism-normalizer.com/</MoreInfo>