Exemplo n.º 1
0
        private QueryCriteria AddQueryCriteria(IDqlObject query, IList <IParameter> parameters, IQueryStore queryStore)
        {
            var queryCriteria = new QueryCriteria {
                Store = queryStore
            };

            if (query is SelectObject)
            {
                var selectQuery = query as SelectObject;
                if (selectQuery.WherePredicate != null && parameters != null)
                {
                    selectQuery.WherePredicate.AssignConstants(parameters);
                    selectQuery.WherePredicate.AssignScalarFunctions();
                }

                var functions = new List <Function>();
                foreach (var projectionValue in selectQuery.Projections)
                {
                    if (selectQuery.IsDistinct)
                    {
                        IEvaluable projValue = projectionValue as IEvaluable;
                        queryCriteria.AddDistinctField(projValue);
                    }

                    var evaluable = projectionValue as IEvaluable;
                    if (parameters != null && evaluable != null)
                    {
                        evaluable.AssignConstants(parameters);
                    }

                    if (evaluable != null)
                    {
                        if (projectionValue is AllEvaluable)
                        {
                            queryCriteria.GetAllFields = true;
                        }
                        else
                        {
                            queryCriteria.AddProjection(evaluable.ToString(), evaluable);
                        }

                        if (evaluable.Functions != null)
                        {
                            functions.AddRange(evaluable.Functions);
                        }
                    }
                }

                foreach (var function in functions)
                {
                    if (!AssignAggregateFunction(function, queryCriteria))
                    {
                        if (!AssignScalarFunction(function))
                        {
                            throw new QuerySystemException(ErrorCodes.Query.INVALID_FUNCTION_NAME_SPECIFIED,
                                                           new[] { function.FunctionNameActual });
                        }
                    }
                }

                if (selectQuery.GroupValue != null)
                {
                    foreach (var projectionValue in selectQuery.GroupValue)
                    {
                        queryCriteria.AddGroupByField(projectionValue);
                    }
                }

                if (queryCriteria.GroupByField == null && queryCriteria.ContainsAggregations &&
                    queryCriteria.Aggregations.Count > 0)
                {
                    queryCriteria.GroupByField = new AllField(Field.FieldType.Grouped);
                }

                if (selectQuery.OrderValue != null)
                {
                    foreach (var projectionValue in selectQuery.OrderValue)
                    {
                        var attribute = projectionValue;
                        if (attribute != null)
                        {
                            queryCriteria.AddOrderByField(attribute,
                                                          attribute is BinaryExpression?
                                                          ((BinaryExpression)attribute).SortOrder: SortOrder.ASC);
                        }
                    }
                }

                long limit = -1;
                if (selectQuery.Limit != null)
                {
                    limit = long.Parse(selectQuery.Limit.InString);
                }
                if (limit > -1)
                {
                    long skip = -1;

                    if (selectQuery.Skip != null)
                    {
                        skip = long.Parse(selectQuery.Skip.InString);
                    }

                    if (skip > 0)
                    {
                        limit += skip;  //: Adding this to avoid bug at query router (while applying skip query)
                    }
                    queryCriteria.AddLimit(limit);
                }
            }
            else if (query is UpdateObject)
            {
                var updateQuery = query as UpdateObject;
                if (updateQuery.WherePredicate != null && parameters != null)
                {
                    updateQuery.WherePredicate.AssignConstants(parameters);
                }
                updateQuery.Updator.AssignConstants(parameters);

                foreach (IUpdation update in updateQuery.Updator.Updations)
                {
                    foreach (var function in update.GetFunctions())
                    {
                        foreach (var argument in function.Arguments)
                        {
                            if (argument.EvaluationType != EvaluationType.Constant)
                            {
                                throw new QuerySystemException(ErrorCodes.Query.INVALID_CONSTANT_FUNCTION_SPECIFIED);
                            }
                        }

                        if (!AssignScalarFunction(function))
                        {
                            throw new QuerySystemException(ErrorCodes.Query.INVALID_FUNCTION_NAME_SPECIFIED,
                                                           new[] { function.FunctionNameActual });
                        }
                    }
                }

                queryCriteria.DocumentUpdate = updateQuery.Updator;
                queryCriteria.UpdateOption   = UpdateOption.Update;
            }
            else if (query is InsertObject)
            {
                var document = new JSONDocument();
                foreach (KeyValuePair <Attribute, IEvaluable> pair in ((InsertObject)query).ValuesToInsert)
                {
                    pair.Value.AssignConstants(parameters);

                    foreach (var function in pair.Value.Functions)
                    {
                        foreach (var argument in function.Arguments)
                        {
                            if (argument.EvaluationType != EvaluationType.Constant)
                            {
                                throw new QuerySystemException(ErrorCodes.Query.INVALID_CONSTANT_FUNCTION_SPECIFIED);
                            }
                        }

                        if (!AssignScalarFunction(function))
                        {
                            throw new QuerySystemException(ErrorCodes.Query.INVALID_FUNCTION_NAME_SPECIFIED,
                                                           new[] { function.FunctionNameActual });
                        }
                    }

                    IJsonValue jsonValue;
                    if (!pair.Value.Evaluate(out jsonValue, null))
                    {
                        throw new QuerySystemException(ErrorCodes.Query.INVALID_CONSTANT_BINARY_EXPRESSION_SPECIFIED);
                    }
                    document.Add(pair.Key.ToString(), jsonValue.Value);
                }
                queryCriteria.NewDocument  = document;
                queryCriteria.UpdateOption = UpdateOption.Insert;
            }
            else if (query is DeleteObject)
            {
                var deleteQuery = query as DeleteObject;
                if (deleteQuery.WherePredicate != null && parameters != null)
                {
                    deleteQuery.WherePredicate.AssignConstants(parameters);
                }
                queryCriteria.UpdateOption = UpdateOption.Delete;
            }
            return(queryCriteria);
        }