private ExpandQueryOptions(IExpandInfo expandInfo, IEnumerable <string> selects, bool isRoot, ExpandQueryOptions parent) { Contracts.AssertValue(expandInfo); Contracts.AssertValue(selects); Contracts.AssertValueOrNull(parent); ExpandInfo = expandInfo; _selects = new HashSet <string>(); _keyColumns = new HashSet <string>(); foreach (var select in selects) { _selects.Add(select); } var parentDataSource = ExpandInfo.ParentDataSource as IExternalTabularDataSource; var keyColumns = parentDataSource?.GetKeyColumns(ExpandInfo); foreach (var keyColumn in keyColumns) { _selects.Add(keyColumn); } _expands = new HashSet <ExpandQueryOptions>(); IsRoot = isRoot; Parent = parent; }
internal bool TryGetExpandQueryOptions(IExpandInfo expandInfo, out ExpandQueryOptions expandQueryOptions) { foreach (var expandQueryOptionsKVP in Expands) { if (expandQueryOptionsKVP.Value.ExpandInfo.ExpandPath == expandInfo.ExpandPath) { expandQueryOptions = (ExpandQueryOptions)expandQueryOptionsKVP.Value; return(true); } } expandQueryOptions = null; return(false); }
internal bool AddExpand(IExpandInfo expandInfo, out ExpandQueryOptions expandQueryOptions) { if (expandInfo == null || !TabularDataSourceInfo.CanIncludeExpand(expandInfo)) { expandQueryOptions = null; return(false); } if (_expandQueryOptions.ContainsKey(expandInfo.ExpandPath)) { expandQueryOptions = (ExpandQueryOptions)_expandQueryOptions[expandInfo.ExpandPath]; return(false); } expandQueryOptions = ExpandQueryOptions.CreateExpandQueryOptions(expandInfo); return(AddExpand(expandInfo.ExpandPath, expandQueryOptions)); }
internal bool AddExpand(IExpandInfo expandInfoToAdd, out ExpandQueryOptions expand) { if (expandInfoToAdd == null) { expand = null; return(false); } var parentDataSource = ExpandInfo.ParentDataSource as IExternalTabularDataSource; if (!parentDataSource.CanIncludeExpand(ExpandInfo, expandInfoToAdd)) { expand = null; return(false); } expand = CreateExpandQueryOptions(expandInfoToAdd); return(AddExpand(expand)); }
public ExpandQueryOptions AppendDataEntity(IExpandInfo expandInfo) { var queryOptions = CreateExpandQueryOptions(expandInfo); foreach (var currentExpand in Expands) { if (!currentExpand.ExpandInfo.Equals(queryOptions.ExpandInfo)) { continue; } foreach (var qoSelect in queryOptions.Selects) { currentExpand.AddSelect(qoSelect); } return(currentExpand); } var expand = new ExpandQueryOptions(queryOptions.ExpandInfo, queryOptions.Selects, isRoot: false, parent: this); AddExpand(expand); return(expand); }
public bool IsValidDottedNameNode(DottedNameNode node, TexlBinding binding, OperationCapabilityMetadata metadata, IOpDelegationStrategy opDelStrategy) { Contracts.AssertValue(node); Contracts.AssertValue(binding); Contracts.AssertValueOrNull(opDelStrategy); var isRowScoped = binding.IsRowScope(node); if (!isRowScoped) { return(IsValidNode(node, binding)); } bool isRowScopedDelegationExempted; if (!IsValidRowScopedDottedNameNode(node, binding, metadata, out isRowScopedDelegationExempted)) { var telemetryMessage = string.Format("Kind:{0}, isRowScoped:{1}", node.Kind, isRowScoped); SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage); return(false); } if (isRowScopedDelegationExempted) { binding.SetBlockScopedConstantNode(node); return(true); } if (binding.TryGetFullRecordRowScopeAccessInfo(node, out var firstNameInfo)) { // This means that this row scoped field is from some parent scope which is non-delegatable. That should deny delegation at that point. // For this scope, this means that value will be provided from some other source. // For example, AddColumns(CDS As Left, "Column1", LookUp(CDS1, Left.Name in FirstName)) // CDS - *[Name:s], CDS1 - *[FirstName:s] if (GetCapabilityMetadata(firstNameInfo) == null) { return(true); } } if (!binding.GetType(node.Left).HasExpandInfo) { DPath columnPath; if (!BinderUtils.TryConvertNodeToDPath(binding, node, out columnPath) || !metadata.IsDelegationSupportedByColumn(columnPath, _function.FunctionDelegationCapability)) { var safeColumnName = CharacterUtils.MakeSafeForFormatString(columnPath.ToDottedSyntax()); var message = string.Format(StringResources.Get(TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn), safeColumnName); SuggestDelegationHintAndAddTelemetryMessage(node, binding, message, TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn, safeColumnName); TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.NoDelSupportByColumn, node, binding, _function, DelegationTelemetryInfo.CreateNoDelSupportByColumnTelemetryInfo(columnPath.ToDottedSyntax())); return(false); } // If there is any operator applied on this node then check if column supports operation. return(opDelStrategy?.IsOpSupportedByColumn(metadata, node, columnPath, binding) ?? true); } // If there is an entity reference then we need to do additional verification. IExpandInfo info = binding.GetType(node.Left).ExpandInfo.VerifyValue(); var dataSourceInfo = info.ParentDataSource; IDataEntityMetadata entityMetadata; if (!dataSourceInfo.DataEntityMetadataProvider.TryGetEntityMetadata(info.Identity, out entityMetadata)) { var telemetryMessage = string.Format("Kind:{0}, isRowScoped:{1}, no metadata found for entity {2}", node.Kind, isRowScoped, CharacterUtils.MakeSafeForFormatString(info.Identity)); SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage); return(false); } OperationCapabilityMetadata entityCapabilityMetadata = GetScopedOperationCapabilityMetadata(entityMetadata.DelegationMetadata); string maybeLogicalName; DName columnName = node.Right.Name; if (entityMetadata.DisplayNameMapping.TryGetFromSecond(node.Right.Name.Value, out maybeLogicalName)) { columnName = new DName(maybeLogicalName); } var entityColumnPath = DPath.Root.Append(columnName); if (!entityCapabilityMetadata.IsDelegationSupportedByColumn(entityColumnPath, _function.FunctionDelegationCapability)) { var safeColumnName = CharacterUtils.MakeSafeForFormatString(columnName.Value); var message = string.Format(StringResources.Get(TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn), safeColumnName); SuggestDelegationHintAndAddTelemetryMessage(node, binding, message, TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn, safeColumnName); TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.NoDelSupportByColumn, node, binding, _function, DelegationTelemetryInfo.CreateNoDelSupportByColumnTelemetryInfo(columnName)); return(false); } // If there is any operator applied on this node then check if column supports operation. return(opDelStrategy?.IsOpSupportedByColumn(entityCapabilityMetadata, node, entityColumnPath, binding) ?? true); }
internal bool RemoveExpand(IExpandInfo expandInfo) { Contracts.AssertValue(expandInfo); return(_expandQueryOptions.Remove(expandInfo.ExpandPath)); }
public static ExpandQueryOptions CreateExpandQueryOptions(IExpandInfo entityInfo) { Contracts.AssertValue(entityInfo); return(new ExpandQueryOptions(entityInfo, selects: new HashSet <string>(), isRoot: true, parent: null)); }