private static void VerifyGroupByTokenProperties(IEnumerable <string> expectedEndPathIdentifiers, GroupByToken actual)
        {
            actual.Should().NotBeNull();

            if (expectedEndPathIdentifiers == null || !expectedEndPathIdentifiers.Any())
            {
                actual.Properties.Should().HaveCount(0);
            }
            else
            {
                actual.Properties.Should().HaveCount(expectedEndPathIdentifiers.Count());

                List <string> expectedIdentifierList = expectedEndPathIdentifiers.ToList();
                int           i = 0;
                foreach (EndPathToken actualProperty in actual.Properties)
                {
                    actualProperty.Should().NotBeNull();

                    EndPathToken endPathToken = actualProperty as EndPathToken;
                    endPathToken.Should().NotBeNull();
                    endPathToken.Identifier.Should().Be(expectedIdentifierList[i]);
                    i++;
                }
            }
        }
 public void PropertyAccessQueryTokenDefaultTest()
 {
     EndPathToken endPath = new EndPathToken("something", null);
     this.Assert.AreEqual(QueryTokenKind.EndPath, endPath.Kind, "The InternalKind property has an unexpected value.");
     this.Assert.AreEqual("something", endPath.Identifier, "The Name property has an unexpected value.");
     this.Assert.IsNull(endPath.NextToken, "The NextToken property should be null.");
 }
Exemplo n.º 3
0
        public void PropertyAccessOnDateCollectionWorks()
        {
            var token  = new EndPathToken("MyDates", null);
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeCollectionPropertyAccessQueryNode(HardCodedTestModel.GetPersonMyDatesProp());
        }
Exemplo n.º 4
0
        public void NestedGroupbyTransformationsInExpandIsAllowed()
        {
            // Arrange & Act
            ExpandTermToken expandTerm = this.ParseExpandOptions("($apply=groupby((Customer/CountryRegion,Product/Name),aggregate(Amount with sum as Total)))");

            // Assert
            Assert.NotNull(expandTerm);
            Assert.NotNull(expandTerm.ApplyOptions);
            QueryToken token = Assert.Single(expandTerm.ApplyOptions);

            GroupByToken groupBy = Assert.IsType <GroupByToken>(token);

            Assert.Equal(2, groupBy.Properties.Count());

            QueryToken   queryToken = groupBy.Properties.ElementAt(0);
            EndPathToken pathToken  = queryToken.ShouldBeEndPathToken("CountryRegion");

            pathToken.NextToken.ShouldBeInnerPathToken("Customer");

            queryToken = groupBy.Properties.ElementAt(1);
            pathToken  = queryToken.ShouldBeEndPathToken("Name");
            pathToken.NextToken.ShouldBeInnerPathToken("Product");

            Assert.NotNull(groupBy.Child);
            AggregateToken           aggregate = Assert.IsType <AggregateToken>(groupBy.Child);
            AggregateExpressionToken aggregateExpressionToken = Assert.Single(aggregate.Expressions);

            Assert.Equal("Total", aggregateExpressionToken.Alias);
            Assert.Equal(AggregationMethod.Sum, aggregateExpressionToken.Method);
            aggregateExpressionToken.Expression.ShouldBeEndPathToken("Amount");
        }
Exemplo n.º 5
0
        public void PropertyAccessOnDateTimeOffsetWorks()
        {
            var token  = new EndPathToken("Birthdate", null);
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonBirthdateProp());
        }
Exemplo n.º 6
0
        public void BoundFunctionWorks()
        {
            var token  = new EndPathToken("Fully.Qualified.Namespace.HasJob", null);
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValueFunctionCallQueryNode(HardCodedTestModel.GetFunctionForHasJob());
        }
Exemplo n.º 7
0
        public void PropertyAccessOnTimeOfDayWorks()
        {
            var token  = new EndPathToken("MyTimeOfDay", null);
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonMyTimeOfDayProp());
        }
Exemplo n.º 8
0
        public void ShouldThrowIfParameterIsNotInScope()
        {
            var    token = new EndPathToken("Color", new RangeVariableToken("notInScope"));
            Action bind  = () => this.propertyBinder.BindEndPath(token);

            bind.ShouldThrow <ODataException>().WithMessage(Strings.MetadataBinder_ParameterNotInScope("notInScope"));
        }
Exemplo n.º 9
0
        public void ShouldThrowIfParameterIsNotInScope()
        {
            var token = new EndPathToken("Color", new RangeVariableToken("notInScope"));
            Action bind = () => this.propertyBinder.BindEndPath(token);

            bind.ShouldThrow<ODataException>().WithMessage(Strings.MetadataBinder_ParameterNotInScope("notInScope"));
        }
