示例#1
0
        /// <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.");
        }
示例#3
0
        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());
        }
示例#4
0
 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());
 }
示例#5
0
        private static string GetShouldStartNewAggregateFunction(QueryExpressions expressions)
        {
            if (expressions.GroupByExpression == null)
            {
                return("return false;");
            }

            return("return " + ShouldStartNewAggregateVisitor.Visit(expressions.GroupByExpression) + ";");
        }
示例#6
0
        private static string GetCreateResultFunction(QueryExpressions expressions)
        {
            if (expressions.CreateResultExpression == null)
            {
                return("return aggregate;");
            }

            return("return " + CreateResultVisitor.Visit(expressions.CreateResultExpression) + ";");
        }
示例#7
0
        private static string GetCreateAggregateSeedFunction(QueryExpressions expressions)
        {
            if (expressions.CreateAggregateSeedExpression == null)
            {
                return("return first;");
            }

            return("return " + CreateAggregateSeedVisitor.Visit(expressions.CreateAggregateSeedExpression) + ";");
        }
示例#8
0
        /// <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[] { });
        }
示例#12
0
        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))
                       ));
        }
示例#13
0
 private static string GetCreateAggregateFunction(QueryExpressions expressions)
 {
     return("return " + CreateAggregateVisitor.Visit(expressions.CreateAggregateExpression) + ";");
 }