/// <summary> /// Initializes a new instance of the <see cref="ODataQueryOptions"/> class based on the incoming request and some metadata information from /// the <see cref="ODataQueryContext"/>. /// </summary> /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information</param> /// <param name="request">The incoming request message</param> public ODataQueryOptions(ODataQueryContext context, HttpRequestMessage request) { if (context == null) { throw Error.ArgumentNull("context"); } if (request == null) { throw Error.ArgumentNull("request"); } // remember the context Context = context; // Parse the query from request Uri RawValues = new ODataRawQueryOptions(); IEnumerable<KeyValuePair<string, string>> queryParameters = request.GetQueryNameValuePairs(); foreach (KeyValuePair<string, string> kvp in queryParameters) { switch (kvp.Key) { case "$filter": RawValues.Filter = kvp.Value; ThrowIfEmpty(kvp.Value, "$filter"); Filter = new FilterQueryOption(kvp.Value, context); break; case "$orderby": RawValues.OrderBy = kvp.Value; ThrowIfEmpty(kvp.Value, "$orderby"); OrderBy = new OrderByQueryOption(kvp.Value, context); break; case "$top": RawValues.Top = kvp.Value; ThrowIfEmpty(kvp.Value, "$top"); Top = new TopQueryOption(kvp.Value, context); break; case "$skip": RawValues.Skip = kvp.Value; ThrowIfEmpty(kvp.Value, "$skip"); Skip = new SkipQueryOption(kvp.Value, context); break; case "$select": RawValues.Select = kvp.Value; break; case "$inlinecount": RawValues.InlineCount = kvp.Value; break; case "$expand": RawValues.Expand = kvp.Value; break; case "$skiptoken": RawValues.SkipToken = kvp.Value; break; default: // we don't throw if we can't recognize the query break; } } }
public void Value_Returns_ParsedSkipValue(string skipValue, int expectedValue) { var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var context = new ODataQueryContext(model, typeof(Customer)); var skip = new SkipQueryOption(skipValue, context); Assert.Equal(expectedValue, skip.Value); }
public void CanConstructValidFilterQuery(string skipValue) { var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var context = new ODataQueryContext(model, typeof(Customer)); var skip = new SkipQueryOption(skipValue, context); Assert.Same(context, skip.Context); Assert.Equal(skipValue, skip.RawValue); }
public void ApplyInValidSkipQueryThrows(string skipValue) { var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var context = new ODataQueryContext(model, typeof(Customer)); var skip = new SkipQueryOption(skipValue, context); Assert.Throws<ODataException>(() => skip.ApplyTo(ODataQueryOptionTest.Customers)); }
private static IQuery Apply(this IQuery query, SkipQueryOption skipQuery) { if (skipQuery != null) { query = query.SetFirstResult(skipQuery.Value); } return query; }
public void ApplyTo_WithUnTypedContext_Throws_InvalidOperation() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); ODataQueryContext context = new ODataQueryContext(model.Model, model.Customer); SkipQueryOption skip = new SkipQueryOption("42", context); IQueryable queryable = new Mock<IQueryable>().Object; // Act & Assert Assert.Throws<NotSupportedException>(() => skip.ApplyTo(queryable, new ODataQuerySettings()), "The query option is not bound to any CLR type. 'ApplyTo' is only supported with a query option bound to a CLR type."); }
public static HttpRequestMessage BuildCustomRequest(this ODataQueryOptions originalOptions, out TopQueryOption top, out SkipQueryOption skip, out OrderByQueryOption orderBy) { top = null; skip = null; orderBy = null; // cuttin out $top and $skip from the request HttpRequestMessage customRequest = originalOptions.Request; if (customRequest.Properties.ContainsKey(HttpPropertyKeys.RequestQueryNameValuePairsKey)) { Uri uri = originalOptions.Request.RequestUri; var pairs = customRequest.Properties[HttpPropertyKeys.RequestQueryNameValuePairsKey] as IEnumerable<KeyValuePair<string, string>>; if (pairs != null) { IEnumerable<KeyValuePair<string, string>> jQueryNameValuePairs = new FormDataCollection(uri).GetJQueryNameValuePairs(); var updatedPairs = new List<KeyValuePair<string, string>>(); foreach (var pair in jQueryNameValuePairs) { if (pair.Key.Equals("$top")) { top = originalOptions.Top; } else if (pair.Key.Equals("$skip")) { skip = originalOptions.Skip; } else if (pair.Key.Equals("$orderby")) { orderBy = originalOptions.OrderBy; } else { updatedPairs.Add(pair); } } customRequest.Properties.Remove(HttpPropertyKeys.RequestQueryNameValuePairsKey); customRequest.Properties.Add(HttpPropertyKeys.RequestQueryNameValuePairsKey, updatedPairs); } } return customRequest; }
public void CanApplySkip() { var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel(); var skipOption = new SkipQueryOption("1", new ODataQueryContext(model, typeof(Customer), "Customers")); var customers = (new List<Customer>{ new Customer { CustomerId = 1, Name = "Andy" }, new Customer { CustomerId = 2, Name = "Aaron" }, new Customer { CustomerId = 3, Name = "Alex" } }).AsQueryable(); var results = skipOption.ApplyTo(customers).ToArray(); Assert.Equal(2, results.Length); Assert.Equal(2, results[0].CustomerId); Assert.Equal(3, results[1].CustomerId); }
/// <summary> /// Validates a <see cref="SkipQueryOption" />. /// </summary> /// <param name="skipQueryOption">The $skip query.</param> /// <param name="validationSettings">The validation settings.</param> public virtual void Validate(SkipQueryOption skipQueryOption, ODataValidationSettings validationSettings) { if (skipQueryOption == null) { throw Error.ArgumentNull("skipQueryOption"); } if (validationSettings == null) { throw Error.ArgumentNull("validationSettings"); } if (skipQueryOption.Value > validationSettings.MaxSkip) { throw new ODataException(Error.Format(SRResources.SkipTopLimitExceeded, validationSettings.MaxSkip, AllowedQueryOptions.Skip, skipQueryOption.Value)); } }
public void CanApplySkipOrderby() { var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel(); var context = new ODataQueryContext(model, typeof(Customer)); var orderbyOption = new OrderByQueryOption("Name", context, queryTranslator: null); var skipOption = new SkipQueryOption("1", context); var customers = (new List<Customer>{ new Customer { CustomerId = 1, Name = "Andy" }, new Customer { CustomerId = 2, Name = "Aaron" }, new Customer { CustomerId = 3, Name = "Alex" } }).AsQueryable(); IQueryable queryable = orderbyOption.ApplyTo(customers); queryable = skipOption.ApplyTo(queryable, new ODataQuerySettings()); var results = ((IQueryable<Customer>)queryable).ToArray(); Assert.Equal(2, results.Length); Assert.Equal(3, results[0].CustomerId); Assert.Equal(1, results[1].CustomerId); }
public void CanApplySkipTopOrderby() { var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetServiceModel(); var context = new ODataQueryContext(model, typeof(Customer)) { RequestContainer = new MockContainer() }; var orderbyOption = new OrderByQueryOption("Name", context); var skipOption = new SkipQueryOption("2", context); var topOption = new TopQueryOption("2", context); var customers = (new List <Customer> { new Customer { CustomerId = 1, Name = "Andy" }, new Customer { CustomerId = 2, Name = "Aaron" }, new Customer { CustomerId = 3, Name = "Alex" }, new Customer { CustomerId = 4, Name = "Ace" }, new Customer { CustomerId = 5, Name = "Abner" } }).AsQueryable(); IQueryable queryable = orderbyOption.ApplyTo(customers); queryable = skipOption.ApplyTo(queryable, new ODataQuerySettings()); queryable = topOption.ApplyTo(queryable, new ODataQuerySettings()); var results = ((IQueryable <Customer>)queryable).ToArray(); Assert.Equal(2, results.Length); Assert.Equal(4, results[0].CustomerId); Assert.Equal(3, results[1].CustomerId); }
public void CanApplySkip() { var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var skipOption = new SkipQueryOption("1", new ODataQueryContext(model, typeof(Customer))); var customers = (new List <Customer> { new Customer { Id = 1, Name = "Andy" }, new Customer { Id = 2, Name = "Aaron" }, new Customer { Id = 3, Name = "Alex" } }).AsQueryable(); var results = skipOption.ApplyTo(customers, new ODataQuerySettings()).ToArray(); Assert.Equal(2, results.Length); Assert.Equal(2, results[0].Id); Assert.Equal(3, results[1].Id); }
/// <summary> /// Updates the QueryExpression's paging settings based on OData parameters. /// </summary> /// <param name="pagingInfo">The target PagingInfo</param> /// <param name="skip">The OData options that describe how many records to skip.</param> /// <param name="top">The OData options that describe how many records per page.</param> private static void UpdatePagingFromSkipAndTop(PagingInfo pagingInfo, SkipQueryOption skip, TopQueryOption top) { if (top == null) { pagingInfo.Count = 50; } else { pagingInfo.Count = top.Value; } if (skip == null) { pagingInfo.PageNumber = 1; } else { // When syncing for offline, the client will always request a page immediately after // the last record. So if there are only 7 records, it will request with $top=50 and // $skip=7. To handle these cases when $skip is not evenly divisible by $top, we round // up, which will send back an empty result set on the last page and complete the sync. pagingInfo.PageNumber = (int)Math.Ceiling((double)skip.Value / pagingInfo.Count) + 1; } }
public void Property_Value_WorksWithUnTypedContext() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); ODataQueryContext context = new ODataQueryContext(model.Model, model.Customer); SkipQueryOption skip = new SkipQueryOption("42", context); // Act & Assert Assert.Equal(42, skip.Value); }
public void Value_ThrowsODataException_ForInvalidValues(string skipValue) { var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var context = new ODataQueryContext(model, typeof(Customer)); var skip = new SkipQueryOption(skipValue, context); Assert.Throws<ODataException>(() => skip.Value); }
private Task <IEnumerable <PackageName> > Query(FeedPrincipal principal, string packageNamePrefix, SkipQueryOption skip, TopQueryOption top) { var feed = storage.GetFeed(principal.FeedName); switch (principal.AuthenticatedArea) { case AuthenticatedArea.QueryingOwn: return(skip != null && top != null ? feed.QueryPackages(principal.Identity.Name, principal.PackageState, packageNamePrefix, skip.Value, top.Value) : feed.QueryPackages(principal.Identity.Name, principal.PackageState)); case AuthenticatedArea.QueryingAll: return(skip != null && top != null ? feed.QueryPackages(principal.PackageState, packageNamePrefix, skip.Value, top.Value) : feed.QueryPackages(principal.PackageState)); default: throw new ArgumentOutOfRangeException("area", principal.AuthenticatedArea, null); } }
public void CanTurnOffValidationForSkip() { // Arrange ODataValidationSettings settings = new ODataValidationSettings() { MaxSkip = 10 }; SkipQueryOption option = new SkipQueryOption("11", ValidationTestHelper.CreateCustomerContext()); // Act and Assert Assert.Throws<ODataException>(() => option.Validate(settings), "The limit of '10' for Skip query has been exceeded. The value from the incoming request is '11'."); option.Validator = null; Assert.DoesNotThrow(() => option.Validate(settings)); }
/// <summary> /// Builds the order clause that skips and takes a number of elements. /// </summary> /// <param name="orderByQueryOption">The order by query option.</param> /// <param name="topQueryOption">The top query option.</param> /// <param name="skipQueryOption">The skip query option.</param> /// <returns> /// Returns sorted and filtered order clause. /// </returns> private string BuildOrderClause(OrderByQueryOption orderByQueryOption, TopQueryOption topQueryOption, SkipQueryOption skipQueryOption) { string orderClause = BuildOrderClause(orderByQueryOption); string skipTopClause = BuildSkipTopClause(topQueryOption, skipQueryOption); if (string.IsNullOrEmpty(skipTopClause)) { return(orderClause); } return($"{orderClause} {skipTopClause}"); }
public static IAsyncEnumerable <T> ApplyTo <T>(this SkipQueryOption query, IAsyncEnumerable <T> source, ODataQuerySettings settings) { return(source.SkipAsync(query.Value)); }