Example #1
0
        /// <summary>
        /// Temporarily replaces the evaluator's data-set with the one given
        /// </summary>
        /// <param name="temporary">The temporary query data-set</param>
        /// <returns>A token that, when disposed, will reset the query data-set back to the original.</returns>
        public IDisposable WithTemporaryDataSet(IQueryDataSet temporary)
        {
            var original = this.QueryDataSet;

            this.QueryDataSet = temporary;
            return(new DelegateBasedDisposable(() => this.QueryDataSet = original));
        }
Example #2
0
        /// <summary>
        /// Build QueryValue from query expresion and server response.
        /// </summary>
        /// <param name="expression">The query expresion of client request.</param>
        /// <param name="response">The http response from the server.</param>
        /// <returns>The baseline QueryValue converted from payload.</returns>
        public QueryValue BuildQueryValue(QueryExpression expression, HttpResponseData response)
        {
            ExceptionUtilities.CheckArgumentNotNull(expression, "expression");
            ExceptionUtilities.CheckArgumentNotNull(response, "response");
            ExceptionUtilities.CheckAllRequiredDependencies(this);

            // get type resolver and payload deserializer.
            var typeResolver = new LinqToAstoriaTypeResolutionVisitor(this.TypeLibrary);

            // if the response has an error
            if (response.StatusCode != HttpStatusCode.OK)
            {
                return(expression.ExpressionType.CreateErrorValue(new QueryError("Response from server has an error!")));
            }

            string contentType;

            ExceptionUtilities.Assert(response.Headers.TryGetValue(HttpHeaders.ContentType, out contentType), "Cannot get content type from response.");
            var deserializer = this.StrategySelector.GetStrategy(contentType, null).GetDeserializer();

            this.currentExpression = expression;

            var      expressionForUri = this.ClientSideProjectionReplacer.ReplaceClientSideProjections(expression);
            ODataUri queryUri         = this.QueryToODataUriConverter.ComputeUri(expressionForUri);

            queryUri.Segments.Insert(0, ODataUriBuilder.Root(this.Workspace.ServiceUri));

            // deserialize byte array payload to OData payload element.
            ODataPayloadElement payload = this.DeserializePayloadData(deserializer, response, queryUri);

            this.PayloadElementMetadataResolver.ResolveMetadata(payload, queryUri);
            var normalizer = this.StrategySelector.GetStrategy(contentType, null).GetPayloadNormalizer();

            payload = normalizer.Normalize(payload);

            if (this.ShouldUsePayloadDrivenVerification(queryUri))
            {
                return(this.BuildQueryValueForActionResponse(payload, expression.ExpressionType));
            }
            else
            {
                // build query data set from payload for evaluation. It's a different data set from the initial one of current workspace.
                IQueryDataSet dataSet = this.BuildQueryDataSet(payload);

                // filter the query and resolve types. Need to remove expressions such as $top, $skip, $orderby, $filter because the returned payload is already the result of performing these expressions.
                // need to keep root expression, key expression, $expand and $select to have correct anonymous type.
                var filteredQuery = this.FilterExpression(expression);
                filteredQuery = typeResolver.ResolveTypes(filteredQuery, this.EvaluationStrategy);

                // replace the evaluator's query-data-set with the one generated in the payload
                using (this.Evaluator.WithTemporaryDataSet(dataSet))
                {
                    return(this.Evaluator.Evaluate(filteredQuery));
                }
            }
        }
Example #3
0
        /// <summary>
        /// Initializes a new instance of the QueryRepository class.
        /// </summary>
        /// <param name="typeLibrary">The query type library.</param>
        /// <param name="rootQueries">The collection of QueryExpressions used to initialize the RootQueries property</param>
        /// <param name="constants">The collection of QueryConstants used to initialize the Constants property</param>
        /// <param name="scalarTypes">The collection of scalar types.</param>
        /// <param name="rootDataTypes">The root data types.</param>
        /// <param name="dataSet">The data set used to initialize the DataSet property.</param>
        public QueryRepository(QueryTypeLibrary typeLibrary, IEnumerable<QueryExpression> rootQueries, IEnumerable<QueryConstantExpression> constants, IEnumerable<QueryScalarType> scalarTypes, IDictionary<string, QueryStructuralType> rootDataTypes, IQueryDataSet dataSet)
        {
            ExceptionUtilities.CheckArgumentNotNull(typeLibrary, "typeLibrary");
            ExceptionUtilities.CheckArgumentNotNull(rootQueries, "rootQueries");
            ExceptionUtilities.CheckArgumentNotNull(constants, "constants");
            ExceptionUtilities.CheckArgumentNotNull(scalarTypes, "scalarTypes");
            ExceptionUtilities.CheckArgumentNotNull(rootDataTypes, "rootDataTypes");
            ExceptionUtilities.CheckArgumentNotNull(dataSet, "dataSet");

            this.TypeLibrary = typeLibrary;
            this.RootQueries = rootQueries.ToList().AsReadOnly();
            this.Constants = constants.ToList().AsReadOnly();
            this.ScalarTypes = scalarTypes.ToList().AsReadOnly();
            this.RootDataTypes = new Dictionary<string, QueryStructuralType>(rootDataTypes);
            this.DataSet = dataSet;
        }