Exemplo n.º 10
0
        public void NestedGroupbyTransformationsIsAllowed()
        {
            var result = this.ParseExpandOptions("($apply=groupby((Customer/CountryRegion,Product/Name),aggregate(Amount with sum as Total)))");

            result.Should().NotBeNull();

            QueryToken token = result.ApplyOptions.Single();

            token.Should().BeOfType <GroupByToken>();
            GroupByToken groupBy = token as GroupByToken;

            groupBy.Properties.Should().HaveCount(2);
            QueryToken   queryToken = groupBy.Properties.ElementAt(0);
            EndPathToken pathToken  = queryToken.ShouldBeEndPathToken("CountryRegion");

            pathToken.NextToken.ShouldBeInnerPathToken("Customer");

            queryToken = groupBy.Properties.ElementAt(1);
            pathToken  = queryToken.ShouldBeEndPathToken("Name");
            pathToken.NextToken.ShouldBeInnerPathToken("Product");

            groupBy.Child.Should().NotBeNull();
            groupBy.Child.Should().BeOfType <AggregateToken>();
            AggregateToken           aggregate = groupBy.Child as AggregateToken;
            AggregateExpressionToken aggregateExpressionToken = aggregate.Expressions.Single();

            aggregateExpressionToken.Alias.Should().Equals("Total");
            aggregateExpressionToken.Method.Should().Equals(AggregationMethod.Sum);
            aggregateExpressionToken.Expression.ShouldBeEndPathToken("Amount");
        }
Exemplo n.º 11
0
        private static void VerifyGroupByTokenProperties(IEnumerable <string> expectedEndPathIdentifiers, GroupByToken actual)
        {
            Assert.NotNull(actual);

            if (expectedEndPathIdentifiers == null || !expectedEndPathIdentifiers.Any())
            {
                Assert.Empty(actual.Properties);
            }
            else
            {
                Assert.Equal(actual.Properties.Count(), expectedEndPathIdentifiers.Count());

                List <string> expectedIdentifierList = expectedEndPathIdentifiers.ToList();
                int           i = 0;
                foreach (EndPathToken actualProperty in actual.Properties)
                {
                    Assert.NotNull(actualProperty);

                    EndPathToken endPathToken = actualProperty as EndPathToken;
                    Assert.NotNull(endPathToken);
                    Assert.Equal(endPathToken.Identifier, expectedIdentifierList[i]);
                    i++;
                }
            }
        }
Exemplo n.º 12
0
        public void PropertyAccessQueryTokenDefaultTest()
        {
            EndPathToken endPath = new EndPathToken("something", null);

            this.Assert.AreEqual(QueryTokenKind.EndPath, endPath.Kind, "The InternalKind property has an unexpected value.");
            this.Assert.AreEqual("something", endPath.Identifier, "The Name property has an unexpected value.");
            this.Assert.IsNull(endPath.NextToken, "The NextToken property should be null.");
        }
Exemplo n.º 13
0
        public void ImplicitPropertyAccessShouldCreatePropertyAccessQueryNode()
        {
            var token  = new EndPathToken("Shoe", null);
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonShoeProp()).
            And.Source.ShouldBeEntityRangeVariableReferenceNode(ExpressionConstants.It);
        }
Exemplo n.º 14
0
        public void ImplicitPropertyAccessShouldCreatePropertyAccessQueryNode()
        {
            var token = new EndPathToken("Shoe", null);
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonShoeProp()).
                And.Source.ShouldBeEntityRangeVariableReferenceNode(ExpressionConstants.It);
        }
Exemplo n.º 15
0
        public void OpenPropertyIsNotBoundToAFunction()
        {
            var           token  = new EndPathToken("SomeOpenProperty", null);
            BindingState  state  = GetBindingStateForTest(HardCodedTestModel.GetPaintingTypeReference(), HardCodedTestModel.GetPaintingsSet());
            EndPathBinder binder = new EndPathBinder(BindMethod, state);
            var           result = binder.BindEndPath(token);

            result.ShouldBeSingleValueOpenPropertyAccessQueryNode("SomeOpenProperty");
        }
Exemplo n.º 16
0
        public static EndPathToken ShouldBeEndPathToken(this QueryToken token, string expectedName)
        {
            Assert.NotNull(token);
            EndPathToken propertyAccessQueryToken = Assert.IsType <EndPathToken>(token);

            Assert.Equal(QueryTokenKind.EndPath, propertyAccessQueryToken.Kind);
            Assert.Equal(expectedName, propertyAccessQueryToken.Identifier);
            return(propertyAccessQueryToken);
        }
Exemplo n.º 17
0
        public void ExplicitPropertyAccessShouldCreatePropertyAccessQueryNode()
        {
            var token = new EndPathToken("Color", new RangeVariableToken("a"));
            EntityCollectionNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetDogsSet());
            this.bindingState.RangeVariables.Push(new EntityRangeVariable("a", HardCodedTestModel.GetDogTypeReference(), entityCollectionNode));
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetDogColorProp()).
                And.Source.ShouldBeEntityRangeVariableReferenceNode("a");
        }
