Ejemplo n.º 1
0
        public void FilterBySpatialFunctionWithProperties()
        {
            var testCases = new[] {
                Tuple.Create("eq 1", 4),
                Tuple.Create("ne 2", 4),
                Tuple.Create("gt 2", 0),
            };

            foreach (var t in testCases)
            {
                this.serviceFactory.SetRequestUri("Entities?$filter=geo.distance(Point, geography'SRID=1234;POINT(20 10)') " + t.Item1);
                var service = this.serviceFactory.CreateService();

                RequestDescription d = RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

                Action <GeographyPoint> verifyPoint =
                    p =>
                {
                    Assert.AreEqual(20.0, p.Longitude);
                    Assert.AreEqual(10.0, p.Latitude);
                };

                RunSpatialDistanceFilterTest(d, null, verifyPoint, 1.0, t.Item2);
            }
        }
Ejemplo n.º 2
0
        private void RunSpatialExpressionTest(string queryOption, string queryOptionValue, Expression <Func <IQueryable <TestEntityType>, IQueryable <TestEntityType> > > expectedExpressionPattern)
        {
            this.serviceFactory.SetRequestUri("Entities?" + queryOption + "=" + queryOptionValue);
            var service = this.serviceFactory.CreateService();

            var d = RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

            var actualQueryableMethodExpression = (MethodCallExpression)d.RequestExpression;

            var expectedString = expectedExpressionPattern.ToString();
            var actualString   = actualQueryableMethodExpression.ToString();

            Console.WriteLine();
            Console.WriteLine("Expected: " + expectedString);
            Console.WriteLine("Actual: " + actualString);

            // get the portion of the expected string which represents the 'root'. it will look something like 'q => q.'
            var parameterString = expectedExpressionPattern.Parameters.Single().ToString();

            parameterString = parameterString + " => " + parameterString + ".";
            expectedString  = expectedString.Substring(parameterString.Length);

            // just verify that the .Where or .OrderBy call matches. We don't verify the root of the tree.
            Assert.IsTrue(actualString.EndsWith(expectedString));
        }
Ejemplo n.º 3
0
        public void FilterCompareSpatialLiterals()
        {
            var tests = new[]
            {
                new { Operator = "eq", ErrorName = "Equal" },
                new { Operator = "ne", ErrorName = "NotEqual" },
                new { Operator = "lt", ErrorName = "LessThan" },
                new { Operator = "gt", ErrorName = "GreaterThan" },
                new { Operator = "le", ErrorName = "LessThanOrEqual" },
                new { Operator = "ge", ErrorName = "GreaterThanOrEqual" }
            };

            this.serviceFactory.SetRequestUri("Entities");

            foreach (var test in tests)
            {
                // spatial literal vs spatial literal
                this.serviceFactory.SetRequestUri("Entities?$filter=geography'POINT(10 20)' " + test.Operator + " geography'SRID=1234;POINT(10 20)'");

                var service = this.serviceFactory.CreateService();

                Action processUri = () => RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);
                processUri.ShouldThrow <DataServiceException>().WithMessage(Microsoft.OData.Core.Strings.MetadataBinder_IncompatibleOperandsError("Edm.GeographyPoint", "Edm.GeographyPoint", test.ErrorName));
            }
        }
Ejemplo n.º 4
0
        public void FilterBySpatialFunctionWithLiterals()
        {
            Tuple <string, int>[] testCases = new Tuple <string, int>[] {
                Tuple.Create("eq 1", 4),
                Tuple.Create("ne 2", 4),
                Tuple.Create("gt 2", 0),
            };

            this.serviceFactory.SetRequestUri("Entities");
            string resourcePath = this.serviceFactory.RequestUri.OriginalString;

            foreach (var t in testCases)
            {
                this.serviceFactory.ClearQueryArgument();
                this.serviceFactory.AddQueryArgument("$filter", "geo.distance(geography'SRID=1234;POINT(20 10)', geography'SRID=1234;POINT(20 10)') " + t.Item1);
                this.serviceFactory.SetRequestUri(resourcePath + "?$filter=geo.distance(geography'SRID=1234;POINT(20 10)', geography'SRID=1234;POINT(20 10)') " + t.Item1);
                var service = this.serviceFactory.CreateService();

                RequestDescription d = RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

                Action <GeographyPoint> verifyPoint =
                    p =>
                {
                    Assert.AreEqual(20.0, p.Longitude);
                    Assert.AreEqual(10.0, p.Latitude);
                };

                RunSpatialDistanceFilterTest(d, verifyPoint, verifyPoint, 1.0, t.Item2);
            }
        }