Example #4
0
        /// <summary>
        /// Initializes a new instance of the QueryRepository class.
        /// </summary>
        /// <param name="typeLibrary">The query type library.</param>
        /// <param name="rootQueries">The collection of QueryExpressions used to initialize the RootQueries property</param>
        /// <param name="constants">The collection of QueryConstants used to initialize the Constants property</param>
        /// <param name="scalarTypes">The collection of scalar types.</param>
        /// <param name="rootDataTypes">The root data types.</param>
        /// <param name="dataSet">The data set used to initialize the DataSet property.</param>
        public QueryRepository(QueryTypeLibrary typeLibrary, IEnumerable <QueryExpression> rootQueries, IEnumerable <QueryConstantExpression> constants, IEnumerable <QueryScalarType> scalarTypes, IDictionary <string, QueryStructuralType> rootDataTypes, IQueryDataSet dataSet)
        {
            ExceptionUtilities.CheckArgumentNotNull(typeLibrary, "typeLibrary");
            ExceptionUtilities.CheckArgumentNotNull(rootQueries, "rootQueries");
            ExceptionUtilities.CheckArgumentNotNull(constants, "constants");
            ExceptionUtilities.CheckArgumentNotNull(scalarTypes, "scalarTypes");
            ExceptionUtilities.CheckArgumentNotNull(rootDataTypes, "rootDataTypes");
            ExceptionUtilities.CheckArgumentNotNull(dataSet, "dataSet");

            this.TypeLibrary   = typeLibrary;
            this.RootQueries   = rootQueries.ToList().AsReadOnly();
            this.Constants     = constants.ToList().AsReadOnly();
            this.ScalarTypes   = scalarTypes.ToList().AsReadOnly();
            this.RootDataTypes = new Dictionary <string, QueryStructuralType>(rootDataTypes);
            this.DataSet       = dataSet;
        }