Exemplo n.º 18
0
        public void ShouldThrowNotImplementedIfTypeIsOpen()
        {
            const string         OpenPropertyName     = "Style";
            var                  token                = new EndPathToken(OpenPropertyName, new RangeVariableToken("a"));
            EntityCollectionNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetPaintingsSet());
            SingleValueNode      parentNode           = new EntityRangeVariableReferenceNode("a", new EntityRangeVariable("a", HardCodedTestModel.GetPaintingTypeReference(), entityCollectionNode));
            var                  propertyNode         = EndPathBinder.GeneratePropertyAccessQueryForOpenType(
                token, parentNode);

            propertyNode.ShouldBeSingleValueOpenPropertyAccessQueryNode(OpenPropertyName);
        }
Exemplo n.º 19
0
        public void ExplicitPropertyAccessShouldCreatePropertyAccessQueryNode()
        {
            var token = new EndPathToken("Color", new RangeVariableToken("a"));
            EntityCollectionNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetDogsSet());

            this.bindingState.RangeVariables.Push(new EntityRangeVariable("a", HardCodedTestModel.GetDogTypeReference(), entityCollectionNode));
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetDogColorProp()).
            And.Source.ShouldBeEntityRangeVariableReferenceNode("a");
        }
Exemplo n.º 20
0
        /// <summary>
        /// This method generates a <see cref="SingleValueOpenPropertyAccessNode"/> for properties of open type
        /// </summary>
        /// <param name="endPathToken">EndPathToken to bind into an open property node.</param>
        /// <param name="parentNode">Parent node of this open property</param>
        /// <returns>Will return a <see cref="SingleValueOpenPropertyAccessNode"/> when open types are supported</returns>
        internal static SingleValueOpenPropertyAccessNode GeneratePropertyAccessQueryForOpenType(EndPathToken endPathToken, SingleValueNode parentNode)
        {
            if (parentNode.TypeReference != null && !parentNode.TypeReference.Definition.IsOpenType())
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclared(
                    parentNode.TypeReference.FullName(),
                    endPathToken.Identifier));
            }

            return new SingleValueOpenPropertyAccessNode(parentNode, endPathToken.Identifier);
        }
 public bool Visit(EndPathToken tokenIn)
 {
     if (isTableQuery)
     {
         stringBuilder.Append(tableEntityDotId);
     }
     else
     {
         stringBuilder.Append(EntityTranslator.GetPropertyName(tokenIn.Identifier, enableTimestampQuery));
     }
     return(true);
 }
Exemplo n.º 22
0
        /// <summary>
        /// Write the property access token as URI part to this builder.
        /// </summary>
        /// <param name="endPath">To write as URI part.</param>
        private void WritePropertyAccess(EndPathToken endPath)
        {
            ExceptionUtils.CheckArgumentNotNull(endPath, "endPath");

            if (endPath.NextToken != null)
            {
                this.WriteQuery(endPath.NextToken);
                this.builder.Append(ExpressionConstants.SymbolForwardSlash);
            }

            this.builder.Append(endPath.Identifier);
        }
Exemplo n.º 23
0
        public void ShouldThrowIfTypeNotOpen()
        {
            var token = new EndPathToken("Color", new RangeVariableToken("a"));
            EntityCollectionNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetDogsSet());
            SingleValueNode      parentNode           = new EntityRangeVariableReferenceNode("a", new EntityRangeVariable("a", HardCodedTestModel.GetPersonTypeReference(), entityCollectionNode));
            Action getQueryNode = () => EndPathBinder.GeneratePropertyAccessQueryForOpenType(
                token, parentNode);

            getQueryNode.ShouldThrow <ODataException>().WithMessage(
                Strings.MetadataBinder_PropertyNotDeclared(parentNode.GetEdmTypeReference().FullName(),
                                                           token.Identifier));
        }
Exemplo n.º 24
0
        /// <summary>
        /// Binds a an end path token into a PropertyAccessToken, OpenPropertyToken, or FunctionCallToken.
        /// </summary>
        /// <param name="endPathToken">The property access token to bind.</param>
        /// <returns>A Query node representing this endpath token, bound to metadata.</returns>
        internal QueryNode BindEndPath(EndPathToken endPathToken)
        {
            ExceptionUtils.CheckArgumentNotNull(endPathToken, "EndPathToken");
            ExceptionUtils.CheckArgumentStringNotNullOrEmpty(endPathToken.Identifier, "EndPathToken.Identifier");

            // Set the parent (get the parent type, so you can check whether the Identifier inside EndPathToken really is legit offshoot of the parent type)
            QueryNode parent = this.DetermineParentNode(endPathToken);

            QueryNode boundFunction;

            SingleValueNode singleValueParent = parent as SingleValueNode;

            if (singleValueParent == null)
            {
                if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, parent, state, out boundFunction))
                {
                    return(boundFunction);
                }

                // Collection with any or all expression is already supported and handled separately.
                // Add support of collection with $count segment.
                CollectionNode colNode = parent as CollectionNode;
                if (colNode != null && endPathToken.Identifier.Equals(UriQueryConstants.CountSegment))
                {
                    // create a collection count node for collection node property.
                    return(new CountNode(colNode));
                }

                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyAccessSourceNotSingleValue(endPathToken.Identifier));
            }


            // Now that we have the parent type, can find its corresponding EDM type
            IEdmStructuredTypeReference structuredParentType =
                singleValueParent.TypeReference == null ? null : singleValueParent.TypeReference.AsStructuredOrNull();

            IEdmProperty property =
                structuredParentType == null ? null : this.Resolver.ResolveProperty(structuredParentType.StructuredDefinition(), endPathToken.Identifier);

            if (property != null)
            {
                return(GeneratePropertyAccessQueryNode(singleValueParent, property));
            }

            if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, singleValueParent, state, out boundFunction))
            {
                return(boundFunction);
            }

            return(GeneratePropertyAccessQueryForOpenType(endPathToken, singleValueParent));
        }
