/// <summary> /// Method for checking login credentials of user. /// </summary> /// <param name="loginDto">loginDto contains login detail of a new user trying to log in.</param> /// <returns>ResponseModel associated to login status of a user.</returns> public ResponseModel Login(LoginDto loginDto) { using (var unitOfWork = new UnitOfWork()) { var userList = unitOfWork.Users.FindOnConstraint(QueryExpressions.UserHandle(loginDto), prop => prop.UserPasswords).ToList(); if (!userList.Count.Equals(0)) { var userInfo = userList[0]; if (!userInfo.IsVerified) { return(ReturnStatements.FailedLogin(StatusMessages.UserNotVerified, StatusCodes.Unauthorized)); } var userPassword = userInfo.UserPasswords.Where(QueryExpressions.UserPassword(loginDto, userInfo.Id)).ToList()[0]; if (userPassword != null) { return(ReturnStatements.SuccessLogin(userInfo.Id)); } } return(ReturnStatements.FailedLogin(StatusMessages.LoginFailed, StatusCodes.Unauthorized)); } }
public void QueryResultsMatch(params string[] input) { var methodChainingQuery = ExtensionMethods.QueryWithoutExtensionMethods(input); var queryExpressionQuery = QueryExpressions.CreateQuery(input); Assert.AreEqual(methodChainingQuery, queryExpressionQuery, "Query results should match."); }
private static string GetQuery(QueryExpressions expressions, Dictionary <string, object> queryParameters) { var queryBuilder = new StringBuilder("SELECT * FROM root r"); if (expressions.WhereExpressions?.Any() == true) { queryBuilder.Append(" WHERE "); queryBuilder.Append( QueryWhereClauseVisitor.Visit(expressions.WhereExpressions.First(), queryParameters)); foreach (var whereExpression in expressions.WhereExpressions.Skip(1)) { queryBuilder.Append(" AND ") .Append(QueryWhereClauseVisitor.Visit(whereExpression, queryParameters)); } } if (expressions.GroupByExpression != null) { queryBuilder.Append(" ORDER BY "); queryBuilder.Append( QueryOrderByClauseVisitor.Visit(expressions.GroupByExpression)); } return(queryBuilder.ToString()); }
public void JoinTest() { QueryExpressions.InnerJoinWithJoin(new AdventureWorks()); QueryExpressions.InnerJoinWithSelect(new AdventureWorks()); QueryExpressions.InnerJoinWithSelectMany(new AdventureWorks()); QueryExpressions.InnerJoinWithSelectAndRelationship(new AdventureWorks()); QueryExpressions.InnerJoinWithSelectManyAndRelationship(new AdventureWorks()); QueryExpressions.LeftOuterJoinWithSelectMany(new AdventureWorks()); }
private static string GetShouldStartNewAggregateFunction(QueryExpressions expressions) { if (expressions.GroupByExpression == null) { return("return false;"); } return("return " + ShouldStartNewAggregateVisitor.Visit(expressions.GroupByExpression) + ";"); }
private static string GetCreateResultFunction(QueryExpressions expressions) { if (expressions.CreateResultExpression == null) { return("return aggregate;"); } return("return " + CreateResultVisitor.Visit(expressions.CreateResultExpression) + ";"); }
private static string GetCreateAggregateSeedFunction(QueryExpressions expressions) { if (expressions.CreateAggregateSeedExpression == null) { return("return first;"); } return("return " + CreateAggregateSeedVisitor.Visit(expressions.CreateAggregateSeedExpression) + ";"); }
/// <summary> /// Gets sub-expressions from the overall expression based on the extension method they were passed in to. /// </summary> /// <param name="expression">The overall expression created by all calls to extension methods on an /// <see cref="IAggregateQueryable{T}"/> object.</param> /// <returns>A <see cref="QueryExpressions"/> object containing expressions identified by which extension /// method they were passed in to.</returns> private static QueryExpressions GetQueryExpressions(Expression expression) { var expressions = new QueryExpressions(); while (expression.NodeType == ExpressionType.Call) { var callExpression = (MethodCallExpression)expression; if (callExpression.Method.DeclaringType != typeof(AggregateQueryableExtensions)) { throw new NotImplementedException(); } switch (callExpression.Method.Name) { case nameof(AggregateQueryableExtensions.Where): expressions.AddWhereExpression(Unquote(callExpression.Arguments[1])); break; case nameof(AggregateQueryableExtensions.GroupBy): expressions.AddGroupByExpression(Unquote(callExpression.Arguments[1])); break; case nameof(AggregateQueryableExtensions.Aggregate) when(callExpression.Arguments.Count == 2): expressions.AddCreateAggregateExpression(Unquote(callExpression.Arguments[1])); break; case nameof(AggregateQueryableExtensions.Aggregate) when(callExpression.Arguments.Count == 3): expressions.AddCreateAggregateSeedExpression(Unquote(callExpression.Arguments[1])); expressions.AddCreateAggregateExpression(Unquote(callExpression.Arguments[2])); break; case nameof(AggregateQueryableExtensions.Select): expressions.AddCreateResultExpression(Unquote(callExpression.Arguments[1])); break; default: throw new NotImplementedException(); } expression = callExpression.Arguments[0]; } Debug.Assert(expression.NodeType == ExpressionType.Constant, "The initial expression should be a constant containing an IAggregateDocumentQuery<T> instance."); Debug.Assert(expression.Type.IsGenericType, "The initial expression should be a constant containing an IAggregateDocumentQuery<T> instance."); Debug.Assert(expression.Type.GetInterfaces() .Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IAggregateDocumentQuery <>)), "The initial expression should be a constant containing an IAggregateDocumentQuery<T> instance."); return(expressions); }
/// <summary> /// Method to get insurance from database based on user query. /// </summary> /// <param name="insuranceQuery">insuranceQuery contains query parameters to get insurances.</param> /// <returns>ResponseModel containing list of InsuranceDto.</returns> public ResponseModel Get(InsuranceQuery insuranceQuery) { using (var unitOfWork = new UnitOfWork()) { //Creating a parameter less query model if it is null from request if (insuranceQuery == null) { insuranceQuery = new InsuranceQuery(id: CommonString.OptionalStringParamInteger, name: CommonString.OptionalStringParam, phoneNumber: CommonString.OptionalStringParam, pubId: CommonString.OptionalStringParam); } insuranceQuery.SetTypedVariables(); var result = unitOfWork.Insurances.FindAll(QueryExpressions.Insurance(insuranceQuery)); result = result.OrderByDescending(m => m.Id).ToList(); return(ReturnStatements.SuccessResponse(CollectionConversions.ListInsurance(result))); } }
/// <summary> /// Method to get patient insurance from database based on user query. /// </summary> /// <param name="patientInsuranceQuery">patientInsuranceQuery containing query to get PatientInsuranceDto from database</param> /// <returns>ResponseModel containing list of PatientInsuranceDto</returns> public ResponseModel Get(PatientInsuranceQuery patientInsuranceQuery) { using (var unitOfWork = new UnitOfWork()) { //Creating a parameter less query model if it is null from request if (patientInsuranceQuery == null) { patientInsuranceQuery = new PatientInsuranceQuery(patientId: CommonString.OptionalStringParamInteger, insuranceId: CommonString.OptionalStringParamInteger); } patientInsuranceQuery.SetTypedVariables(); var result = unitOfWork.PatientInsurances.FindOnConstraint(QueryExpressions.PatientInsurance(patientInsuranceQuery), prop => prop.Insurance, prop => prop.Patient).ToList(); result = result.OrderByDescending(m => m.Id).ToList(); return(ReturnStatements.SuccessResponse(CollectionConversions.ListPatientInsuranceToDto(ConvertPatientInsuranceToPairList(result)))); } }
private LambdaExpression[] GetMapExpressions(QueryExpressions queryExpressions) { if (queryExpressions.LetClause != null && queryExpressions.Projection != null) { return new LambdaExpression[] { queryExpressions.LetClause, queryExpressions.Projection } } ; else if (queryExpressions.LetClause != null) { return new LambdaExpression[] { queryExpressions.LetClause } } ; else if (queryExpressions.Projection != null) { return new LambdaExpression[] { queryExpressions.Projection } } ; return(new LambdaExpression[] { }); }
public async Task <ActionResult> GetArtefacts( [FromQuery] string id, [FromQuery] string user, [FromQuery] string[] q, // query by string [FromQuery] bool?includeDesc, [FromQuery] Visibility[] vis, // eg. ...&vis=public,private&... [FromQuery] string[] category, [FromQuery] bool?matchAll, [FromQuery] DateTime since, [FromQuery] DateTime until, [FromQuery] string sort) { // Iterate through query params, adding lambdas of type // 'System.Linq.Expression'. // // Their conjunction is applied ie. 'artefact.Where(conj)' // // Similar expressions are built for calls to '.OrderBy'. IQueryable <Artefact> artefacts = _context.Artefacts .Include(a => a.CategoryJoin) .ThenInclude(cj => cj.Category) .Include(a => a.Owner) .Include(a => a.Images) .Include(a => a.Comments); ApplicationUser curUser = await _userService.GetCurUser(HttpContext); // if querying for a single artefact, simply return that artefact if (id != null) { var artefact = await artefacts .SingleOrDefaultAsync(a => a.Id == id); if (artefact == null) { return(NotFound()); } // check auth if (Queries.QueryIsAuthorised( artefact.Visibility, curUser, artefact.Owner, (curUser, queryUser) => curUser.Id == queryUser.Id, (curUser, queryUser) => true // just one big happy family )) { return(new JsonResult(_artefactConverter.ToJson(artefact))); } } /// Build dynamic linq queries using expression trees. See - /// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/expression-trees/how-to-use-expression-trees-to-build-dynamic-queries ParameterExpression artefactParam = Expression.Parameter(typeof(Artefact), "artefact"); IList <Expression> whereLambdas = new List <Expression>(); IList <Expression> orderByLambdas = new List <Expression>(); // first initialise queryUser - check for NotFound ApplicationUser queryUser = null; // query 'user' if (user != null) { // this throws if 'user == null' queryUser = await _userManager.FindByNameAsync(user); if (queryUser == null) { return(NotFound("'user' does not exist.")); } } if (vis != null && vis.Length > 0) { if (vis.Any(visQuery => !Queries.QueryIsAuthorised( visQuery, curUser, queryUser, (curUser, queryUser) => curUser.Id == queryUser.Id, (curUser, queryUser) => true // just one big happy family ))) { return(Unauthorized()); } else { var visLambdas = new List <Expression>( Enum.GetValues(typeof(Visibility)).Length ); foreach (Visibility visQuery in vis) { visLambdas.Add( QueryExpressions.ArtefactVisQueryExpression(visQuery, artefactParam) ); } // OR visibilities since artefact can belong to any of the // queried visibilities whereLambdas.Add( QueryExpressions.FoldBoolLambdas( Expression.Constant(false), visLambdas, (lamb1, lamb2) => Expression.OrElse(lamb1, lamb2)) ); } } else { // no vis query has been specified, so just return public // artefacts and consider other queries whereLambdas.Add( QueryExpressions.ArtefactVisQueryExpression( Visibility.Public, artefactParam) ); } // user query // Visibility filter should already have been authorised and added // to 'whereLambdas'. // // If no 'vis' query was specified, just returns public artefacts // of user. if (user != null) { if (vis == null) { whereLambdas.Add( QueryExpressions.ArtefactVisQueryExpression( Visibility.Public, artefactParam) ); } whereLambdas.Add( QueryExpressions.ArtefactUserQueryExpression(queryUser.Id, artefactParam) ); } else { // no user was specified and vis. authorisation has already // been applied - so just filter to see only public whereLambdas.Add( QueryExpressions.ArtefactVisQueryExpression( Visibility.Public, artefactParam) ); } // query string query if (q != null && q.Length > 0) { try { for (int i = 0; i < q.Length; i++) { ProcessQuery(q[i]); } } catch (Exception e) { if (e is QueryException) { return(BadRequest("Badly formatted query 'q'")); } else if (e is ArgumentException) { return(BadRequest("Badly formatted query 'q'")); } else { throw; } } void ProcessQuery(string query) { var(queryText, queryProperty) = SplitQuery(query); if (!IsValidQueryProperty(queryProperty)) { throw new QueryException { IsQuery = true }; } var propertyName = ApiQueryPropertyToPropertyName(queryProperty); whereLambdas.Add( QueryExpressions.ArtefactStrQueryExpression( queryText, propertyName, artefactParam ) ); bool IsValidQueryProperty(string queryProperty) { return((queryProperty != null) || (queryProperty == "title") || (queryProperty == "description")); } string ApiQueryPropertyToPropertyName(string apiQueryProperty) { if (apiQueryProperty == "title") { return("Title"); } else if (apiQueryProperty == "description") { return("Description"); } else { throw new ArgumentException(); } } } // (queryText, queryProperty) (string, string) SplitQuery(string query) { var split = query.Split(':'); var queryText = split[0]; string queryProperty; // Artefact property to be queried if (split.Length > 1) { queryProperty = split[1]; } else { queryProperty = null; } return(queryText, queryProperty); } } // categories query if (category != null && category.Length > 0) { var categoryLambdas = category .Select(cat => QueryExpressions.CategoryQueryExpression(cat, artefactParam)); Expression categoryLambdasJoined; // if matchAll, artefact must belong to every category in query // 'category' if (matchAll.HasValue && matchAll.Value) { categoryLambdasJoined = QueryExpressions.FoldBoolLambdas( (Expression)Expression.Constant(true), categoryLambdas, Expression.AndAlso ); } else { categoryLambdasJoined = QueryExpressions.FoldBoolLambdas( (Expression)Expression.Constant(false), categoryLambdas, Expression.OrElse ); } whereLambdas.Add(categoryLambdasJoined); } // since & until bool isSpecified(DateTime date) { return(date.CompareTo(default(DateTime)) != 0); } if (since != null && isSpecified(since)) { whereLambdas.Add( QueryExpressions.ArtefactCreatedAtQueryExpression( since, true, artefactParam ) ); } if (until != null && isSpecified(until)) { whereLambdas.Add( QueryExpressions.ArtefactCreatedAtQueryExpression( until, false, artefactParam ) ); } // Query param lambda have been appended to 'whereLambdas'. // Take conjunction, then call with Where. Expression whereLambdasAnded = QueryExpressions.FoldBoolLambdas( (Expression)Expression.Constant(true), whereLambdas, Expression.AndAlso ); Expression whereCallExpression = QueryExpressions.GetWhereExp <Artefact>( whereLambdasAnded, artefactParam, artefacts ); // Where applied - build 'OrderBy' lambda Expression finalExpr = whereCallExpression; // sort queries if (sort != null) { var split = sort.Split(':'); var sortBy = split[0]; string sortOrder; if (split.Length > 1) { sortOrder = split[1]; } else { sortOrder = "asc"; } Expression orderByBodyExp; Type orderType = typeof(string); // type of second in a => a.asdasd // get the order by body - ie. OrderBy(orderByBodyExp) switch (sortBy) { case "title": orderType = typeof(string); orderByBodyExp = QueryExpressions.ArtefactPropertyExpression <string>( "Title", artefactParam); break; case "createdAt": orderType = typeof(DateTime); orderByBodyExp = QueryExpressions.ArtefactPropertyExpression <DateTime>( "CreatedAt", artefactParam); break; // TODO(jonah) case "questionCount": orderType = typeof(int); var commentsPropertyExpQ = QueryExpressions.ArtefactPropertyExpression <IEnumerable <ArtefactComment> >( "Comments", artefactParam ); var ofTypeMethod = typeof(Enumerable) .GetMethods() .Single(method => method.Name == "OfType" && method.IsStatic && method.GetParameters().Length == 1); var questionsExp = Expression.Call( ofTypeMethod.MakeGenericMethod(typeof(ArtefactQuestion)), commentsPropertyExpQ ); orderByBodyExp = QueryExpressions .CountExpression <ArtefactQuestion>(questionsExp); break; case "commentCount": orderType = typeof(int); var commentsPropertyExp = QueryExpressions .ArtefactPropertyExpression <IEnumerable <ArtefactComment> >( "Comments", artefactParam ); orderByBodyExp = QueryExpressions .CountExpression <ArtefactComment>(commentsPropertyExp); break; case "imageCount": orderType = typeof(int); var imagePropertyExp = QueryExpressions.ArtefactPropertyExpression <IEnumerable <ArtefactDocument> >( "Images", artefactParam ); orderByBodyExp = QueryExpressions.CountExpression <ArtefactDocument>(imagePropertyExp); break; default: return(BadRequest($"Invalid sort query '{sortBy}'")); } // Set 'finalExpr' since 'OrderBy(..)' instance is // 'artefacts.Where(..)'. if (sortOrder == "asc") { finalExpr = MakeOrderByExp(false); } else if (sortOrder == "desc") { finalExpr = MakeOrderByExp(true); } else { return(BadRequest($"Invalid sort query order '${sortOrder}'")); } MethodCallExpression MakeOrderByExp(bool isDesc) { MethodInfo GetOrderByExpression_MethInfo = typeof(Artefactor.Shared.QueryExpressions) .GetMethod("GetOrderByExp"); object orderByCallExpression = GetOrderByExpression_MethInfo .MakeGenericMethod(typeof(Artefact), orderType) .Invoke(this, new object[] { whereCallExpression, orderByBodyExp, artefactParam, isDesc }); T Cast <T>(object entity) where T : class { return(entity as T); } return(Cast <MethodCallExpression>(orderByCallExpression)); } } // finally, compile and return results IQueryable <Artefact> results = artefacts.Provider.CreateQuery <Artefact>(finalExpr); return(new JsonResult( (await results.ToListAsync()) .Select(a => _artefactConverter.ToJson(a)) )); }
private static string GetCreateAggregateFunction(QueryExpressions expressions) { return("return " + CreateAggregateVisitor.Visit(expressions.CreateAggregateExpression) + ";"); }