Ejemplo n.º 5
0
        private void SetResourceReferenceToUrl(object entityResource, ResourceProperty navigationProperty, string url)
        {
            base.CheckAndIncrementObjectCount();
            RequestDescription description = RequestUriProcessor.ProcessRequestUri(RequestUriProcessor.GetAbsoluteUriFromReference(url, base.Service.OperationContext), base.Service, true);

            if ((this.ContentFormat == ContentFormat.Atom) && !description.IsSingleResult)
            {
                if ((navigationProperty != null) && (navigationProperty.Kind == ResourcePropertyKind.ResourceReference))
                {
                    throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_LinkHrefMustReferToSingleResource(navigationProperty.Name));
                }
            }
            else
            {
                object propertyValue = base.Service.GetResource(description, description.SegmentInfos.Length - 1, null);
                if (navigationProperty.Kind == ResourcePropertyKind.ResourceReference)
                {
                    base.Updatable.SetReference(entityResource, navigationProperty.Name, propertyValue);
                }
                else
                {
                    WebUtil.CheckResourceExists(propertyValue != null, description.LastSegmentInfo.Identifier);
                    base.Updatable.AddReferenceToCollection(entityResource, navigationProperty.Name, propertyValue);
                }
            }
        }
Ejemplo n.º 6
0
        public void QuerySpatialProperty()
        {
            this.serviceFactory.SetRequestUri("Entities(0)/Spatial");
            var service = this.serviceFactory.CreateService();

            RequestDescription d = RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

            Assert.AreEqual(RequestTargetKind.Primitive, d.LastSegmentInfo.TargetKind);
            Assert.AreEqual("Spatial", d.LastSegmentInfo.Identifier);
        }
Ejemplo n.º 7
0
        protected object GetTargetResourceToBind(Uri referencedUri, bool checkNull)
        {
            System.Data.Services.RequestDescription description = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service, true);
            object obj2 = this.Service.GetResource(description, description.SegmentInfos.Length - 1, null);

            if (checkNull)
            {
                WebUtil.CheckResourceExists(obj2 != null, description.LastSegmentInfo.Identifier);
            }
            return(obj2);
        }
Ejemplo n.º 8
0
        [Ignore] // Currently we have overloads of geog, geogPoint; etc. because EF forces us to use properties of type Geography rather than GeographyPoint.
        public void FilterBySpatialFunctionWrongType()
        {
            this.serviceFactory.SetRequestUri("Entities");

            this.serviceFactory.AddQueryArgument("$filter", "geo.distance(Spatial, SRID=1234;POINT(10 20)) lt 10");
            var service = this.serviceFactory.CreateService();

            Action test = () => RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);

            string expectedFunctions = "geo.distance(System.Data.Spatial.Geography.GeographyPoint, System.Data.Spatial.Geography.GeographyPoint)";

            test.ShouldThrow <DataServiceException>().WithMessage(Microsoft.OData.Service.Strings.RequestQueryParser_NoApplicableFunction(
                                                                      "geo.distance",
                                                                      expectedFunctions));
        }
