public async Task <SqlMethodResult> ExecuteAsync(IContext context, Invoke invoke) { using (var methodContext = new MethodContext(context, this, invoke)) { try { await ExecuteContextAsync(methodContext); } catch (MethodException) { throw; } catch (Exception ex) { throw new MethodException($"Error while executing {MethodInfo.MethodName}: see inner exception for more information", ex); } var result = methodContext.CreateResult(); result.Validate(this, context); return(result); } }
private async Task <SqlObject> IterateValues(MethodContext context, SqlExpression input, IGroupResolver groupResolver) { SqlObject result = null; for (long i = 0; i < groupResolver.Size; i++) { SqlObject value; var resolver = groupResolver.GetResolver(i); using (var reduce = context.Create("reduce", scope => scope.AddReferenceResolver(resolver))) { var reduced = await input.ReduceAsync(reduce); if (reduced.ExpressionType != SqlExpressionType.Constant) { throw new InvalidOperationException(); } value = ((SqlConstantExpression)reduced).Value; } using (var accumulate = new IterateContext(context, i, result, value)) { await IterateAsync(accumulate); if (accumulate.Result == null) { throw new MethodAccessException("No result value was provided by the iteration"); } result = accumulate.Result; if (!accumulate.Iterate) { break; } } } return(result); }
protected abstract Task ExecuteContextAsync(MethodContext context);
protected override async Task ExecuteContextAsync(MethodContext context) { var groupResolver = (context as IContext).Scope.Resolve <IGroupResolver>(); if (groupResolver == null) { throw new NotSupportedException($"Aggregate function {MethodInfo.MethodName} requires a group resolver in context"); } if (groupResolver.Size == 0) { context.SetResult(SqlObject.NullOf(MethodInfo.ReturnType)); return; } SqlExpression input = null; if (context.ArgumentCount > 0) { input = context.Argument(0); } using (var seed = new InitializeContext(context, input)) { await InitializeAsync(seed); if (seed.Result != null) { input = seed.Result; } if (!seed.Iterate) { context.SetResult(input); return; } } SqlObject output = null; if (input != null) { if (input is SqlReferenceExpression) { var reference = (SqlReferenceExpression)input; output = await IterateReference(context, reference.ReferenceName, groupResolver); } else { output = await IterateValues(context, input, groupResolver); } } using (var aggregate = new MergeContext(context, output)) { await MergeAsync(aggregate); if (aggregate.Output != null) { output = aggregate.Output; } } context.SetResult(output); }
internal InitializeContext(MethodContext context, SqlExpression input) : base(context, $"Initialize({context.Method.MethodInfo.MethodName})") { Input = input; }
protected override Task ExecuteContextAsync(MethodContext context) { return(body(context)); }