public void ParsedFunctionWithAParent()
 {
     var tokenizer = GetFunctionCallParser("func()");
     var parent = new InnerPathToken("Customer", null, null);
     QueryToken result = tokenizer.ParseIdentifierAsFunction(parent);
     result.ShouldBeFunctionCallToken("func").And.Source.Should().BeSameAs(parent);
 }
 public void NamedValuesSetCorrectly()
 {
     InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });
     innerPathToken.NamedValues.Count().Should().Be(1);
     innerPathToken.NamedValues.ElementAt(0).Name.Should().Be("blah");
     innerPathToken.NamedValues.ElementAt(0).Value.ShouldBeLiteralQueryToken(1);
 }
 public void OrderByQueryTokenDefaultTest()
 {
     var expression = new InnerPathToken(string.Empty, null, null);
     OrderByToken orderby = new OrderByToken(expression, OrderByDirection.Ascending);
     this.Assert.AreEqual(QueryTokenKind.OrderBy, orderby.Kind, "The InternalKind property has an unexpected value.");
     this.Assert.AreEqual(OrderByDirection.Ascending, orderby.Direction, "The Direction property should be Ascending.");
     this.Assert.AreEqual(expression, orderby.Expression, "The Expression property has an unexpected value.");
 }
        public void ParsedFunctionWithAParent()
        {
            var        tokenizer = GetFunctionCallParser("func()");
            var        parent    = new InnerPathToken("Customer", null, null);
            QueryToken result    = tokenizer.ParseIdentifierAsFunction(parent);

            result.ShouldBeFunctionCallToken("func").And.Source.Should().BeSameAs(parent);
        }
Example #5
0
        public void NamedValuesSetCorrectly()
        {
            InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });

            innerPathToken.NamedValues.Count().Should().Be(1);
            innerPathToken.NamedValues.ElementAt(0).Name.Should().Be("blah");
            innerPathToken.NamedValues.ElementAt(0).Value.ShouldBeLiteralQueryToken(1);
        }
        public void NamedValuesSetCorrectly()
        {
            InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });

            Assert.Single(innerPathToken.NamedValues);
            Assert.Equal("blah", innerPathToken.NamedValues.ElementAt(0).Name);
            innerPathToken.NamedValues.ElementAt(0).Value.ShouldBeLiteralQueryToken(1);
        }
        public static InnerPathToken ShouldBeInnerPathToken(this QueryToken token, string expectedName)
        {
            Assert.NotNull(token);
            InnerPathToken nonRootToken = Assert.IsType <InnerPathToken>(token);

            Assert.Equal(QueryTokenKind.InnerPath, nonRootToken.Kind);
            Assert.Equal(expectedName, nonRootToken.Identifier);
            return(nonRootToken);
        }
        public void PrimitiveCollectionPropertyShouldCreateMatchingNode()
        {
            var state = new BindingState(configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASingleDog, state);
            var token = new InnerPathToken("Nicknames", new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);
            result.ShouldBeCollectionPropertyAccessQueryNode(HardCodedTestModel.GetDogNicknamesProperty());
        }
