Beispiel #1
0
        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;
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
 internal bool RemoveExpand(IExpandInfo expandInfo)
 {
     Contracts.AssertValue(expandInfo);
     return(_expandQueryOptions.Remove(expandInfo.ExpandPath));
 }
Beispiel #8
0
        public static ExpandQueryOptions CreateExpandQueryOptions(IExpandInfo entityInfo)
        {
            Contracts.AssertValue(entityInfo);

            return(new ExpandQueryOptions(entityInfo, selects: new HashSet <string>(), isRoot: true, parent: null));
        }