Eric Svensen fixes: translations immutable & BiDi relax validation
This commit is contained in:
parent
f6f04dee4c
commit
d86d6212c6
@ -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")]
|
||||
|
@ -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")]
|
||||
|
@ -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">
|
||||
|
@ -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")]
|
||||
|
@ -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;
|
||||
}
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user