Example #9
0
        public void OrderByQueryTokenDefaultTest()
        {
            var          expression = new InnerPathToken(string.Empty, null, null);
            OrderByToken orderby    = new OrderByToken(expression, OrderByDirection.Ascending);

            this.Assert.AreEqual(QueryTokenKind.OrderBy, orderby.Kind, "The InternalKind property has an unexpected value.");
            this.Assert.AreEqual(OrderByDirection.Ascending, orderby.Direction, "The Direction property should be Ascending.");
            this.Assert.AreEqual(expression, orderby.Expression, "The Expression property has an unexpected value.");
        }
        public void DeclaredPropertyOnOpenTypeShouldCreateMatchingNode()
        {
            var state = new BindingState(configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASinglePainting, state);
            var token = new InnerPathToken("Colors", new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);
            result.ShouldBeCollectionPropertyAccessQueryNode(HardCodedTestModel.GetPaintingColorsProperty());
        }
 public void ParsedFunctionWithAParentAndArgs()
 {
     var tokenizer = GetFunctionCallParser("func(x='blah')");
     var parent = new InnerPathToken("Customer", null, null);
     QueryToken result = tokenizer.ParseIdentifierAsFunction(parent);
     var functionCallToken = result.ShouldBeFunctionCallToken("func").And;
     functionCallToken.Source.Should().BeSameAs(parent);
     functionCallToken.Arguments.Should().HaveCount(1);
 }
        public void OpenPropertyShouldCreateMatchingNode()
        {
            const string OpenPropertyName = "Emotions";
            var state = new BindingState(configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASinglePainting, state);
            var token = new InnerPathToken(OpenPropertyName, new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);
            result.ShouldBeSingleValueOpenPropertyAccessQueryNode(OpenPropertyName);
        }
        public void ParsedFunctionWithAParent()
        {
            FunctionCallParser tokenizer = GetFunctionCallParser("func()");
            InnerPathToken     parent    = new InnerPathToken("Customer", null, null);
            QueryToken         result;
            bool success = tokenizer.TryParseIdentifierAsFunction(parent, out result);

            success.Should().BeTrue();
            result.ShouldBeFunctionCallToken("func").And.Source.Should().BeSameAs(parent);
        }
Example #14
0
        public void CollectionOfDateTimeOffsetShouldCreateMatchingNode()
        {
            var state  = new BindingState(Configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASingleLion, state);
            var token  = new InnerPathToken("AttackDates", new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);

            result.ShouldBeCollectionPropertyAccessQueryNode(HardCodedTestModel.GetLionAttackDatesProp());
        }
        public void ParsedFunctionWithAParentAndArgs()
        {
            var        tokenizer         = GetFunctionCallParser("func(x='blah')");
            var        parent            = new InnerPathToken("Customer", null, null);
            QueryToken result            = tokenizer.ParseIdentifierAsFunction(parent);
            var        functionCallToken = result.ShouldBeFunctionCallToken("func").And;

            functionCallToken.Source.Should().BeSameAs(parent);
            functionCallToken.Arguments.Should().HaveCount(1);
        }
Example #16
0
        public void DeclaredPropertyOnOpenTypeShouldCreateMatchingNode()
        {
            var state  = new BindingState(Configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASinglePainting, state);
            var token  = new InnerPathToken("Colors", new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);

            result.ShouldBeCollectionPropertyAccessQueryNode(HardCodedTestModel.GetPaintingColorsProperty());
        }
Example #17
0
        public void PrimitiveCollectionPropertyShouldCreateMatchingNode()
        {
            var state  = new BindingState(Configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASingleDog, state);
            var token  = new InnerPathToken("Nicknames", new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);

            result.ShouldBeCollectionPropertyAccessQueryNode(HardCodedTestModel.GetDogNicknamesProperty());
        }
Example #18
0
        public void ComplexCollectionPropertyShouldCreateMatchingNode()
        {
            var state  = new BindingState(Configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASinglePerson, state);
            var token  = new InnerPathToken("PreviousAddresses", new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);

            result.ShouldBeCollectionComplexNode(HardCodedTestModel.GetPersonPreviousAddressesProp());
        }
        public void CollectionNavigationPropertyShouldCreateMatchingNode()
        {
            var state = new BindingState(configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASingleDog, state);
            var token = new InnerPathToken("MyPeople", new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);
            result.ShouldBeCollectionNavigationNode(HardCodedTestModel.GetDogMyPeopleNavProp()).
                And.NavigationSource.Should().BeSameAs(HardCodedTestModel.GetDogsSet().FindNavigationTarget(HardCodedTestModel.GetDogMyPeopleNavProp()));
        }
Example #20
0
        public void CollectionNavigationPropertyShouldCreateMatchingNode()
        {
            var state  = new BindingState(Configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASingleDog, state);
            var token  = new InnerPathToken("MyPeople", new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);

            Assert.Same(HardCodedTestModel.GetDogsSet().FindNavigationTarget(HardCodedTestModel.GetDogMyPeopleNavProp()),
                        result.ShouldBeCollectionNavigationNode(HardCodedTestModel.GetDogMyPeopleNavProp()).NavigationSource);
        }
