public static void SetDAX(this IDaxDependantObject obj, DAXProperty property, string expression) { if (obj is TablePermission tp && property == DAXProperty.Expression) { tp.FilterExpression = expression; return; } if (obj is KPI) { if (property == DAXProperty.StatusExpression) { (obj as KPI).StatusExpression = expression; return; } if (property == DAXProperty.TargetExpression) { (obj as KPI).TargetExpression = expression; return; } if (property == DAXProperty.TrendExpression) { (obj as KPI).TrendExpression = expression; return; } } if (obj is IExpressionObject && property == DAXProperty.Expression) { (obj as IExpressionObject).Expression = expression; return; } if (obj is Measure && property == DAXProperty.DetailRowsExpression) { (obj as Measure).DetailRowsExpression = expression; return; } if (obj is Table && property == DAXProperty.DefaultDetailRowsExpression) { (obj as Table).DefaultDetailRowsExpression = expression; return; } /*if (obj is Measure m && property == DAXProperty.FormatStringExpression) * { * m.FormatStringExpression = expression; * return; * }*/ if (obj is CalculationItem ci) { if (property == DAXProperty.Expression) { ci.Expression = expression; return; } if (property == DAXProperty.FormatStringExpression) { ci.FormatStringExpression = expression; return; } } throw new ArgumentException(string.Format(Messages.InvalidExpressionProperty, obj.GetTypeName(), property), "property"); }
/// <summary> /// This method can be called to obtain a DependsOnList for any DAX expression. This is useful when the /// user is currently editing the DAX expression of an object, but the expression has not been saved to /// the object. /// </summary> public static DependsOnList GetDependencies(IDaxDependantObject expressionObj, string dax, DAXProperty prop) { var dependsOn = new DependsOnList(null); ParseExpression(dax, expressionObj, prop, dependsOn); return(dependsOn); }
public static IEnumerable <DAXProperty> GetDAXProperties(this IDaxDependantObject obj) { if (obj is Measure || obj is CalculatedColumn || obj is CalculatedTable) { yield return(DAXProperty.Expression); } if (TabularModelHandler.Singleton.CompatibilityLevel >= 1400) { if (obj is Measure) { yield return(DAXProperty.DetailRowsExpression); } if (obj is Table) { yield return(DAXProperty.DefaultDetailRowsExpression); } } if (obj is KPI) { yield return(DAXProperty.StatusExpression); yield return(DAXProperty.TargetExpression); yield return(DAXProperty.TrendExpression); } if (obj is RLSFilterExpression) { yield return(DAXProperty.Expression); } }
public static void ClearDependsOn(IDaxDependantObject expressionObj) { foreach (var d in expressionObj.DependsOn.Keys) { d.ReferencedBy.Remove(expressionObj); } expressionObj.DependsOn.Clear(); }
static public void AddDep(this IDaxDependantObject target, IDaxObject dependsOn, DAXProperty property, int fromChar, int toChar, bool fullyQualified) { target.DependsOn.Add(dependsOn, property, fromChar, toChar, fullyQualified); if (!dependsOn.ReferencedBy.Contains(target)) { dependsOn.ReferencedBy.Add(target); } }
private void Dax_ExplicitColumnRefAssert(IDaxDependantObject dependant, Column reference) { // If a column is explicitly referenced, we expect to have two references (one for the column, one for the table): Assert.AreEqual(2, dependant.DependsOn.Count); Assert.IsTrue(dependant.DependsOn.ContainsKey(reference)); Assert.IsTrue(dependant.DependsOn.ContainsKey(reference.Table)); Assert.IsTrue(reference.ReferencedBy.Contains(dependant)); }
public static string GetDAX(this IDaxDependantObject obj, DAXProperty property) { if (obj is TablePermission tp && property == DAXProperty.Expression) { return(tp.FilterExpression); } if (obj is KPI) { if (property == DAXProperty.StatusExpression) { return((obj as KPI).StatusExpression); } if (property == DAXProperty.TargetExpression) { return((obj as KPI).TargetExpression); } if (property == DAXProperty.TrendExpression) { return((obj as KPI).TrendExpression); } } if (obj is IExpressionObject && property == DAXProperty.Expression) { return((obj as IExpressionObject).Expression); } if (obj is CalculationItem ci) { if (property == DAXProperty.Expression) { return(ci.Expression); } if (property == DAXProperty.FormatStringExpression) { return(ci.FormatStringExpression); } } if (TabularModelHandler.Singleton.CompatibilityLevel >= 1400) { if (obj is Measure && property == DAXProperty.DetailRowsExpression) { return((obj as Measure).DetailRowsExpression); } if (obj is Table && property == DAXProperty.DefaultDetailRowsExpression) { return((obj as Table).DefaultDetailRowsExpression); } } /*if (obj is Measure m && property == DAXProperty.FormatStringExpression) * return m.FormatStringExpression;*/ throw new ArgumentException(string.Format(Messages.InvalidExpressionProperty, obj.GetTypeName(), property), "property"); }
public static string GetDAXProperty(this IDaxDependantObject obj, DAXProperty property) { if (obj is TablePermission tp && property == DAXProperty.Expression) { return(Properties.FILTEREXPRESSION); } if (obj is KPI) { if (property == DAXProperty.StatusExpression) { return(Properties.STATUSEXPRESSION); } if (property == DAXProperty.TargetExpression) { return(Properties.TARGETEXPRESSION); } if (property == DAXProperty.TrendExpression) { return(Properties.TRENDEXPRESSION); } } if (obj is IExpressionObject && property == DAXProperty.Expression) { return(Properties.EXPRESSION); } if (obj is CalculationItem ci) { if (property == DAXProperty.Expression) { return(Properties.EXPRESSION); } if (property == DAXProperty.FormatStringExpression) { return(Properties.FORMATSTRINGEXPRESSION); } } if (TabularModelHandler.Singleton.CompatibilityLevel >= 1400) { if (obj is Measure && property == DAXProperty.DetailRowsExpression) { return(Properties.DETAILROWSEXPRESSION); } if (obj is Table && property == DAXProperty.DefaultDetailRowsExpression) { return(Properties.DEFAULTDETAILROWSEXPRESSION); } } /*if (obj is Measure m && property == DAXProperty.FormatStringExpression) * return m.FormatStringExpression;*/ throw new ArgumentException(string.Format(Messages.InvalidExpressionProperty, obj.GetTypeName(), property), "property"); }
public static void BuildDependencyTree(IDaxDependantObject expressionObj) { ClearDependsOn(expressionObj); foreach (var prop in expressionObj.GetDAXProperties()) { var dax = expressionObj.GetDAX(prop) ?? ""; ParseExpression(dax, expressionObj, prop); } }
public static void BuildDependencyTree(IDaxDependantObject expressionObj) { foreach (var d in expressionObj.DependsOn.Keys) { d.ReferencedBy.Remove(expressionObj); } expressionObj.DependsOn.Clear(); foreach (var prop in expressionObj.GetDAXProperties()) { var dax = expressionObj.GetDAX(prop) ?? ""; ParseExpression(dax, expressionObj, prop); } }
/// <summary> /// Rebuilds the dependency tree for the provided object. If within a BeginUpdate / EndUpdate batch, /// this operation is postponed until the batch ends unless force is set to true. /// </summary> /// <param name="expressionObj"></param> /// <param name="force"></param> public static void BuildDependencyTree(IDaxDependantObject expressionObj, bool force = false) { if (Handler.EoB_PostponeOperations && !force) { Handler.EoB_RequireRebuildDependencyTree = true; return; } ClearDependsOn(expressionObj); foreach (var prop in expressionObj.GetDAXProperties()) { var dax = expressionObj.GetDAX(prop) ?? ""; ParseExpression(dax, expressionObj, prop); } }
public static void SetDAX(this IDaxDependantObject obj, DAXProperty property, string expression) { if (obj is RLSFilterExpression && property == DAXProperty.Expression) { var rls = (obj as RLSFilterExpression); rls.Role.RowLevelSecurity[rls.Table] = expression; return; } if (obj is KPI) { if (property == DAXProperty.StatusExpression) { (obj as KPI).StatusExpression = expression; return; } if (property == DAXProperty.TargetExpression) { (obj as KPI).TargetExpression = expression; return; } if (property == DAXProperty.TrendExpression) { (obj as KPI).TrendExpression = expression; return; } } if (obj is IExpressionObject && property == DAXProperty.Expression) { (obj as IExpressionObject).Expression = expression; return; } if (obj is Measure && property == DAXProperty.DetailRowsExpression) { (obj as Measure).DetailRowsExpression = expression; return; } if (obj is Table && property == DAXProperty.DefaultDetailRowsExpression) { (obj as Table).DefaultDetailRowsExpression = expression; return; } throw new ArgumentException(string.Format(Messages.InvalidExpressionProperty, obj.GetTypeName(), property), "property"); }
public static DAXProperty GetDefaultDAXProperty(this IDaxDependantObject obj) { if (obj is CalculatedTable) { return(DAXProperty.Expression); } if (obj is Table) { return(DAXProperty.DefaultDetailRowsExpression); } if (obj is KPI) { return(DAXProperty.StatusExpression); } else { return(DAXProperty.Expression); } }
public static string GetDAX(this IDaxDependantObject obj, DAXProperty property) { if (obj is RLSFilterExpression && property == DAXProperty.Expression) { var rls = (obj as RLSFilterExpression); return(rls.Role.RowLevelSecurity[rls.Table]); } if (obj is KPI) { if (property == DAXProperty.StatusExpression) { return((obj as KPI).StatusExpression); } if (property == DAXProperty.TargetExpression) { return((obj as KPI).TargetExpression); } if (property == DAXProperty.TrendExpression) { return((obj as KPI).TrendExpression); } } if (obj is IExpressionObject && property == DAXProperty.Expression) { return((obj as IExpressionObject).Expression); } if (TabularModelHandler.Singleton.CompatibilityLevel >= 1400) { if (obj is Measure && property == DAXProperty.DetailRowsExpression) { return((obj as Measure).DetailRowsExpression); } if (obj is Table && property == DAXProperty.DefaultDetailRowsExpression) { return((obj as Table).DefaultDetailRowsExpression); } } throw new ArgumentException(string.Format(Messages.InvalidExpressionProperty, obj.GetTypeName(), property), "property"); }
public static IEnumerable <DAXProperty> GetDAXProperties(this IDaxDependantObject obj) { if (obj is Measure || obj is CalculatedColumn || obj is CalculatedTable) { yield return(DAXProperty.Expression); } if (TabularModelHandler.Singleton.CompatibilityLevel >= 1400) { if (obj is Measure) { yield return(DAXProperty.DetailRowsExpression); } if (obj.ObjectType == ObjectType.Table) { yield return(DAXProperty.DefaultDetailRowsExpression); } } /*if (TabularModelHandler.Singleton.CompatibilityLevel >= 1470) * { * if (obj is Measure) yield return DAXProperty.FormatStringExpression; * }*/ if (obj is KPI) { yield return(DAXProperty.StatusExpression); yield return(DAXProperty.TargetExpression); yield return(DAXProperty.TrendExpression); } if (obj is TablePermission) { yield return(DAXProperty.Expression); } if (obj.ObjectType == ObjectType.CalculationItem) { yield return(DAXProperty.Expression); yield return(DAXProperty.FormatStringExpression); } }
public static IList <DaxToken> Tokenize(this IDaxDependantObject obj, DAXProperty property) { var result = new List <DaxToken>(); var dax = obj.GetDAX(property); if (string.IsNullOrEmpty(dax)) { return(result); } var lexer = new DAXLexer(new DAXCharStream(obj.GetDAX(property), false)); lexer.RemoveErrorListeners(); var lexerTokens = lexer.GetAllTokens(); for (int i = 0; i < lexerTokens.Count; i++) { result.Add(new DaxToken(lexerTokens[i], result, i)); } return(result); }
public static DependsOnList GetDependencies(IDaxDependantObject obj, string dax, DAXProperty prop) { return(FormulaFixup.GetDependencies(obj, dax, prop)); }
private static void ParseExpression(string dax, IDaxDependantObject expressionObj, DAXProperty prop, DependsOnList dependsOn = null) { var tokens = new DAXLexer(new AntlrInputStream(dax)).GetAllTokens(); IToken lastTableRef = null; int startTableIndex = 0; for (var i = 0; i < tokens.Count; i++) { // TODO: This parsing could be used to check for invalid object references, for example to use in syntax highlighting or validation of expressions var tok = tokens[i]; switch (tok.Type) { case DAXLexer.TABLE: case DAXLexer.TABLE_OR_VARIABLE: if (i < tokens.Count - 1 && tokens[i + 1].Type == DAXLexer.COLUMN_OR_MEASURE) { // Keep the token reference, as the next token should be column (fully qualified). lastTableRef = tok; startTableIndex = tok.StartIndex; } else { // Table referenced directly, don't save the reference for the next token. lastTableRef = null; } if (Model.Tables.Contains(tok.Text.NoQ(true))) { if (dependsOn != null) { dependsOn.Add(Model.Tables[tok.Text.NoQ(true)], prop, tok.StartIndex, tok.StopIndex, true); } else { expressionObj.AddDep(Model.Tables[tok.Text.NoQ(true)], prop, tok.StartIndex, tok.StopIndex, true); } } else { // Invalid reference (no table with that name) or possibly a variable or function ref } break; case DAXLexer.COLUMN_OR_MEASURE: // Referencing a table just before the object reference if (lastTableRef != null) { var tableName = lastTableRef.Text.NoQ(true); lastTableRef = null; if (!Model.Tables.Contains(tableName)) { return; // Invalid reference (no table with that name) } var table = Model.Tables[tableName]; // Referencing a column on a specific table if (table.Columns.Contains(tok.Text.NoQ())) { if (dependsOn != null) { dependsOn.Add(table.Columns[tok.Text.NoQ()], prop, startTableIndex, tok.StopIndex, true); } else { expressionObj.AddDep(table.Columns[tok.Text.NoQ()], prop, startTableIndex, tok.StopIndex, true); } } // Referencing a measure on a specific table else if (table.Measures.Contains(tok.Text.NoQ())) { if (dependsOn != null) { dependsOn.Add(table.Measures[tok.Text.NoQ()], prop, startTableIndex, tok.StopIndex, true); } else { expressionObj.AddDep(table.Measures[tok.Text.NoQ()], prop, startTableIndex, tok.StopIndex, true); } } } // No table reference before the object reference else { var table = (expressionObj as ITabularTableObject)?.Table; // Referencing a column without specifying a table (assume column in same table): if (table != null && table.Columns.Contains(tok.Text.NoQ())) { if (dependsOn != null) { dependsOn.Add(table.Columns[tok.Text.NoQ()], prop, tok.StartIndex, tok.StopIndex, false); } else { expressionObj.AddDep(table.Columns[tok.Text.NoQ()], prop, tok.StartIndex, tok.StopIndex, false); } } // Referencing a measure or column without specifying a table else { Measure m = null; if (table != null && table.Measures.Contains(tok.Text.NoQ())) { m = table.Measures[tok.Text.NoQ()]; } else { m = Model.Tables.FirstOrDefault(t => t.Measures.Contains(tok.Text.NoQ()))?.Measures[tok.Text.NoQ()]; } if (m != null) { if (dependsOn != null) { dependsOn.Add(m, prop, tok.StartIndex, tok.StopIndex, false); } else { expressionObj.AddDep(m, prop, tok.StartIndex, tok.StopIndex, false); } } } } break; default: lastTableRef = null; break; } } }
internal DependsOnList(IDaxDependantObject parent) { Parent = parent; }
private void Dax_SingleRefAssert(IDaxDependantObject dependant, IDaxObject reference) { Assert.AreEqual(1, dependant.DependsOn.Count); Assert.AreSame(reference, dependant.DependsOn[0]); Assert.IsTrue(reference.ReferencedBy.Contains(dependant)); }
private void FixUpTest(TabularModelHandler tmh, IDaxDependantObject obj, Utils.DAXProperty property, bool isFullyQualified, Table tableRef, IDaxObject objRef) { var baseExpression = obj.GetDAX(property); if (isFullyQualified) { Assert.AreEqual(2, obj.DependsOn.Count); Assert.AreSame(tableRef, obj.DependsOn[0]); var references = obj.DependsOn[tableRef]; Assert.AreEqual(1, references.Count); Assert.AreEqual(property, references[0].property); Assert.IsTrue(references[0].fullyQualified); Assert.AreSame(objRef, obj.DependsOn[1]); references = obj.DependsOn[objRef]; Assert.AreEqual(1, references.Count); Assert.AreEqual(property, references[0].property); Assert.IsTrue(references[0].fullyQualified); } else { Assert.AreEqual(1, obj.DependsOn.Count); Assert.AreSame(objRef, obj.DependsOn[0]); var references = obj.DependsOn[objRef]; Assert.AreEqual(1, references.Count); Assert.AreEqual(property, references[0].property); Assert.IsFalse(references[0].fullyQualified); } var expression = baseExpression; var oldObjName = objRef.Name; objRef.Name = oldObjName + " Renamed"; var expr1 = expression = expression.Replace(oldObjName, objRef.Name); Assert.AreEqual(expression, obj.GetDAX(property)); var oldTableName = tableRef.Name; tableRef.Name = oldTableName + " Renamed"; var expr2 = expression = expression.Replace(oldTableName, tableRef.Name); Assert.AreEqual(expression, obj.GetDAX(property)); oldObjName = objRef.Name; objRef.Name = "b b"; var expr3 = expression = expression.Replace(oldObjName, objRef.Name); Assert.AreEqual(expression, obj.GetDAX(property)); oldTableName = tableRef.Name; tableRef.Name = "a a"; var expr4 = expression = expression.Replace(oldTableName, tableRef.Name); Assert.AreEqual(expression, obj.GetDAX(property)); tmh.UndoManager.Undo(); Assert.AreEqual(expr3, obj.GetDAX(property)); tmh.UndoManager.Undo(); Assert.AreEqual(expr2, obj.GetDAX(property)); tmh.UndoManager.Undo(); Assert.AreEqual(expr1, obj.GetDAX(property)); tmh.UndoManager.Undo(); Assert.AreEqual(baseExpression, obj.GetDAX(property)); }
public static void FormatDax(this IDaxDependantObject obj) { objectsFlaggedForFormatting.Add(obj); }
public static IList <DaxToken> Tokenize(this IDaxDependantObject obj) { return(Tokenize(obj, DAXProperty.Expression)); }