/// <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)); }
/// <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)); } } }
/// <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; }
/// <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; }
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); }
/// <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) { }
/// <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; }