Exemplo n.º 25
0
        private static void VerifyAggregateExpressionToken(string expectedEndPathIdentifier, AggregationMethodDefinition expectedVerb, string expectedAlias, AggregateExpressionToken actual)
        {
            Assert.NotNull(actual.Expression);

            EndPathToken expression = actual.Expression as EndPathToken;

            Assert.NotNull(expression);
            Assert.Equal(expectedEndPathIdentifier, expression.Identifier);

            Assert.Equal(expectedVerb.MethodLabel, actual.MethodDefinition.MethodLabel);
            Assert.Equal(expectedVerb.MethodKind, actual.MethodDefinition.MethodKind);

            Assert.Equal(expectedAlias, actual.Alias);
        }
        private static void VerifyAggregateExpressionToken(string expectedEndPathIdentifier, AggregationMethodDefinition expectedVerb, string expectedAlias, AggregateExpressionToken actual)
        {
            actual.Expression.Should().NotBeNull();

            EndPathToken expression = actual.Expression as EndPathToken;

            expression.Should().NotBeNull();
            expression.Identifier.Should().Be(expectedEndPathIdentifier);

            actual.MethodDefinition.MethodLabel.Should().Be(expectedVerb.MethodLabel);
            actual.MethodDefinition.MethodKind.Should().Be(expectedVerb.MethodKind);

            actual.Alias.Should().Be(expectedAlias);
        }
Exemplo n.º 27
0
        public void ShouldThrowNotImplementedIfTypeIsOpen()
        {
            const string           OpenPropertyName     = "Style";
            var                    token                = new EndPathToken(OpenPropertyName, new RangeVariableToken("a"));
            CollectionResourceNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetPaintingsSet());
            SingleValueNode        parentNode           = new ResourceRangeVariableReferenceNode("a", new ResourceRangeVariable("a", HardCodedTestModel.GetPaintingTypeReference(), entityCollectionNode));

            var state          = new BindingState(this.configuration);
            var metadataBinder = new MetadataBinder(state);
            var endPathBinder  = new EndPathBinder(metadataBinder.Bind, state);
            var propertyNode   = endPathBinder.GeneratePropertyAccessQueryForOpenType(
                token, parentNode);

            propertyNode.ShouldBeSingleValueOpenPropertyAccessQueryNode(OpenPropertyName);
        }
Exemplo n.º 28
0
        private static void VerifyBinaryOperatorToken <T>(string expectedEndPathIdentifier, BinaryOperatorKind expectedOperator, T expectedLiteralValue, BinaryOperatorToken actual)
        {
            Assert.NotNull(actual);
            Assert.Equal(actual.OperatorKind, expectedOperator);

            EndPathToken left = actual.Left as EndPathToken;

            Assert.NotNull(left);
            Assert.Equal(left.Identifier, expectedEndPathIdentifier);

            LiteralToken right = actual.Right as LiteralToken;

            Assert.NotNull(right);
            Assert.Equal(right.Value, expectedLiteralValue);
        }
Exemplo n.º 29
0
        /// <summary>
        /// Determines the parent node. If the token has a parent, that token is bound. If not, then we
        /// use the implicit parameter from the BindingState as the parent node.
        /// </summary>
        /// <param name="segmentToken">Token to determine the parent node for.</param>
        /// <returns>A SingleValueQueryNode that is the parent node of the <paramref name="segmentToken"/>.</returns>
        private QueryNode DetermineParentNode(EndPathToken segmentToken)
        {
            ExceptionUtils.CheckArgumentNotNull(segmentToken, "segmentToken");
            ExceptionUtils.CheckArgumentNotNull(state, "state");

            if (segmentToken.NextToken != null)
            {
                return(this.bindMethod(segmentToken.NextToken));
            }
            else
            {
                RangeVariable implicitRangeVariable = state.ImplicitRangeVariable;
                return(NodeFactory.CreateRangeVariableReferenceNode(implicitRangeVariable));
            }
        }
        private static void VerifyBinaryOperatorToken <T>(string expectedEndPathIdentifier, BinaryOperatorKind expectedOperator, T expectedLiteralValue, BinaryOperatorToken actual)
        {
            actual.Should().NotBeNull();
            actual.OperatorKind.Should().Be(expectedOperator);

            EndPathToken left = actual.Left as EndPathToken;

            left.Should().NotBeNull();
            left.Identifier.Should().Be(expectedEndPathIdentifier);

            LiteralToken right = actual.Right as LiteralToken;

            right.Should().NotBeNull();
            right.Value.Should().Be(expectedLiteralValue);
        }
