public void executes_SideExpressions_in_order() { var expression = new BatchExpression <int> { SideExpressions = new[] { new EmptyExpression(), new EmptyExpression(), new EmptyExpression() } }; var executionOrder = new List <int>(); var expressionExecutor = Substitute.For <IExpressionExecutor>(); for (var i = 0; i < 3; i++) { var order = i; expressionExecutor.Execute(expression.SideExpressions.ElementAt(i)) .Returns(_ => { executionOrder.Add(order); return(0); }); } Act(expression, expressionExecutor); executionOrder.Should().Equal(0, 1, 2); }
public void executes_SideExpressions_before_ResultExpression() { var expression = new BatchExpression <int> { SideExpressions = new[] { new EmptyExpression() }, ResultExpression = new EmptyExpression <int>() }; var executionOrder = new List <int>(); var expressionExecutor = Substitute.For <IExpressionExecutor>(); expressionExecutor.Execute(expression.SideExpressions.First()) .Returns(_ => { executionOrder.Add(0); return(0); }); expressionExecutor.Execute(expression.ResultExpression) .Returns(_ => { executionOrder.Add(1); return(0); }); Act(expression, expressionExecutor); executionOrder.Should().Equal(0, 1); }
public void batch_expression(string log1, string log2, int constant) { var expression = new BatchExpression <int> { SideExpressions = new IExpression[] { new FunctionExpression <LogFunction, Domain.FunctionsDomain.Void> { ArgumentExpressions = new Dictionary <string, IExpression> { [nameof(LogFunction.Log)] = new ConstantExpression <string> { Value = log1 } } }, new FunctionExpression <LogFunction, Domain.FunctionsDomain.Void> { ArgumentExpressions = new Dictionary <string, IExpression> { [nameof(LogFunction.Log)] = new ConstantExpression <string> { Value = log2 } } } }, ResultExpression = new ConstantExpression <int> { Value = constant } }; var result = Act(expression); result.Should().Be(constant); LogStore.GetLog().Should().Equal(log1, log2); }
protected BatchExpression UpdateBatch(BatchExpression batch, Expression input, LambdaExpression operation, Expression batchSize, Expression stream) { if (input != batch.Input || operation != batch.Operation || batchSize != batch.BatchSize || stream != batch.Stream) { return new BatchExpression(input, operation, batchSize, stream); } return batch; }
protected virtual Expression BuildExecuteBatch(BatchExpression batch) { // parameterize query Expression operation = this.Parameterize(batch.Operation.Body); string commandText = this.linguist.Format(operation); var namedValues = NamedValueGatherer.Gather(operation); QueryCommand command = new QueryCommand(commandText, namedValues.Select(v => new QueryParameter(v.Name, v.Type, v.QueryType))); Expression[] values = namedValues.Select(v => Expression.Convert(this.Visit(v.Value), typeof(object))).ToArray(); Expression paramSets = Expression.Call(typeof(Enumerable), "Select", new Type[] { batch.Operation.Parameters[1].Type, typeof(object[]) }, batch.Input, Expression.Lambda(Expression.NewArrayInit(typeof(object), values), new[] { batch.Operation.Parameters[1] })); Expression plan = null; ProjectionExpression projection = ProjectionFinder.FindProjection(operation); if (projection != null) { var saveScope = this.scope; ParameterExpression reader = Expression.Parameter(typeof(FieldReader), "r" + this.nReaders++); this.scope = new Scope(this.scope, reader, projection.Select.Alias, projection.Select.Columns); LambdaExpression projector = Expression.Lambda(this.Visit(projection.Projector), reader); this.scope = saveScope; var entity = EntityFinder.Find(projection.Projector); command = new QueryCommand(command.CommandText, command.Parameters); plan = Expression.Call(this.executor, "ExecuteBatch", new Type[] { projector.Body.Type }, Expression.Constant(command), paramSets, projector, Expression.Constant(entity, typeof(MappingEntity)), batch.BatchSize, batch.Stream); } else { plan = Expression.Call(this.executor, "ExecuteBatch", null, Expression.Constant(command), paramSets, batch.BatchSize, batch.Stream); } return(plan); }
public void BatchExpression___invokes_batchExpressionExecutor(int expressionResult) { var expression = new BatchExpression <int>(); var batchExpressionExecutor = Substitute.For <IBatchExpressionExecutor>(); batchExpressionExecutor.Execute(expression) .Returns(expressionResult); var result = Act(expression, batchExpressionExecutor: batchExpressionExecutor); result.Should().Be(expressionResult); }
protected override Expression VisitBatch(BatchExpression batch) { if (this.Dialect.SupportMultipleCommands || !IsMultipleCommands(batch.Operation.Body as CommandExpression)) { return(this.BuildExecuteBatch(batch)); } else { var source = this.Visit(batch.Input); var op = this.Visit(batch.Operation.Body); var fn = Expression.Lambda(op, batch.Operation.Parameters[1]); return(Expression.Call(this.GetType(), "Batch", new Type[] { ReflectionHelper.GetElementType(source.Type), batch.Operation.Body.Type }, source, fn)); } }
protected override Expression VisitBatch(BatchExpression batch) { if (this.linguist.Language.AllowsMultipleCommands || !this.IsMultipleCommands(batch.Operation.Body as CommandExpression)) { return(this.BuildExecuteBatch(batch)); } else { var source = this.Visit(batch.Input); var op = this.Visit(batch.Operation.Body); var fn = Expression.Lambda(op, batch.Operation.Parameters[1]); return(Expression.Call(this.GetType(), "Batch", new Type[] { TypeHelper.GetElementType(source.Type), batch.Operation.Body.Type }, source, fn, batch.Stream)); } }
public void returns_ResultExpression_result(int resultExpressionResult) { var expression = new BatchExpression <int> { ResultExpression = new EmptyExpression <int>() }; var expressionExecutor = Substitute.For <IExpressionExecutor>(); expressionExecutor.Execute(expression.ResultExpression) .Returns(x => resultExpressionResult); var result = Act(expression, expressionExecutor); result.Should().Be(resultExpressionResult); }
public void complex_expression() { var expression = new BatchExpression <int> { SideExpressions = new IExpression[] { new FunctionExpression <LogFunction, Void> { ArgumentExpressions = new Dictionary <string, IExpression> { [nameof(LogFunction.Text)] = new ConstantExpression <string> { Value = "Calculating..." } } } }, ResultExpression = new FunctionExpression <SubFunction, int> { ArgumentExpressions = new Dictionary <string, IExpression> { [nameof(SubFunction.A)] = new FunctionExpression <AddFunction, int> { ArgumentExpressions = new Dictionary <string, IExpression> { [nameof(AddFunction.A)] = new ConstantExpression <int> { Value = 1 }, [nameof(AddFunction.B)] = new ConstantExpression <int> { Value = 2 } } }, [nameof(SubFunction.B)] = new ConstantExpression <int> { Value = 3 } } } }; var result = Act(Serialize(expression)); result.ShouldBeEquivalentTo(expression); }
public void BatchExpression() { var expression = new BatchExpression <string> { SideExpressions = new IExpression[] { new ConstantExpression <int> { Value = 3 }, new ConstantExpression <double> { Value = 5.0 } }, ResultExpression = new ConstantExpression <string> { Value = "value" } }; var result = Act(Serialize(expression)); result.ShouldBeEquivalentTo(expression); }
protected virtual Expression VisitBatch(BatchExpression batch) { this.Write("Batch("); this.WriteLine(Indentation.Inner); this.Visit(batch.Input); this.Write(","); this.WriteLine(Indentation.Same); this.Visit(batch.Operation); this.Write(")"); return batch; }
protected virtual bool CompareBatch(BatchExpression x, BatchExpression y) { return this.Compare(x.Input, y.Input) && this.Compare(x.Operation, y.Operation) && this.Compare(x.BatchSize, y.BatchSize) && this.Compare(x.Stream, y.Stream); }
protected virtual bool CompareBatch(BatchExpression x, BatchExpression y) { return this.Compare(x.Input, y.Input) && this.Compare(x.Operation, y.Operation); }
protected BatchExpression UpdateBatch(BatchExpression batch, Expression input, LambdaExpression operation) { if (input != batch.Input || operation != batch.Operation) { return new BatchExpression(input, operation); } return batch; }
protected virtual Expression VisitBatch(BatchExpression batch) { var operation = (LambdaExpression)this.Visit(batch.Operation); return this.UpdateBatch(batch, batch.Input, operation); }
protected virtual Expression BuildExecuteBatch(BatchExpression batch) { Expression operation = this.Parameterize(batch.Operation.Body); var cdu = batch.Operation.Body as CDUCommandExpression; Type entityType = null; if (cdu != null) { entityType = cdu.Table.Mapping.EntityType; } string commandText = this.dbContext.BuildSql(operation); var namedValues = NamedValueGatherer.Gather(operation); var parameters = namedValues.Select(v => new NamedParameter(v.Name, v.Type, v.SqlType)).ToArray(); Expression[] values = namedValues.Select(v => Expression.Convert(this.Visit(v.Value), typeof(object))).ToArray(); Expression paramSets = Expression.Call(typeof(Enumerable), "Select", new Type[] { batch.Operation.Parameters[1].Type, typeof(object[]) }, batch.Input, Expression.Lambda(Expression.NewArrayInit(typeof(object), values), new[] { batch.Operation.Parameters[1] }) ); Expression plan = null; ProjectionExpression projection = ProjectionFinder.FindProjection(operation); if (projection != null) { var saveScope = this.scope; ParameterExpression reader = Expression.Parameter(typeof(FieldReader), "r" + nReaders++); this.scope = new Scope(this.scope, reader, projection.Select.Alias, projection.Select.Columns); LambdaExpression projector = Expression.Lambda(this.Visit(projection.Projector), reader); this.scope = saveScope; // var entity = EntityFinder.Find(projection.Projector); var batchContext = Expression.New(typeof(BatchContext <>).MakeGenericType(projector.Body.Type).GetConstructors().FirstOrDefault(), Expression.Constant(commandText), Expression.Constant(parameters), paramSets, projector); plan = Expression.Call(this.executor, "Batch", new Type[] { projector.Body.Type }, batchContext); } else { var batchContext = Expression.New(typeof(BatchContext).GetConstructors().FirstOrDefault(), Expression.Constant(commandText), Expression.Constant(parameters), paramSets, Expression.Constant(entityType)); //plan = Expression.Call(this.executor, "Batch", null, // Expression.Constant(commandText), // Expression.Constant(parameters), // paramSets // ); plan = Expression.Call(this.executor, "Batch", null, batchContext); } return(plan); }
protected virtual Expression VisitBatch(BatchExpression batch) { var operation = (LambdaExpression)this.Visit(batch.Operation); var batchSize = this.Visit(batch.BatchSize); var stream = this.Visit(batch.Stream); return this.UpdateBatch(batch, batch.Input, operation, batchSize, stream); }