Example #21
0
        public void OpenPropertyShouldCreateMatchingNode()
        {
            const string OpenPropertyName = "Emotions";
            var          state            = new BindingState(Configuration);
            var          binder           = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASinglePainting, state);
            var          token            = new InnerPathToken(OpenPropertyName, new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);

            result.ShouldBeSingleValueOpenPropertyAccessQueryNode(OpenPropertyName);
        }
Example #22
0
        /// <summary>
        /// Write the navigation property token as URI part to this builder.
        /// </summary>
        /// <param name="navigation">To write as URI part.</param>
        private void WriteNavigationProperty(InnerPathToken navigation)
        {
            ExceptionUtils.CheckArgumentNotNull(navigation, "navigation");

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

            this.builder.Append(navigation.Identifier);
        }
Example #23
0
        public void ParsedFunctionWithAParentAndArgs()
        {
            FunctionCallParser tokenizer = GetFunctionCallParser("func(x='blah')");
            InnerPathToken     parent    = new InnerPathToken("Customer", null, null);
            QueryToken         result;
            bool success = tokenizer.TryParseIdentifierAsFunction(parent, out result);

            Assert.True(success);
            FunctionCallToken functionCallToken = result.ShouldBeFunctionCallToken("func");

            Assert.Same(parent, functionCallToken.Source);
            Assert.Single(functionCallToken.Arguments);
        }
Example #24
0
        public void KeyLookupOnNavPropIntegrationTest()
        {
            var state = new BindingState(Configuration);

            state.ImplicitRangeVariable = NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet());
            var metadataBinder = new MetadataBinder(state);
            var binder         = new InnerPathTokenBinder(metadataBinder.Bind, state);
            var token          = new InnerPathToken("MyPeople", null, new[] { new NamedValue(null, new LiteralToken(123)) });

            var result = binder.BindInnerPathSegment(token);

            result.ShouldBeKeyLookupQueryNode();
        }
Example #25
0
        public void InnerPathTokenBinderShouldFailIfPropertySourceIsNotASingleValue()
        {
            var state = new BindingState(Configuration);

            state.ImplicitRangeVariable = NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet());
            var metadataBinder = new MetadataBinder(state);
            var binder         = new InnerPathTokenBinder(metadataBinder.Bind, state);
            var token          = new InnerPathToken("MyDog", new InnerPathToken("MyPeople", null, null), null);

            Action bind = () => binder.BindInnerPathSegment(token);

            bind.Throws <ODataException>(Strings.MetadataBinder_PropertyAccessSourceNotSingleValue("MyDog"));
        }
        public void MissingPropertyShouldThrow()
        {
            const string MissingPropertyName = "ThisPropertyDoesNotExist";
            var state = new BindingState(configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASingleDog, state);
            var token = new InnerPathToken(MissingPropertyName, new DummyToken(), null /*namedValues*/);

            Action bind = () => binder.BindInnerPathSegment(token);

            string expectedMessage =
                ODataErrorStrings.MetadataBinder_PropertyNotDeclared(HardCodedTestModel.GetDogType().FullTypeName(), MissingPropertyName);
            bind.ShouldThrow<ODataException>(expectedMessage);
        }
        public void ParsedFunctionWithAParentAndArgs()
        {
            FunctionCallParser tokenizer = GetFunctionCallParser("func(x='blah')");
            InnerPathToken     parent    = new InnerPathToken("Customer", null, null);
            QueryToken         result;
            bool success = tokenizer.TryParseIdentifierAsFunction(parent, out result);

            success.Should().BeTrue();
            FunctionCallToken functionCallToken = result.ShouldBeFunctionCallToken("func").And;

            functionCallToken.Source.Should().BeSameAs(parent);
            functionCallToken.Arguments.Should().HaveCount(1);
        }
