1using System.Threading.Tasks;
18 private readonly
bool[] groupByAsynchronous;
20 private readonly
bool[] iteratorUsesElement;
21 private readonly
bool[] iteratorAsynchronous;
23 private readonly
int iteratorCount;
24 private readonly
int count;
25 private readonly
bool isAsynchronous;
28 private object[] last =
null;
29 private object[] current =
null;
44 this.groupBy = GroupBy;
45 this.groupNames = GroupNames;
46 this.isAsynchronous =
false;
51 this.groupByAsynchronous =
new bool[c];
54 for (i = 0; i < c; i++)
57 this.isAsynchronous |= b;
60 if (!this.isAsynchronous && !(GroupNames is
null))
62 for (i = 0, c = GroupNames.
Length; i < c; i++)
66 this.isAsynchronous =
true;
72 if (!this.isAsynchronous && !(Columns is
null))
74 for (i = 0, c = Columns.
Length; i < c; i++)
78 this.isAsynchronous =
true;
84 if (!this.isAsynchronous && !(Having is
null))
85 this.isAsynchronous |= Having.IsAsynchronous;
89 if (!(Columns is
null))
91 for (i = 0, c = Columns.
Length; i < c; i++)
92 FindIterators(ref Columns[i], Iterators);
95 FindIterators(ref Having, Iterators);
97 this.iterators = Iterators.
ToArray();
98 this.iteratorCount = this.iterators.Length;
100 this.iteratorUsesElement =
new bool[this.iteratorCount];
101 this.iteratorAsynchronous =
new bool[this.iteratorCount];
103 for (i = 0; i < this.iteratorCount; i++)
105 this.iteratorUsesElement[i] = this.iterators[i].UsesElement;
106 this.iteratorAsynchronous[i] = b = this.iterators[i].IsAsynchronous;
107 this.isAsynchronous |= b;
117 this.processor = Processor;
124 int IteratorIndex = Iterators.
Count;
126 Iterators.
Add(Evaluator);
131 Node.Start, Node.Length, Node.Expression);
133 Node.SetParent(Node0.
Parent);
136 Iterators.
Add(GroupIteratorValue2.Iterator);
138 Node?.ForAllChildNodes(FindIterators, Iterators,
SearchMethod.TreeOrder);
148 int IteratorIndex = Iterators.
Count;
150 Iterators.
Add(Evaluator);
181 if (this.objectVariables is
null)
184 this.objectVariables.Object = Object;
186 if (this.last is
null)
188 this.last =
new object[this.count];
190 for (i = 0; i < this.count; i++)
192 E = this.groupBy[i].Evaluate(this.objectVariables);
196 if (this.iteratorCount > 0)
198 for (j = 0; j < this.iteratorCount; j++)
199 this.iterators[j].RestartEvaluator();
204 if (this.current is
null)
205 this.current =
new object[this.count];
209 for (i = 0; i < this.count; i++)
211 E = this.groupBy[i].Evaluate(this.objectVariables);
216 if ((o1 is
null ^ o2 is
null) ||
217 (!(o1 is
null) && !o1.Equals(o2)))
225 if (this.processor is
null)
231 if (!this.processor.
Process(Obj))
234 this.last = this.current;
239 if (this.iteratorCount > 0)
241 for (j = 0; j < this.iteratorCount; j++)
243 Iterator = this.iterators[j];
245 if (this.iteratorUsesElement[j])
247 E = Iterator.
Evaluate(this.objectVariables);
264 for (i = 0; i < this.iteratorCount; i++)
266 Iterator = this.iterators[i];
271 return new GroupObject(this.last, Aggregates, this.groupNames, this.variables);
286 if (this.objectVariables is
null)
289 this.objectVariables.Object = Object;
291 if (this.last is
null)
293 this.last =
new object[this.count];
295 for (i = 0; i < this.count; i++)
297 if (this.groupByAsynchronous[i])
298 E = await this.groupBy[i].EvaluateAsync(this.objectVariables);
300 E = this.groupBy[i].Evaluate(this.objectVariables);
305 if (this.iteratorCount > 0)
307 for (j = 0; j < this.iteratorCount; j++)
308 this.iterators[j].RestartEvaluator();
313 if (this.current is
null)
314 this.current =
new object[this.count];
318 for (i = 0; i < this.count; i++)
320 if (this.groupByAsynchronous[i])
321 E = await this.groupBy[i].EvaluateAsync(this.objectVariables);
323 E = this.groupBy[i].Evaluate(this.objectVariables);
328 if ((o1 is
null ^ o2 is
null) ||
329 (!(o1 is
null) && !o1.Equals(o2)))
337 if (this.processor is
null)
346 this.last = this.current;
351 if (this.iteratorCount > 0)
353 for (j = 0; j < this.iteratorCount; j++)
355 Iterator = this.iterators[j];
357 if (this.iteratorUsesElement[j])
359 if (this.iteratorAsynchronous[j])
362 E = Iterator.
Evaluate(this.objectVariables);
380 if (!(this.last is
null))
385 if (!this.processor.
Process(Obj))
389 return this.processor.
Flush();
398 if (!(this.last is
null))
A chunked list is a linked list of chunks of objects of type T .
int Count
Number of elements in collection.
void Add(T Item)
Adds an item to the collection.
T[] ToArray()
Returns an array containing all elements of the collection.
Base class for all nodes in a parsed script tree.
int Length
Length of expression covered by node.
ScriptNode Parent
Parent node.
Expression Expression
Expression of which the node is a part.
int Start
Start position in script expression.
virtual bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
static readonly ObjectValue Null
Null value.
Returns the result value from an iterator.
IIterativeEvaluator Iterator
Iterator
Represents a collection of objects grouped together useing a GROUP BY construct.
Processor that groups items into groups, and processes aggregated elements.
bool Process(object Object)
Processes an object synchronously.
bool Flush()
Called at the end of processing, to allow for flushing of buffers, etc.
async Task< bool > FlushAsync()
Called at the end of processing, to allow for flushing of buffers, etc.
bool IsAsynchronous
If the processor operates asynchronously.
async Task< bool > ProcessAsync(object Object)
Processes an object asynchronously.
GroupProcessor(Variables Variables, ScriptNode[] GroupBy, ScriptNode[] GroupNames, ScriptNode[] Columns, ref ScriptNode Having)
Processor that groups items into groups, and processes aggregated elements.
void SetInnerProcessor(IProcessor< object > Processor)
Sets the inner processor.
Interface for processors of objects.
bool Process(T Object)
Processes an object synchronously.
bool Flush()
Called at the end of processing, to allow for flushing of buffers, etc.
Task< bool > FlushAsync()
Called at the end of processing, to allow for flushing of buffers, etc.
Task< bool > ProcessAsync(T Object)
Processes an object asynchronously.
Basic interface for all types of elements.
object AssociatedObjectValue
Associated object value.
A function that can be iteratively evaluated, meaning it can be iteratively computed one element at a...
An interative evaluator of a function supporting the IIterativeEvaluation interface.
IElement GetAggregatedResult()
Gets the aggregated result.
Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the evaluator, using the variables provided in the Variables collection and an object inst...
IElement Evaluate(Variables Variables)
Evaluates the evaluator, using the variables provided in the Variables collection and an object inst...
void AggregateElement(IElement Element)
Aggregates one new element.
void RestartEvaluator()
Restarts the evaluator.
SearchMethod
Method to traverse the expression structure