Exemplo n.º 31
0
        public void ShouldThrowIfTypeNotOpen()
        {
            var token = new EndPathToken("Color", new RangeVariableToken("a"));
            CollectionResourceNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetDogsSet());
            SingleValueNode        parentNode           = new ResourceRangeVariableReferenceNode("a", new ResourceRangeVariable("a", HardCodedTestModel.GetPersonTypeReference(), entityCollectionNode));

            var    state          = new BindingState(this.configuration);
            var    metadataBinder = new MetadataBinder(state);
            var    endPathBinder  = new EndPathBinder(metadataBinder.Bind, state);
            Action getQueryNode   = () => endPathBinder.GeneratePropertyAccessQueryForOpenType(
                token, parentNode);

            getQueryNode.Throws <ODataException>(
                Strings.MetadataBinder_PropertyNotDeclared(parentNode.GetEdmTypeReference().FullName(),
                                                           token.Identifier));
        }
        public Expression Visit(EndPathToken tokenIn)
        {
            if (tokenIn.Identifier.Equals("null", StringComparison.OrdinalIgnoreCase))
            {
                return(Expression.Constant(null));
            }

            var prop = _properties.FirstOrDefault(i => i.Name.Equals(tokenIn.Identifier, StringComparison.OrdinalIgnoreCase));

            if (prop != null)
            {
                return(Expression.Property(_parameter, prop));
            }

            return(Expression.Constant(tokenIn.Identifier));
        }
Exemplo n.º 33
0
        public void ShouldNotThrowIfTypeNotOpenButAggregateApplied()
        {
            var token = new EndPathToken("Color", new RangeVariableToken("a"));
            CollectionResourceNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetDogsSet());
            SingleValueNode        parentNode           = new ResourceRangeVariableReferenceNode("a", new ResourceRangeVariable("a", HardCodedTestModel.GetPersonTypeReference(), entityCollectionNode));

            var state = new BindingState(this.configuration);

            state.AggregatedPropertyNames = new HashSet <EndPathToken> {
                new EndPathToken("Color", new RangeVariableToken("a"))
            };
            var metadataBinder = new MetadataBinder(state);
            var endPathBinder  = new EndPathBinder(metadataBinder.Bind, state);
            var propertyNode   = endPathBinder.GeneratePropertyAccessQueryForOpenType(
                token, parentNode);

            propertyNode.ShouldBeSingleValueOpenPropertyAccessQueryNode("Color");
        }
Exemplo n.º 34
0
 private IEnumerable <EndPathToken> GetGroupByPaths(IEnumerable <GroupByPropertyNode> nodes, EndPathToken token)
 {
     foreach (var node in nodes)
     {
         var nodeToken = new EndPathToken(node.Name, token);
         if (node.ChildTransformations == null || !node.ChildTransformations.Any())
         {
             yield return(nodeToken);
         }
         else
         {
             foreach (var child in GetGroupByPaths(node.ChildTransformations, nodeToken))
             {
                 yield return(child);
             }
         }
     }
 }
Exemplo n.º 35
0
        /// <summary>
        /// Binds a an end path token into a PropertyAccessToken, OpenPropertyToken, or FunctionCallToken.
        /// </summary>
        /// <param name="endPathToken">The property access token to bind.</param>
        /// <param name="state">State of the binding algorithm.</param>
        /// <returns>A Query node representing this endpath token, bound to metadata.</returns>
        internal QueryNode BindEndPath(EndPathToken endPathToken, BindingState state)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(endPathToken, "EndPathToken");
            ExceptionUtils.CheckArgumentStringNotNullOrEmpty(endPathToken.Identifier, "EndPathToken.Identifier");

            // Set the parent (get the parent type, so you can check whether the Identifier inside EndPathToken really is legit offshoot of the parent type)
            QueryNode parent = this.DetermineParentNode(endPathToken, state);

            QueryNode boundFunction;

            SingleValueNode singleValueParent = parent as SingleValueNode;

            if (singleValueParent == null)
            {
                if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, parent, state, out boundFunction))
                {
                    return(boundFunction);
                }

                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyAccessSourceNotSingleValue(endPathToken.Identifier));
            }


            // Now that we have the parent type, can find its corresponding EDM type
            IEdmStructuredTypeReference structuredParentType =
                singleValueParent.TypeReference == null ? null : singleValueParent.TypeReference.AsStructuredOrNull();

            IEdmProperty property =
                structuredParentType == null ? null : structuredParentType.FindProperty(endPathToken.Identifier);

            if (property != null)
            {
                return(GeneratePropertyAccessQueryNode(singleValueParent, property));
            }

            if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, singleValueParent, state, out boundFunction))
            {
                return(boundFunction);
            }

            return(GeneratePropertyAccessQueryForOpenType(endPathToken, singleValueParent));
        }