Example #28
0
        public void MissingPropertyShouldThrow()
        {
            const string MissingPropertyName = "ThisPropertyDoesNotExist";
            var          state  = new BindingState(Configuration);
            var          binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASingleDog, state);
            var          token  = new InnerPathToken(MissingPropertyName, new DummyToken(), null /*namedValues*/);

            Action bind = () => binder.BindInnerPathSegment(token);

            string expectedMessage =
                ODataErrorStrings.MetadataBinder_PropertyNotDeclared(HardCodedTestModel.GetDogType().FullTypeName(), MissingPropertyName);

            bind.Throws <ODataException>(expectedMessage);
        }
Example #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>
        /// <param name="state">Current state of binding.</param>
        /// <returns>A SingleValueQueryNode that is the parent node of the <paramref name="segmentToken"/>.</returns>
        private QueryNode DetermineParentNode(InnerPathToken segmentToken, BindingState state)
        {
            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));
            }
        }
Example #30
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
                });
            }
        }
Example #31
0
 public void ParentSetCorrectly()
 {
     InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });
     innerPathToken.NextToken.ShouldBeLiteralQueryToken(1);
 }
Example #32
0
 /// <summary>
 /// Visits a InnerPathToken
 /// </summary>
 /// <param name="tokenIn">The InnerPathToken to bind</param>
 /// <returns>A SingleValueNode or SingleEntityNode bound to this InnerPathToken</returns>
 public virtual T Visit(InnerPathToken tokenIn)
 {
     throw new NotImplementedException();
 }
        public void CollectionOfTimeOfDayShouldCreateMatchingNode()
        {
            var state = new BindingState(configuration);
            var binder = new InnerPathTokenBinder(FakeBindMethods.BindMethodReturningASinglePerson, state);
            var token = new InnerPathToken("MyTimeOfDays", new DummyToken(), null /*namedValues*/);

            var result = binder.BindInnerPathSegment(token);
            result.ShouldBeCollectionPropertyAccessQueryNode(HardCodedTestModel.GetPersonMyTimeOfDaysProp());
        }
Example #34
0
 /// <summary>
 /// Try to bind an inner path token as a function call. Used for bound functions without parameters
 /// that parse as inner path tokens syntactically
 /// </summary>
 /// <param name="innerPathToken">the end path token to bind</param>
 /// <param name="parent">the parent node to this end path token.</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 TryBindInnerPathAsFunctionCall(InnerPathToken innerPathToken, QueryNode parent, out QueryNode boundFunction)
 {
     return this.TryBindIdentifier(innerPathToken.Identifier, null, parent, state, out boundFunction);
 }
        public void InnerPathTokenBinderShouldFailIfPropertySourceIsNotASingleValue()
        {
            var state = new BindingState(configuration);
            state.ImplicitRangeVariable = NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet());
            var metadataBinder = new MetadataBinder(state);
            var binder = new InnerPathTokenBinder(metadataBinder.Bind, state);
            var token = new InnerPathToken("MyDog", new InnerPathToken("MyPeople", null, null), null);

            Action bind = () => binder.BindInnerPathSegment(token);
            bind.ShouldThrow<ODataException>().WithMessage(Strings.MetadataBinder_PropertyAccessSourceNotSingleValue("MyDog"));
        }
Example #36
0
 public void KindIsInnerPath()
 {
     InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });
     innerPathToken.Kind.Should().Be(QueryTokenKind.InnerPath);
 }
Example #37
0
        public void NameSetCorrectly()
        {
            InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });

            innerPathToken.Identifier.Should().Be("stuff");
        }