Ejemplo n.º 9
0
        public void FilterSpatialMathOperators()
        {
            var tests = new[]
            {
                new { Operator = "add", ErrorName = "Add" },
                new { Operator = "mul", ErrorName = "Multiply" },
            };

            this.serviceFactory.SetRequestUri("Entities");

            foreach (var test in tests)
            {
                // property vs spatial literal
                this.serviceFactory.SetRequestUri("Entities?$filter=Spatial " + test.Operator + " geography'SRID=1234;POINT(10 20)'");
                var service = this.serviceFactory.CreateService();

                Action processUri = () => RequestUriProcessor.ProcessRequestUri(this.serviceFactory.RequestUri, service, false);
                processUri.ShouldThrow <DataServiceException>().WithMessage(Microsoft.OData.Core.Strings.MetadataBinder_IncompatibleOperandsError("Edm.Geography", "Edm.GeographyPoint", test.ErrorName));
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Sets a resource reference to resource referenced by a URL.
        /// </summary>
        /// <param name="entityResource">The entity resource to set the resource reference on.</param>
        /// <param name="navigationProperty">The navigation property for which to set the reference to null.</param>
        /// <param name="url">The URL which points to the resource to set as the value of the navigation property.</param>
        private void SetResourceReferenceToUrl(object entityResource, ResourceProperty navigationProperty, string url)
        {
            Debug.Assert(entityResource != null, "entityResource != null");
            Debug.Assert(navigationProperty != null, "navigationProperty != null");

            // Update the object count when you are performing a bind operation.
            this.CheckAndIncrementObjectCount();

            // Get the referenced resource.
            Uri referencedUri = RequestUriProcessor.GetAbsoluteUriFromReference(url, this.Service.OperationContext);
            RequestDescription requestDescription = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service, true /*internalQuery*/);

            // ATOM deserializer checks that the url doesn't point to a collection. If it does it will ignore the link.
            if (this.IsAtomRequest && !requestDescription.IsSingleResult)
            {
                if (navigationProperty != null &&
                    navigationProperty.Kind == ResourcePropertyKind.ResourceReference)
                {
                    throw DataServiceException.CreateBadRequestError(Microsoft.OData.Service.Strings.BadRequest_LinkHrefMustReferToSingleResource(navigationProperty.Name));
                }

                return;
            }

            // Get the resource
            object referencedResource = this.Service.GetResource(requestDescription, requestDescription.SegmentInfos.Count - 1, null);

            if (navigationProperty.Kind == ResourcePropertyKind.ResourceReference)
            {
                this.Updatable.SetReference(entityResource, navigationProperty.Name, referencedResource);
            }
            else
            {
                Debug.Assert(navigationProperty.Kind == ResourcePropertyKind.ResourceSetReference, "Only navigation properties are allowed in this method.");

                // If we are to set the resource to a collection property it must not be null (so check for nulls), otherwise do allow nulls for backward compatibility.
                WebUtil.CheckResourceExists(referencedResource != null, requestDescription.LastSegmentInfo.Identifier);
                this.Updatable.AddReferenceToCollection(entityResource, navigationProperty.Name, referencedResource);
            }
        }
Ejemplo n.º 11
0
        /// <summary>Applies the information from a link to the specified resource.</summary>
        /// <param name='link'>LinkDescriptor with information to apply.</param>
        /// <param name="resourceSet">Set for the target resource.</param>
        /// <param name='resourceType'>Type for the target resource.</param>
        /// <param name='resource'>Target resource to which information will be applied.</param>
        /// <param name="propertyName">Name of the property that this link represents.</param>
        private void ApplyLink(SyndicationLink link, ResourceSetWrapper resourceSet, ResourceType resourceType, object resource, string propertyName)
        {
            Debug.Assert(link != null, "link != null");
            Debug.Assert(resourceType != null, "resourceType != null");
            Debug.Assert(resource != null, "resource != null");

            ResourceProperty property = resourceType.TryResolvePropertyName(propertyName);

            if (property == null)
            {
                // Open navigation properties are not supported on OpenTypes
                throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(propertyName));
            }

            if (property.TypeKind != ResourceTypeKind.EntityType)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidNavigationPropertyName(propertyName, resourceType.FullName));
            }

            string      typeParameterValue = ValidateTypeParameterForNonOpenTypeProperties(link.MediaType, property);
            LinkContent linkContent        = this.HandleLinkContent(link, resource, resourceSet, resourceType, property, typeParameterValue, propertyName);

            #region Handle bind/unbind operation
            // If the href was specified empty or an empty inline element was specified, then we will set the
            // reference to null - this helps in overrriding if there was a default non-value for this property
            // else if only link element was specified, and then href points to a single result, then we will
            // perform a bind operation
            if ((linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && String.IsNullOrEmpty(link.Uri.OriginalString)) ||
                linkContent == LinkContent.EmptyInlineElementSpecified)
            {
                // update the object count when you are performing a bind operation
                this.CheckAndIncrementObjectCount();
                if (property != null && property.Kind == ResourcePropertyKind.ResourceSetReference)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequest_CannotSetCollectionsToNull(propertyName));
                }

                // For open properties, we will assume that this is a reference property and set it to null
                this.Updatable.SetReference(resource, propertyName, null);
            }
            else if (linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && !String.IsNullOrEmpty(link.Uri.OriginalString))
            {
                // update the object count when you are performing a bind operation
                this.CheckAndIncrementObjectCount();

                // If the link points to a reference navigation property, then update the link
                Uri referencedUri = RequestUriProcessor.GetAbsoluteUriFromReference(link.Uri.OriginalString, this.Service.OperationContext);
                RequestDescription description = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service);
                if (!description.IsSingleResult)
                {
                    if (property != null && property.Kind == ResourcePropertyKind.ResourceReference)
                    {
                        throw DataServiceException.CreateBadRequestError(Strings.BadRequest_LinkHrefMustReferToSingleResource(propertyName));
                    }

                    return;
                }

                // no need to check for null. For collection properties, they can never be null and that
                // check has been added below. For reference properties, if they are null, it means unbind
                // and hence no need to check for null.
                // Get the resource
                object targetResource = this.Service.GetResource(description, description.SegmentInfos.Length - 1, null);
                if (property.Kind == ResourcePropertyKind.ResourceReference)
                {
                    this.Updatable.SetReference(resource, propertyName, targetResource);
                }
                else
                {
                    WebUtil.CheckResourceExists(targetResource != null, description.LastSegmentInfo.Identifier);
                    this.Updatable.AddReferenceToCollection(resource, propertyName, targetResource);
                }
            }
            #endregion Handle bind/unbind operation
        }