Exemplo n.º 36
0
        public void ManyParametersInScopeShouldNotInterfere()
        {
            var token = new EndPathToken("Shoe", null);

            EntityCollectionNode dogsEntityCollectionNode = new EntitySetNode(HardCodedTestModel.GetDogsSet());
            EntityCollectionNode peopleEntityCollectionNode = new EntitySetNode(HardCodedTestModel.GetPeopleSet());

            this.bindingState.RangeVariables.Push(new EntityRangeVariable("a", HardCodedTestModel.GetDogTypeReference(), dogsEntityCollectionNode));
            this.bindingState.RangeVariables.Push(new EntityRangeVariable("b", HardCodedTestModel.GetDogTypeReference(), dogsEntityCollectionNode));
            this.bindingState.RangeVariables.Push(new EntityRangeVariable("c", HardCodedTestModel.GetDogTypeReference(), dogsEntityCollectionNode));
            this.bindingState.RangeVariables.Push(new EntityRangeVariable("d", HardCodedTestModel.GetDogTypeReference(), dogsEntityCollectionNode));
            this.bindingState.RangeVariables.Push(new EntityRangeVariable("e", HardCodedTestModel.GetDogTypeReference(), dogsEntityCollectionNode));
            this.bindingState.RangeVariables.Push(new EntityRangeVariable("f", HardCodedTestModel.GetPersonTypeReference(), peopleEntityCollectionNode));
            this.bindingState.RangeVariables.Push(new EntityRangeVariable("g", HardCodedTestModel.GetPersonTypeReference(), peopleEntityCollectionNode));
            this.bindingState.RangeVariables.Push(new EntityRangeVariable("h", HardCodedTestModel.GetPersonTypeReference(), peopleEntityCollectionNode));
            this.bindingState.RangeVariables.Push(new EntityRangeVariable("i", HardCodedTestModel.GetPersonTypeReference(), peopleEntityCollectionNode));

            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonShoeProp()).
                And.Source.ShouldBeEntityRangeVariableReferenceNode(ExpressionConstants.It);
        }
Exemplo n.º 37
0
        /// <summary>
        /// Determines the parent node. If the token has a parent, that token is bound. If not, then we 
        /// use the implicit parameter from the BindingState as the parent node.
        /// </summary>
        /// <param name="segmentToken">Token to determine the parent node for.</param>
        /// <returns>A SingleValueQueryNode that is the parent node of the <paramref name="segmentToken"/>.</returns>
        private QueryNode DetermineParentNode(EndPathToken segmentToken)
        {
            ExceptionUtils.CheckArgumentNotNull(segmentToken, "segmentToken");
            ExceptionUtils.CheckArgumentNotNull(state, "state");

            if (segmentToken.NextToken != null)
            {
                return this.bindMethod(segmentToken.NextToken);
            }
            else
            {
                RangeVariable implicitRangeVariable = state.ImplicitRangeVariable;
                return NodeFactory.CreateRangeVariableReferenceNode(implicitRangeVariable);
            }
        }
Exemplo n.º 38
0
        /// <summary>
        /// Binds a an end path token into a PropertyAccessToken, OpenPropertyToken, or FunctionCallToken.
        /// </summary>
        /// <param name="endPathToken">The property access token to bind.</param>
        /// <returns>A Query node representing this endpath token, bound to metadata.</returns>
        internal QueryNode BindEndPath(EndPathToken endPathToken)
        {
            ExceptionUtils.CheckArgumentNotNull(endPathToken, "EndPathToken");
            ExceptionUtils.CheckArgumentStringNotNullOrEmpty(endPathToken.Identifier, "EndPathToken.Identifier");

            // Set the parent (get the parent type, so you can check whether the Identifier inside EndPathToken really is legit offshoot of the parent type)
            QueryNode parent = this.DetermineParentNode(endPathToken);

            QueryNode boundFunction;

            SingleValueNode singleValueParent = parent as SingleValueNode;
            if (singleValueParent == null)
            {
                if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, parent, state, out boundFunction))
                {
                    return boundFunction;
                }

                // Collection with any or all expression is already supported and handled separately.
                // Add support of collection with $count segment.
                CollectionNode colNode = parent as CollectionNode;
                if (colNode != null && endPathToken.Identifier.Equals(UriQueryConstants.CountSegment))
                {
                    // create a collection count node for collection node property.
                    return new CountNode(colNode);
                }

                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyAccessSourceNotSingleValue(endPathToken.Identifier));
            }


            // Now that we have the parent type, can find its corresponding EDM type
            IEdmStructuredTypeReference structuredParentType =
                singleValueParent.TypeReference == null ? null : singleValueParent.TypeReference.AsStructuredOrNull();

            IEdmProperty property =
                structuredParentType == null ? null : this.Resolver.ResolveProperty(structuredParentType.StructuredDefinition(), endPathToken.Identifier);

            if (property != null)
            {
                return GeneratePropertyAccessQueryNode(singleValueParent, property);
            }

            if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, singleValueParent, state, out boundFunction))
            {
                return boundFunction;
            }

            return GeneratePropertyAccessQueryForOpenType(endPathToken, singleValueParent);
        }