Example #38
0
        public void KindIsInnerPath()
        {
            InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });

            innerPathToken.Kind.Should().Be(QueryTokenKind.InnerPath);
        }
        /// <summary>
        /// Binds a <see cref="InnerPathToken"/>.
        /// This includes more than just navigations - it includes complex property access and primitive collections.
        /// </summary>
        /// <param name="segmentToken">The segment token to bind.</param>
        /// <returns>The bound node.</returns>
        internal QueryNode BindInnerPathSegment(InnerPathToken segmentToken)
        {
            FunctionCallBinder functionCallBinder = new FunctionCallBinder(this.bindMethod, state);

            // First we get the parent node
            QueryNode parent = this.DetermineParentNode(segmentToken, state);
            Debug.Assert(parent != null, "parent should never be null");

            SingleValueNode singleValueParent = parent as SingleValueNode;
            if (singleValueParent == null)
            {
                QueryNode boundFunction;
                if (functionCallBinder.TryBindInnerPathAsFunctionCall(segmentToken, parent, out boundFunction))
                {
                    return boundFunction;
                }

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

            // Using the parent and name of this token, we try to get the IEdmProperty it represents
            IEdmProperty property = BindProperty(singleValueParent.TypeReference, segmentToken.Identifier, this.Resolver);

            if (property == null)
            {
                QueryNode boundFunction;
                if (functionCallBinder.TryBindInnerPathAsFunctionCall(segmentToken, parent, out boundFunction))
                {
                    return boundFunction;
                }

                if (singleValueParent.TypeReference != null && !singleValueParent.TypeReference.Definition.IsOpenType())
                {
                    throw new ODataException(
                        ODataErrorStrings.MetadataBinder_PropertyNotDeclared(
                            parent.GetEdmTypeReference().FullName(), segmentToken.Identifier));
                }

                return new SingleValueOpenPropertyAccessNode(singleValueParent, segmentToken.Identifier);
            }

            if (property.Type.IsODataComplexTypeKind())
            {
                return new SingleValuePropertyAccessNode(singleValueParent, property);
            }

            // Note - this means nonentity collection (primitive or complex)
            if (property.Type.IsNonEntityCollectionType())
            {
                return new CollectionPropertyAccessNode(singleValueParent, property);
            }

            IEdmNavigationProperty navigationProperty = property as IEdmNavigationProperty;
            if (navigationProperty == null)
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_IllegalSegmentType(property.Name));
            }

            SingleEntityNode parentEntity = EnsureParentIsEntityForNavProp(singleValueParent);

            return GetNavigationNode(navigationProperty, parentEntity, segmentToken.NamedValues, state, new KeyBinder(this.bindMethod));
        }
        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
                };
            }
        }
Example #41
0
 /// <summary>
 /// Binds an InnerPathToken.
 /// </summary>
 /// <param name="token">Token to bind.</param>
 /// <returns>Either a SingleNavigationNode, CollectionNavigationNode, SinglePropertyAccessNode (complex), 
 /// or CollectionPropertyAccessNode (primitive or complex) that is the metadata-bound version of the given token.</returns>
 protected virtual QueryNode BindInnerPathSegment(InnerPathToken token)
 {
     InnerPathTokenBinder innerPathTokenBinder = new InnerPathTokenBinder(this.Bind, this.BindingState);
     return innerPathTokenBinder.BindInnerPathSegment(token);
 }
Example #42
0
 /// <summary>
 /// Try to bind an inner path token as a function call. Used for bound functions without parameters
 /// that parse as inner path tokens syntactically
 /// </summary>
 /// <param name="innerPathToken">the end path token to bind</param>
 /// <param name="parent">the parent node to this end path token.</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 TryBindInnerPathAsFunctionCall(InnerPathToken innerPathToken, QueryNode parent, out QueryNode boundFunction)
 {
     return(this.TryBindIdentifier(innerPathToken.Identifier, null, parent, state, out boundFunction));
 }
Example #43
0
 private static void VerifyNonRootSegmentQueryTokensAreEqual(InnerPathToken expected, InnerPathToken actual, AssertionHandler assert)
 {
     assert.AreEqual(expected.Identifier, actual.Identifier, "The Name of the navigation property token doesn't match the expected one.");
     VerifyQueryTokensAreEqual(expected.NextToken, actual.NextToken, assert);
 }
        public void KindIsInnerPath()
        {
            InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });

            Assert.Equal(QueryTokenKind.InnerPath, innerPathToken.Kind);
        }