Example #5
0
        protected virtual void BuildConstants(QueryTypeLibrary queryTypeLibrary, IQueryDataSet dataSet)
        {
            ExceptionUtilities.CheckObjectNotNull(this.RootQueries, "Build root queries first before building constants");

            List <QueryConstantExpression> queryConstants = new List <QueryConstantExpression>();
            var rootQueries = this.RootQueries.OfType <QueryRootExpression>();

            int constantsOfSameTypeLimit = 5;

            foreach (var rootQuery in rootQueries)
            {
                var entityElements = dataSet[rootQuery.Name].Elements;

                if (entityElements.Count() == 0)
                {
                    continue;
                }

                var dataRow           = this.Random.ChooseFrom(entityElements.Cast <QueryStructuralValue>());
                var scalarDataValues  = dataRow.Type.Properties.Where(p => p.PropertyType is QueryScalarType).Select(st => dataRow.GetScalarValue(st.Name)).ToList();
                var complexDataValues = dataRow.Type.Properties.Where(p => p.PropertyType is QueryComplexType).Select(ct => dataRow.GetStructuralValue(ct.Name)).ToList();

                while (complexDataValues.Count() > 0)
                {
                    var complexDataValue = complexDataValues.First();

                    foreach (var propertyName in complexDataValue.MemberNames)
                    {
                        var complexPropertyValue = complexDataValue.GetValue(propertyName);
                        var nestedComplexValue   = complexPropertyValue as QueryStructuralValue;
                        var nestedScalarValue    = complexPropertyValue as QueryScalarValue;

                        if (nestedComplexValue != null)
                        {
                            complexDataValues.Add(nestedComplexValue);
                        }
                        else if (nestedScalarValue != null)
                        {
                            scalarDataValues.Add(nestedScalarValue);
                        }
                    }

                    complexDataValues.Remove(complexDataValue);
                }

                this.AddDefaultConstants(scalarDataValues, queryTypeLibrary);

                foreach (var scalarTypeValue in scalarDataValues)
                {
                    if (queryConstants.Count(qce => qce.ExpressionType.IsSameQueryScalarType(scalarTypeValue.Type as QueryScalarType)) <= constantsOfSameTypeLimit)
                    {
                        queryConstants.Add(CommonQueryBuilder.Constant(scalarTypeValue));
                    }
                }
            }

            var nonMappedEnumTypes = queryTypeLibrary.GetNonMappedEnumTypes();

            foreach (var nonMappedEnum in nonMappedEnumTypes)
            {
                var enumMember      = this.Random.ChooseFrom(nonMappedEnum.EnumType.Members);
                var enumObjectToAdd = Enum.Parse(nonMappedEnum.ClrType, enumMember.Name, false);

                queryConstants.Add(CommonQueryBuilder.Constant(enumObjectToAdd));
            }

            this.Constants = queryConstants.AsEnumerable();
        }
        protected virtual void BuildConstants(QueryTypeLibrary queryTypeLibrary, IQueryDataSet dataSet)
        {
            ExceptionUtilities.CheckObjectNotNull(this.RootQueries, "Build root queries first before building constants");

            List<QueryConstantExpression> queryConstants = new List<QueryConstantExpression>();
            var rootQueries = this.RootQueries.OfType<QueryRootExpression>();

            int constantsOfSameTypeLimit = 5;
            foreach (var rootQuery in rootQueries)
            {
                var entityElements = dataSet[rootQuery.Name].Elements;

                if (entityElements.Count() == 0)
                {
                    continue;
                }

                var dataRow = this.Random.ChooseFrom(entityElements.Cast<QueryStructuralValue>());
                var scalarDataValues = dataRow.Type.Properties.Where(p => p.PropertyType is QueryScalarType).Select(st => dataRow.GetScalarValue(st.Name)).ToList();
                var complexDataValues = dataRow.Type.Properties.Where(p => p.PropertyType is QueryComplexType).Select(ct => dataRow.GetStructuralValue(ct.Name)).ToList();

                while (complexDataValues.Count() > 0)
                {
                    var complexDataValue = complexDataValues.First();

                    foreach (var propertyName in complexDataValue.MemberNames)
                    {
                        var complexPropertyValue = complexDataValue.GetValue(propertyName);
                        var nestedComplexValue = complexPropertyValue as QueryStructuralValue;
                        var nestedScalarValue = complexPropertyValue as QueryScalarValue;

                        if (nestedComplexValue != null)
                        {
                            complexDataValues.Add(nestedComplexValue);
                        }
                        else if (nestedScalarValue != null)
                        {
                            scalarDataValues.Add(nestedScalarValue);
                        }
                    }

                    complexDataValues.Remove(complexDataValue);
                }

                this.AddDefaultConstants(scalarDataValues, queryTypeLibrary);

                foreach (var scalarTypeValue in scalarDataValues)
                {
                    if (queryConstants.Count(qce => qce.ExpressionType.IsSameQueryScalarType(scalarTypeValue.Type as QueryScalarType)) <= constantsOfSameTypeLimit)
                    {
                        queryConstants.Add(CommonQueryBuilder.Constant(scalarTypeValue));
                    }
                }
            }

            var nonMappedEnumTypes = queryTypeLibrary.GetNonMappedEnumTypes();

            foreach (var nonMappedEnum in nonMappedEnumTypes)
            {
                var enumMember = this.Random.ChooseFrom(nonMappedEnum.EnumType.Members);
                var enumObjectToAdd = Enum.Parse(nonMappedEnum.ClrType, enumMember.Name, false);

                queryConstants.Add(CommonQueryBuilder.Constant(enumObjectToAdd));
            }

            this.Constants = queryConstants.AsEnumerable();
        }
 /// <summary>
 /// Initializes a new instance of the LinqEvaluatingVisitor class.
 /// </summary>
 /// <param name="dataSet">The data set.</param>
 /// <param name="freeVariableAssignments">Free variable assignments.</param>
 protected LinqEvaluatingVisitor(IQueryDataSet dataSet, IDictionary <string, QueryExpression> freeVariableAssignments)
     : base(dataSet)
 {
     this.lambdaParameterAssignments = new Dictionary <LinqParameterExpression, QueryValue>();
     this.freeVariableAssignments    = new Dictionary <string, QueryExpression>(freeVariableAssignments);
 }
Example #8
0
 /// <summary>
 /// Initializes a new instance of the LinqToAstoriaEvaluatingVisitor class.
 /// </summary>
 /// <param name="dataSet">The data set.</param>
 /// <param name="freeVariableAssignments">Free variable assignments.</param>
 internal LinqToAstoriaEvaluatingVisitor(IQueryDataSet dataSet, IDictionary <string, QueryExpression> freeVariableAssignments)
     : base(dataSet, freeVariableAssignments)
 {
 }
Example #9
0
 /// <summary>
 /// Initializes a new instance of the CommonExpressionEvaluatingVisitor class.
 /// </summary>
 /// <param name="dataSet">The data set.</param>
 protected CommonExpressionEvaluatingVisitor(IQueryDataSet dataSet)
 {
     ExceptionUtilities.CheckArgumentNotNull(dataSet, "dataSet");
     this.dataSet = dataSet;
 }