Exemplo n.º 39
0
 private static void VerifyPropertyAccessQueryTokensAreEqual(EndPathToken expected, EndPathToken actual, AssertionHandler assert)
 {
     assert.AreEqual(expected.Identifier, actual.Identifier, "The Name of the property access token doesn't match the expected one.");
     VerifyQueryTokensAreEqual(expected.NextToken, actual.NextToken, assert);
 }
Exemplo n.º 40
0
 public void KindIsInnerPath()
 {
     EndPathToken endPathToken = new EndPathToken("stuff", new LiteralToken(1));
     endPathToken.Kind.Should().Be(QueryTokenKind.EndPath);
 }
Exemplo n.º 41
0
        public void BoundFunctionWorks()
        {
            var token = new EndPathToken("Fully.Qualified.Namespace.HasJob", null);
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValueFunctionCallQueryNode(HardCodedTestModel.GetFunctionForHasJob());
        }
Exemplo n.º 42
0
 /// <summary>
 /// Try to bind an end path token as a function call. Used for bound functions without parameters
 /// that parse as end path tokens syntactically
 /// </summary>
 /// <param name="endPathToken">the end path token to bind</param>
 /// <param name="parent">the parent node to this end path token.</param>
 /// <param name="state">the current state of the binding algorithm</param>
 /// <param name="boundFunction">a single value function call node representing the function call, if it exists</param>
 /// <returns>true if we found a function for this token, false otherwise.</returns>
 internal bool TryBindEndPathAsFunctionCall(EndPathToken endPathToken, QueryNode parent, BindingState state, out QueryNode boundFunction)
 {
     return this.TryBindIdentifier(endPathToken.Identifier, null, parent, state, out boundFunction);
 }
Exemplo n.º 43
0
 /// <summary>
 /// Binds a property access token.
 /// </summary>
 /// <param name="endPathToken">The property access token to bind.</param>
 /// <returns>The bound property access token.</returns>
 protected virtual QueryNode BindEndPath(EndPathToken endPathToken)
 {
     EndPathBinder endPathBinder = new EndPathBinder(this.Bind, this.BindingState);
     return endPathBinder.BindEndPath(endPathToken);
 }
Exemplo n.º 44
0
 public void ParentSetCorrectly()
 {
     EndPathToken endPathToken = new EndPathToken("stuff", new LiteralToken(1));
     endPathToken.NextToken.ShouldBeLiteralQueryToken(1);
 }
Exemplo n.º 45
0
 public void NameSetCorrectly()
 {
     EndPathToken endPathToken = new EndPathToken("stuff", new LiteralToken(1));
     endPathToken.Identifier.Should().Be("stuff");
 }
Exemplo n.º 46
0
        public void ShouldThrowIfTypeNotOpen()
        {
            var token = new EndPathToken("Color", new RangeVariableToken("a"));
            EntityCollectionNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetDogsSet());
            SingleValueNode parentNode = new EntityRangeVariableReferenceNode("a", new EntityRangeVariable("a", HardCodedTestModel.GetPersonTypeReference(), entityCollectionNode));
            Action getQueryNode = () => EndPathBinder.GeneratePropertyAccessQueryForOpenType(
                token, parentNode);

            getQueryNode.ShouldThrow<ODataException>().WithMessage(
                Strings.MetadataBinder_PropertyNotDeclared(parentNode.GetEdmTypeReference().ODataFullName(),
                                                                                    token.Identifier));

        }
 private bool RunBindEndPathAsFunctionCall(string endPathIdentifier, out QueryNode functionCallNode)
 {
     var boundFunctionCallToken = new EndPathToken(endPathIdentifier, null);
     return this.functionCallBinder.TryBindEndPathAsFunctionCall(boundFunctionCallToken,
                                                          new EntityRangeVariableReferenceNode(
                                                              ExpressionConstants.It,
                                                              (EntityRangeVariable)
                                                              this.binder.BindingState.ImplicitRangeVariable),
                                                          this.binder.BindingState, out functionCallNode);
 }
Exemplo n.º 48
0
 public void OpenPropertyIsNotBoundToAFunction()
 {
     var token = new EndPathToken("SomeOpenProperty", null);
     BindingState state = GetBindingStateForTest(HardCodedTestModel.GetPaintingTypeReference(), HardCodedTestModel.GetPaintingsSet());
     EndPathBinder binder = new EndPathBinder(BindMethod, state);
     var result = binder.BindEndPath(token);
     result.ShouldBeSingleValueOpenPropertyAccessQueryNode("SomeOpenProperty");
 }