Example #45
0
        /// <summary>
        /// Binds a <see cref="InnerPathToken"/>.
        /// This includes more than just navigations - it includes complex property access and primitive collections.
        /// </summary>
        /// <param name="segmentToken">The segment token to bind.</param>
        /// <returns>The bound node.</returns>
        internal QueryNode BindInnerPathSegment(InnerPathToken segmentToken)
        {
            FunctionCallBinder functionCallBinder = new FunctionCallBinder(this.bindMethod, state);

            // First we get the parent node
            QueryNode parent = this.DetermineParentNode(segmentToken, state);

            Debug.Assert(parent != null, "parent should never be null");

            SingleValueNode singleValueParent = parent as SingleValueNode;

            if (singleValueParent == null)
            {
                QueryNode boundFunction;
                if (functionCallBinder.TryBindInnerPathAsFunctionCall(segmentToken, parent, out boundFunction))
                {
                    return(boundFunction);
                }

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

            // Using the parent and name of this token, we try to get the IEdmProperty it represents
            IEdmProperty property = BindProperty(singleValueParent.TypeReference, segmentToken.Identifier, this.Resolver);

            if (property == null)
            {
                QueryNode boundFunction;
                if (functionCallBinder.TryBindInnerPathAsFunctionCall(segmentToken, parent, out boundFunction))
                {
                    return(boundFunction);
                }

                if (singleValueParent.TypeReference != null && !singleValueParent.TypeReference.Definition.IsOpenType())
                {
                    throw new ODataException(
                              ODataErrorStrings.MetadataBinder_PropertyNotDeclared(
                                  parent.GetEdmTypeReference().FullName(), segmentToken.Identifier));
                }

                return(new SingleValueOpenPropertyAccessNode(singleValueParent, segmentToken.Identifier));
            }

            if (property.Type.IsODataComplexTypeKind())
            {
                return(new SingleValuePropertyAccessNode(singleValueParent, property));
            }

            // Note - this means nonentity collection (primitive or complex)
            if (property.Type.IsNonEntityCollectionType())
            {
                return(new CollectionPropertyAccessNode(singleValueParent, property));
            }

            IEdmNavigationProperty navigationProperty = property as IEdmNavigationProperty;

            if (navigationProperty == null)
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_IllegalSegmentType(property.Name));
            }

            SingleEntityNode parentEntity = EnsureParentIsEntityForNavProp(singleValueParent);

            return(GetNavigationNode(navigationProperty, parentEntity, segmentToken.NamedValues, state, new KeyBinder(this.bindMethod)));
        }
Example #46
0
        public void ParentSetCorrectly()
        {
            InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });

            innerPathToken.NextToken.ShouldBeLiteralQueryToken(1);
        }
Example #47
0
 private static void VerifyNonRootSegmentQueryTokensAreEqual(InnerPathToken expected, InnerPathToken actual, AssertionHandler assert)
 {
     assert.AreEqual(expected.Identifier, actual.Identifier, "The Name of the navigation property token doesn't match the expected one.");
     VerifyQueryTokensAreEqual(expected.NextToken, actual.NextToken, assert);
 }
Example #48
0
 public void NameSetCorrectly()
 {
     InnerPathToken innerPathToken = new InnerPathToken("stuff", new LiteralToken(1), new NamedValue[] { new NamedValue("blah", new LiteralToken(1)) });
     innerPathToken.Identifier.Should().Be("stuff");
 }
 public Expression Visit(InnerPathToken tokenIn)
 {
     throw new NotImplementedException();
 }
        /// <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>
        /// <param name="state">Current state of binding.</param>
        /// <returns>A SingleValueQueryNode that is the parent node of the <paramref name="segmentToken"/>.</returns>
        private QueryNode DetermineParentNode(InnerPathToken segmentToken, BindingState state)
        {
            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);
            }
        }
        public void KeyLookupOnNavPropIntegrationTest()
        {
            var state = new BindingState(configuration);
            state.ImplicitRangeVariable = NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet());
            var metadataBinder = new MetadataBinder(state);
            var binder = new InnerPathTokenBinder(metadataBinder.Bind, state);
            var token = new InnerPathToken("MyPeople", null, new[] { new NamedValue(null, new LiteralToken(123)) });

            var result = binder.BindInnerPathSegment(token);
            result.ShouldBeKeyLookupQueryNode();
        }