private PomonaResponse ExecuteQueryable(PomonaContext context, IQueryable resultAsQueryable) { var queryableActionResult = resultAsQueryable as IQueryableActionResult; int?defaultPageSize = null; if (queryableActionResult != null && queryableActionResult.Projection != null) { defaultPageSize = queryableActionResult.DefaultPageSize; if (queryableActionResult.Projection != QueryProjection.AsEnumerable) { var entity = queryableActionResult.Execute(queryableActionResult.Projection); if (entity == null) { throw new ResourceNotFoundException("Resource not found."); } return(new PomonaResponse(entity, expandedPaths: context.ExpandedPaths)); } resultAsQueryable = queryableActionResult.WrappedQueryable; } var queryExecutor = GetInstance <IQueryExecutor>(); var pomonaQuery = ParseQuery(context, resultAsQueryable.ElementType, defaultPageSize); return(queryExecutor.ApplyAndExecute(resultAsQueryable, pomonaQuery)); }
private PomonaQuery ParseQuery(PomonaContext context, Type rootType, int?defaultPageSize = null) { var queryPropertyResolver = new QueryTypeResolver(TypeMapper); var queryExpressionParser = new QueryExpressionParser(queryPropertyResolver); var queryTransformer = new PomonaHttpQueryTransformer(TypeMapper, queryExpressionParser); var structuredType = (ResourceType)TypeMapper.FromType(rootType); return(queryTransformer.TransformRequest(context, structuredType, defaultPageSize)); }
internal static IQueryable Query(this IPomonaSession session, UrlSegment urlSegment) { if (session == null) throw new ArgumentNullException(nameof(session)); if (urlSegment == null) throw new ArgumentNullException(nameof(urlSegment)); var request = new PomonaContext(urlSegment, acceptType : typeof(IQueryable), handleException : false); return (IQueryable)session.Dispatch(request).Entity; }
internal static object Get(this IPomonaSession session, UrlSegment urlSegment) { if (session == null) throw new ArgumentNullException(nameof(session)); if (urlSegment == null) throw new ArgumentNullException(nameof(urlSegment)); var request = new PomonaContext(urlSegment, executeQueryable : true, handleException : false); return session.Dispatch(request).Entity; }
private PomonaResponse DispatchInternal(PomonaContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Session != this) { throw new ArgumentException("Request session is not same as this."); } var savedOuterContext = CurrentContext; try { CurrentContext = context; var result = Factory.Pipeline.Process(context); var resultEntity = result.Entity; var resultAsQueryable = resultEntity as IQueryable; if (resultAsQueryable != null && context.ExecuteQueryable) { result = ExecuteQueryable(context, resultAsQueryable); } if (context.AcceptType != null && !context.AcceptType.IsInstanceOfType(resultEntity)) { var route = context.Route; var resultType = route.ResultType; if (typeof(IQueryable).IsAssignableFrom(context.AcceptType) && route.IsSingle && resultType.Type.IsInstanceOfType(resultEntity)) { var array = Array.CreateInstance(resultType, 1); array.SetValue(resultEntity, 0); return(new PomonaResponse(array.AsQueryable())); } throw new InvalidOperationException("Result is not of accepted type."); } return(result); } finally { CurrentContext = savedOuterContext; } }
internal static IQueryable Query(this IPomonaSession session, UrlSegment urlSegment) { if (session == null) { throw new ArgumentNullException(nameof(session)); } if (urlSegment == null) { throw new ArgumentNullException(nameof(urlSegment)); } var request = new PomonaContext(urlSegment, acceptType: typeof(IQueryable), handleException: false); return((IQueryable)session.Dispatch(request).Entity); }
internal static object Get(this IPomonaSession session, UrlSegment urlSegment) { if (session == null) { throw new ArgumentNullException(nameof(session)); } if (urlSegment == null) { throw new ArgumentNullException(nameof(urlSegment)); } var request = new PomonaContext(urlSegment, executeQueryable: true, handleException: false); return(session.Dispatch(request).Entity); }
public virtual PomonaResponse Dispatch(PomonaContext context) { try { return(DispatchInternal(context)); } catch (Exception ex) { if (!context.HandleException) { throw; } var error = this.container.GetInstance <IPomonaErrorHandler>().HandleException(ex); if (error == null) { throw; } return(new PomonaResponse(error.Entity ?? PomonaResponse.NoBodyEntity, error.StatusCode, responseHeaders: error.ResponseHeaders)); } }
public IEnumerable <RouteAction> GetRouteActions(PomonaContext context) { var route = context.Node.Route; return(Factory.ActionResolver.Resolve(route, context.Method)); }
public PomonaQuery TransformRequest(PomonaContext context, StructuredType rootType, int? defaultTop = null) { if (context == null) throw new ArgumentNullException(nameof(context)); if (rootType == null) throw new ArgumentNullException(nameof(rootType)); StructuredType ofType = null; if (context.Query["$oftype"].HasValue) ofType = (StructuredType)this.typeMapper.FromType((string)context.Query["$oftype"]); var query = new PomonaQuery(rootType, ofType); if (context.Query["$debug"].HasValue) { query.DebugInfoKeys = new HashSet<string>(((string)context.Query["$debug"]).ToLower().Split(',').Select(x => x.Trim())); } string filter = null; var top = defaultTop ?? 100; var skip = 0; if (context.Query["$totalcount"].HasValue && ((string)context.Query["$totalcount"]).ToLower() == "true") query.IncludeTotalCount = true; if (context.Query["$top"].HasValue) top = int.Parse(context.Query["$top"]); if (context.Query["$skip"].HasValue) skip = int.Parse(context.Query["$skip"]); if (context.Query["$filter"].HasValue) filter = (string)context.Query["$filter"]; ParseFilterExpression(query, filter); var selectSourceType = query.OfType.Type; if (context.Query["$groupby"].HasValue) { var groupby = (string)context.Query["$groupby"]; ParseGroupByExpression(query, groupby); selectSourceType = typeof(IGrouping<,>).MakeGenericType( query.GroupByExpression.ReturnType, selectSourceType); } if (context.Query["$projection"].HasValue) { var projectionString = (string)context.Query["$projection"]; query.Projection = projectionMap[projectionString]; QueryProjection projection; if (!projectionMap.TryGetValue(projectionString, out projection)) { throw new QueryParseException("\"" + projectionString + "\" is not a valid value for query parameter $projection", null, QueryParseErrorReason.UnrecognizedProjection, null); } query.Projection = projection; } else { query.Projection = QueryProjection.AsEnumerable; } if (context.Query["$select"].HasValue) { var select = (string)context.Query["$select"]; ParseSelect(query, select, selectSourceType); } if (context.Query["$orderby"].HasValue) ParseOrderBy(query, (string)context.Query["$orderby"]); query.Top = top; query.Skip = skip; if (context.Query["$expand"].HasValue) { // TODO: Translate expanded paths using TypeMapper query.ExpandedPaths = ((string)context.Query["$expand"]); } else query.ExpandedPaths = string.Empty; query.Url = context.Url; UpdateResultType(query); return query; }
public PomonaQuery TransformRequest(PomonaContext context, StructuredType rootType, int?defaultTop = null) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (rootType == null) { throw new ArgumentNullException(nameof(rootType)); } StructuredType ofType = null; if (context.Query["$oftype"].HasValue) { ofType = (StructuredType)this.typeMapper.FromType((string)context.Query["$oftype"]); } var query = new PomonaQuery(rootType, ofType); if (context.Query["$debug"].HasValue) { query.DebugInfoKeys = new HashSet <string>(((string)context.Query["$debug"]).ToLower().Split(',').Select(x => x.Trim())); } string filter = null; var top = defaultTop ?? 100; var skip = 0; if (context.Query["$totalcount"].HasValue && ((string)context.Query["$totalcount"]).ToLower() == "true") { query.IncludeTotalCount = true; } if (context.Query["$top"].HasValue) { top = int.Parse(context.Query["$top"]); } if (context.Query["$skip"].HasValue) { skip = int.Parse(context.Query["$skip"]); } if (context.Query["$filter"].HasValue) { filter = (string)context.Query["$filter"]; } ParseFilterExpression(query, filter); var selectSourceType = query.OfType.Type; if (context.Query["$groupby"].HasValue) { var groupby = (string)context.Query["$groupby"]; ParseGroupByExpression(query, groupby); selectSourceType = typeof(IGrouping <,>).MakeGenericType( query.GroupByExpression.ReturnType, selectSourceType); } if (context.Query["$projection"].HasValue) { var projectionString = (string)context.Query["$projection"]; query.Projection = projectionMap[projectionString]; QueryProjection projection; if (!projectionMap.TryGetValue(projectionString, out projection)) { throw new QueryParseException("\"" + projectionString + "\" is not a valid value for query parameter $projection", null, QueryParseErrorReason.UnrecognizedProjection, null); } query.Projection = projection; } else { query.Projection = QueryProjection.AsEnumerable; } if (context.Query["$select"].HasValue) { var select = (string)context.Query["$select"]; ParseSelect(query, select, selectSourceType); } if (context.Query["$orderby"].HasValue) { ParseOrderBy(query, (string)context.Query["$orderby"]); } query.Top = top; query.Skip = skip; if (context.Query["$expand"].HasValue) { // TODO: Translate expanded paths using TypeMapper query.ExpandedPaths = ((string)context.Query["$expand"]); } else { query.ExpandedPaths = string.Empty; } query.Url = context.Url; UpdateResultType(query); return(query); }