Exemplo n.º 49
0
        public void ShouldNotThrowIfTypeNotOpenButAggregateApplied()
        {
            var token = new EndPathToken("Color", new RangeVariableToken("a"));
            EntityCollectionNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetDogsSet());
            SingleValueNode parentNode = new EntityRangeVariableReferenceNode("a", new EntityRangeVariable("a", HardCodedTestModel.GetPersonTypeReference(), entityCollectionNode));

            var state = new BindingState(this.configuration);
            state.AggregatedPropertyNames = new List<string> { "Color" };
            var metadataBinder = new MetadataBinder(state);
            var endPathBinder = new EndPathBinder(metadataBinder.Bind, state);
            var propertyNode = endPathBinder.GeneratePropertyAccessQueryForOpenType(
                token, parentNode);

            propertyNode.ShouldBeSingleValueOpenPropertyAccessQueryNode("Color");
        }
Exemplo n.º 50
0
        public void PropertyAccessOnDateWorks()
        {
            var token = new EndPathToken("MyDate", null);
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonMyDateProp());
        }
Exemplo n.º 51
0
        public static IEnumerable<ExpressionTestCase> PropertyAccessTestCases(string [] propertyNames)
        {
            foreach (var properties in propertyNames.Variations().Where(p => p.Length > 0))
            {
                // Simple property access paths
                QueryToken pathToken = null;
                foreach (string propertyName in properties)
                {
                    pathToken = new InnerPathToken(propertyName, pathToken, null);
                }
                InnerPathToken pathNav = (InnerPathToken)pathToken;
                pathToken = new EndPathToken(pathNav.Identifier, pathNav.NextToken);

                yield return new ExpressionTestCase()
                {
                    Expression = string.Join("/", properties),
                    ExpectedToken = pathToken
                };
            }
        }
Exemplo n.º 52
0
        /// <summary>
        /// Binds a an end path token into a PropertyAccessToken, OpenPropertyToken, or FunctionCallToken.
        /// </summary>
        /// <param name="endPathToken">The property access token to bind.</param>
        /// <returns>A Query node representing this endpath token, bound to metadata.</returns>
        internal QueryNode BindEndPath(EndPathToken endPathToken)
        {
            ExceptionUtils.CheckArgumentNotNull(endPathToken, "EndPathToken");
            ExceptionUtils.CheckArgumentStringNotNullOrEmpty(endPathToken.Identifier, "EndPathToken.Identifier");

            // Set the parent (get the parent type, so you can check whether the Identifier inside EndPathToken really is legit offshoot of the parent type)
            QueryNode parent = this.DetermineParentNode(endPathToken);

            QueryNode boundFunction;

            SingleValueNode singleValueParent = parent as SingleValueNode;
            if (singleValueParent == null)
            {
                if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, parent, state, out boundFunction))
                {
                    return boundFunction;
                }

                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyAccessSourceNotSingleValue(endPathToken.Identifier));
            }


            // Now that we have the parent type, can find its corresponding EDM type
            IEdmStructuredTypeReference structuredParentType =
                singleValueParent.TypeReference == null ? null : singleValueParent.TypeReference.AsStructuredOrNull();

            IEdmProperty property =
                structuredParentType == null ? null : this.Resolver.ResolveProperty(structuredParentType.StructuredDefinition(), endPathToken.Identifier);

            if (property != null)
            {
                return GeneratePropertyAccessQueryNode(singleValueParent, property);
            }

            if (functionCallBinder.TryBindEndPathAsFunctionCall(endPathToken, singleValueParent, state, out boundFunction))
            {
                return boundFunction;
            }

            return GeneratePropertyAccessQueryForOpenType(endPathToken, singleValueParent);
        }
Exemplo n.º 53
0
        public void ShouldThrowNotImplementedIfTypeIsOpen()
        {
            const string OpenPropertyName = "Style";
            var token = new EndPathToken(OpenPropertyName, new RangeVariableToken("a"));
            EntityCollectionNode entityCollectionNode = new EntitySetNode(HardCodedTestModel.GetPaintingsSet());
            SingleValueNode parentNode = new EntityRangeVariableReferenceNode("a", new EntityRangeVariable("a", HardCodedTestModel.GetPaintingTypeReference(), entityCollectionNode));
            var propertyNode = EndPathBinder.GeneratePropertyAccessQueryForOpenType(
                token, parentNode);

            propertyNode.ShouldBeSingleValueOpenPropertyAccessQueryNode(OpenPropertyName);
        }
Exemplo n.º 54
0
        public void PropertyAccessOnTimeOfDayCollectionWorks()
        {
            var token = new EndPathToken("MyTimeOfDays", null);
            var result = this.propertyBinder.BindEndPath(token);

            result.ShouldBeCollectionPropertyAccessQueryNode(HardCodedTestModel.GetPersonMyTimeOfDaysProp());
        }