示例#1
0
        /// <summary>
        /// Advances the enumerator to the next element of the collection.
        /// </summary>
        /// <returns>true if the enumerator was successfully advanced to the next element; false if
        /// the enumerator has passed the end of the collection.</returns>
        /// <exception cref="InvalidOperationException">The collection was modified after the enumerator was created.</exception>
        public async Task <bool> MoveNextAsync()
        {
            if (!await this.e.MoveNextAsync())
            {
                return(false);
            }

            int      i;
            object   Item    = e.Current;
            IElement Element = Item as IElement;

            if (this.properties is null)
            {
                this.properties = new ObjectProperties(Element?.AssociatedObjectValue ?? Item, this.variables);
            }
            else
            {
                this.properties.Object = Element?.AssociatedObjectValue ?? Item;
            }

            if (this.columns is null)
            {
                this.record = new IElement[1] {
                    Element ?? Expression.Encapsulate(Item)
                }
            }
            ;
            else
            {
                this.record = new IElement[this.count];

                for (i = 0; i < this.count; i++)
                {
                    try
                    {
                        this.record[i] = this.columns[i].Evaluate(this.properties);
                    }
                    catch (Exception ex)
                    {
                        ex             = Log.UnnestException(ex);
                        this.record[i] = Expression.Encapsulate(ex);
                    }
                }
            }

            return(true);
        }
示例#2
0
        /// <summary>
        /// Advances the enumerator to the next element of the collection.
        /// </summary>
        /// <returns>true if the enumerator was successfully advanced to the next element; false if
        /// the enumerator has passed the end of the collection.</returns>
        /// <exception cref="InvalidOperationException">The collection was modified after the enumerator was created.</exception>
        public async Task <bool> MoveNextAsync()
        {
            if (!await this.e.MoveNextAsync())
            {
                return(false);
            }

            this.current = this.e.Current;

            if (this.objectVariables is null)
            {
                this.objectVariables = new ObjectProperties(this.current, this.variables);
            }
            else
            {
                this.objectVariables.Object = e.Current;
            }

            if (this.current is GenericObject GenObj)
            {
                foreach (KeyValuePair <string, ScriptNode> P in this.additionalFields)
                {
                    GenObj[P.Key] = P.Value.Evaluate(this.objectVariables);
                }
            }
            else if (this.current is GroupObject GroupObj)
            {
                foreach (KeyValuePair <string, ScriptNode> P in this.additionalFields)
                {
                    GroupObj[P.Key] = P.Value.Evaluate(this.objectVariables);
                }
            }
            else
            {
                GroupObject Obj = new GroupObject(new object[] { this.current }, new object[0], new ScriptNode[0], this.objectVariables);

                foreach (KeyValuePair <string, ScriptNode> P in this.additionalFields)
                {
                    Obj[P.Key] = P.Value.Evaluate(this.objectVariables);
                }

                this.current = Obj;
            }

            return(true);
        }
示例#3
0
        private bool MatchesCondition()
        {
            try
            {
                ObjectProperties Properties = new ObjectProperties(this.e.Current, this.variables);

                IElement E = this.conditions.Evaluate(Properties);
                if (!(E is BooleanValue B) || !B.Value)
                {
                    return(false);
                }

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
示例#4
0
        /// <summary>
        /// <see cref="IEnumerator.MoveNext"/>
        /// </summary>
        public bool MoveNext()
        {
            while (e.MoveNext())
            {
                try
                {
                    ObjectProperties Properties = new ObjectProperties(e.Current, this.variables);

                    IElement E = this.conditions.Evaluate(Properties);
                    if (!(E is BooleanValue B) || !B.Value)
                    {
                        continue;
                    }

                    return(true);
                }
                catch (Exception)
                {
                    continue;
                }
            }

            return(false);
        }
示例#5
0
        /// <summary>
        /// Evaluates the node, using the variables provided in the <paramref name="Variables"/> collection.
        /// </summary>
        /// <param name="Variables">Variables collection.</param>
        /// <returns>Result.</returns>
        public override IElement Evaluate(Variables Variables)
        {
            IElement E;
            int      Top;
            int      Offset;
            int      i, c;

            if (this.top != null)
            {
                E   = this.top.Evaluate(Variables);
                Top = (int)Expression.ToDouble(E.AssociatedObjectValue);
                if (Top <= 0)
                {
                    throw new ScriptRuntimeException("TOP must evaluate to a positive integer.", this.top);
                }
            }
            else
            {
                Top = int.MaxValue;
            }

            if (this.offset != null)
            {
                E      = this.offset.Evaluate(Variables);
                Offset = (int)Expression.ToDouble(E.AssociatedObjectValue);
                if (Offset < 0)
                {
                    throw new ScriptRuntimeException("OFFSET must evaluate to a non-negative integer.", this.offset);
                }
            }
            else
            {
                Offset = 0;
            }

            c = this.sources.Length;
            if (c != 1)
            {
                throw new ScriptRuntimeException("Joinds between multiple sources not supported.", this);
            }

            E = this.sources[0].Evaluate(Variables);
            if (!(E.AssociatedObjectValue is Type T))
            {
                throw new ScriptRuntimeException("Type expected.", this.sources[0]);
            }

            List <string> OrderBy         = new List <string>();
            bool          CalculatedOrder = false;

            if (this.orderBy != null)
            {
                foreach (KeyValuePair <ScriptNode, bool> Node in this.orderBy)
                {
                    if (Node.Key is VariableReference Ref)
                    {
                        if (Node.Value)
                        {
                            OrderBy.Add(Ref.VariableName);
                        }
                        else
                        {
                            OrderBy.Add("-" + Ref.VariableName);
                        }
                    }
                    else
                    {
                        CalculatedOrder = true;
                    }
                }
            }

            if (this.groupBy != null)
            {
                foreach (ScriptNode Node in this.groupBy)
                {
                    if (Node is VariableReference Ref)
                    {
                        if (!OrderBy.Contains(Ref.VariableName))
                        {
                            OrderBy.Add(Ref.VariableName);
                        }
                    }
                    else
                    {
                        CalculatedOrder = true;
                    }
                }
            }

            bool ManualPaging = this.groupBy != null || this.where != null;
            bool ManualTop    = Top != int.MaxValue && ManualPaging;
            bool ManualOffset = Offset != 0 && ManualPaging;

            IEnumerator              e       = Find(T, ManualOffset ? 0 : Offset, ManualTop ? int.MaxValue : Top, this.where, Variables, OrderBy.ToArray(), this);
            LinkedList <IElement[]>  Items   = new LinkedList <IElement[]>();
            Dictionary <string, int> Columns = new Dictionary <string, int>();

            IElement[] Rec;
            int        NrRecords = 0;

            if (this.columns != null)
            {
                c = this.columns.Length;
                for (i = 0; i < c; i++)
                {
                    if (this.columns[i] is VariableReference Ref)
                    {
                        Columns[Ref.VariableName] = i;
                    }
                }
            }
            else
            {
                c = 0;
            }

            if (this.where != null)
            {
                e = new ConditionalEnumerator(e, Variables, this.where);
            }

            if (this.groupBy != null)
            {
                e = new GroupEnumerator(e, Variables, this.groupBy, this.groupByNames);

                if (this.having != null)
                {
                    e = new ConditionalEnumerator(e, Variables, this.having);
                }
            }

            if (CalculatedOrder)
            {
                List <KeyValuePair <ScriptNode, bool> > Order = new List <KeyValuePair <ScriptNode, bool> >();

                if (this.orderBy != null)
                {
                    Order.AddRange(this.orderBy);
                }

                if (this.groupByNames != null)
                {
                    foreach (ScriptNode Group in this.groupByNames)
                    {
                        if (Group != null)
                        {
                            Order.Add(new KeyValuePair <ScriptNode, bool>(Group, true));
                        }
                    }
                }

                e = new CustomOrderEnumerator(e, Variables, Order.ToArray());
            }

            while (e.MoveNext())
            {
                if (ManualOffset && Offset > 0)
                {
                    Offset--;
                    continue;
                }

                object           Item       = e.Current;
                ObjectProperties Properties = new ObjectProperties(Item, Variables);

                if (this.columns is null)
                {
                    Rec = new IElement[1] {
                        Expression.Encapsulate(Item)
                    }
                }
                ;
                else
                {
                    Rec = new IElement[c];

                    for (i = 0; i < c; i++)
                    {
                        try
                        {
                            Rec[i] = this.columns[i].Evaluate(Properties);
                        }
                        catch (Exception ex)
                        {
                            ex     = Log.UnnestException(ex);
                            Rec[i] = Expression.Encapsulate(ex);
                        }
                    }
                }

                Items.AddLast(Rec);
                NrRecords++;

                if (ManualTop && NrRecords >= Top)
                {
                    break;
                }
            }

            IElement[] Elements = new IElement[this.columns is null ? NrRecords : NrRecords * c];
        /// <summary>
        /// Enumerator that reorders a sequence of items.
        /// </summary>
        /// <param name="ItemEnumerator">Item enumerator</param>
        /// <param name="Variables">Current set of variables.</param>
        /// <param name="Order">Custom order.</param>
        public CustomOrderEnumerator(IEnumerator ItemEnumerator, Variables Variables, KeyValuePair <ScriptNode, bool>[] Order)
        {
            this.variables = Variables;
            this.order     = Order;

            List <object> Items = new List <object>();

            while (ItemEnumerator.MoveNext())
            {
                Items.Add(ItemEnumerator.Current);
            }

            Dictionary <Type, ObjectProperties> PropertiesX = new Dictionary <Type, ObjectProperties>();
            Dictionary <Type, ObjectProperties> PropertiesY = new Dictionary <Type, ObjectProperties>();

            Items.Sort((x, y) =>
            {
                if (x is null)
                {
                    if (y is null)
                    {
                        return(0);
                    }
                    else
                    {
                        return(-1);
                    }
                }
                else if (y is null)
                {
                    return(1);
                }

                Type Tx = x.GetType();
                Type Ty = y.GetType();

                if (PropertiesX.TryGetValue(Tx, out ObjectProperties Vx))
                {
                    Vx.Object = x;
                }
                else
                {
                    Vx = new ObjectProperties(x, Variables);
                    PropertiesX[Tx] = Vx;
                }

                if (PropertiesY.TryGetValue(Ty, out ObjectProperties Vy))
                {
                    Vy.Object = y;
                }
                else
                {
                    Vy = new ObjectProperties(y, Variables);
                    PropertiesY[Ty] = Vy;
                }

                int i, j, c = this.order.Length;
                IElement Ex, Ey;
                ScriptNode Node;

                for (i = 0; i < c; i++)
                {
                    Node = this.order[i].Key;
                    Ex   = Node.Evaluate(Vx);
                    Ey   = Node.Evaluate(Vy);

                    if (!(Ex.AssociatedSet is IOrderedSet S))
                    {
                        throw new ScriptRuntimeException("Result not member of an ordered set.", Node);
                    }

                    j = S.Compare(Ex, Ey);
                    if (j != 0)
                    {
                        if (this.order[i].Value)
                        {
                            return(j);
                        }
                        else
                        {
                            return(-j);
                        }
                    }
                }

                return(0);
            });

            this.e = Items.GetEnumerator();
        }
示例#7
0
        /// <summary>
        /// Advances the enumerator to the next element of the collection.
        /// </summary>
        /// <returns>true if the enumerator was successfully advanced to the next element; false if
        /// the enumerator has passed the end of the collection.</returns>
        /// <exception cref="InvalidOperationException">The collection was modified after the enumerator was created.</exception>
        public async Task <bool> MoveNextAsync()
        {
            Dictionary <string, List <object> > Aggregated = null;
            ObjectProperties Variables = null;
            IElement         E;

            object[] Last = null;
            int      i, c = this.groupBy.Length;
            object   o1, o2;

            while (this.processLast || await e.MoveNextAsync())
            {
                this.processLast = false;

                Variables = new ObjectProperties(e.Current, this.variables);

                if (Last is null)
                {
                    Last = new object[c];

                    for (i = 0; i < c; i++)
                    {
                        E       = this.groupBy[i].Evaluate(Variables);
                        Last[i] = E.AssociatedObjectValue;
                    }
                }
                else
                {
                    for (i = 0; i < c; i++)
                    {
                        E = this.groupBy[i].Evaluate(Variables);

                        o1 = Last[i];
                        o2 = E.AssociatedObjectValue;

                        if (o1 is null ^ o2 is null)
                        {
                            break;
                        }

                        if (o1 != null && !o1.Equals(o2))
                        {
                            break;
                        }
                    }

                    if (i < c)
                    {
                        this.processLast = true;
                        break;
                    }
                }

                o1 = e.Current;

                Type T = o1.GetType();
                if (T != this.lastType)
                {
                    this.lastType   = T;
                    this.properties = T.GetRuntimeProperties();
                    this.fields     = T.GetRuntimeFields();
                }

                if (Aggregated is null)
                {
                    Aggregated = new Dictionary <string, List <object> >();
                }

                foreach (PropertyInfo PI in this.properties)
                {
                    if (!PI.CanRead || !PI.CanWrite)
                    {
                        continue;
                    }

                    if (!Aggregated.TryGetValue(PI.Name, out List <object> List))
                    {
                        List = new List <object>();
                        Aggregated[PI.Name] = List;
                    }

                    List.Add(PI.GetValue(o1));
                }

                foreach (FieldInfo FI in this.fields)
                {
                    if (!Aggregated.TryGetValue(FI.Name, out List <object> List))
                    {
                        List = new List <object>();
                        Aggregated[FI.Name] = List;
                    }

                    List.Add(FI.GetValue(o1));
                }
            }

            if (Aggregated is null)
            {
                return(false);
            }

            Dictionary <string, object> Result = new Dictionary <string, object>();
            bool First = true;

            foreach (KeyValuePair <string, List <object> > Rec in Aggregated)
            {
                object[] A = Rec.Value.ToArray();
                Result[Rec.Key] = A;

                if (First)
                {
                    First             = false;
                    Result[" First "] = A;
                }
            }

            if (this.groupNames != null)
            {
                for (i = 0; i < c; i++)
                {
                    ScriptNode Node = this.groupNames[i];
                    if (Node is null)
                    {
                        continue;
                    }

                    if (Node is VariableReference Ref)
                    {
                        Result[Ref.VariableName] = Last[i];
                    }
                    else
                    {
                        E = this.groupNames[i]?.Evaluate(Variables);
                        if (E != null && E is StringValue S)
                        {
                            Result[S.Value] = Last[i];
                        }
                    }
                }
            }

            this.current = Result;

            return(true);
        }
示例#8
0
        /// <summary>
        /// <see cref="IEnumerator.MoveNext"/>
        /// </summary>
        public async Task <bool> MoveNextAsync()
        {
            if (this.e is null)
            {
                List <object> Items = new List <object>();

                while (await this.items.MoveNextAsync())
                {
                    Items.Add(this.items.Current);
                }

                Items.Sort((x, y) =>
                {
                    if (x is null)
                    {
                        if (y is null)
                        {
                            return(0);
                        }
                        else
                        {
                            return(-1);
                        }
                    }
                    else if (y is null)
                    {
                        return(1);
                    }

                    Type Tx = x.GetType();
                    Type Ty = y.GetType();

                    if (this.propertiesX.TryGetValue(Tx, out ObjectProperties Vx))
                    {
                        Vx.Object = x;
                    }
                    else
                    {
                        Vx = new ObjectProperties(x, this.variables);
                        this.propertiesX[Tx] = Vx;
                    }

                    if (this.propertiesY.TryGetValue(Ty, out ObjectProperties Vy))
                    {
                        Vy.Object = y;
                    }
                    else
                    {
                        Vy = new ObjectProperties(y, this.variables);
                        this.propertiesY[Ty] = Vy;
                    }

                    int i, j, c = this.order.Length;
                    IElement Ex, Ey;
                    ScriptNode Node;

                    for (i = 0; i < c; i++)
                    {
                        Node = this.order[i].Key;
                        Ex   = Node.Evaluate(Vx);
                        Ey   = Node.Evaluate(Vy);

                        if (!(Ex.AssociatedSet is IOrderedSet S))
                        {
                            throw new ScriptRuntimeException("Result not member of an ordered set.", Node);
                        }

                        j = S.Compare(Ex, Ey);
                        if (j != 0)
                        {
                            if (this.order[i].Value)
                            {
                                return(j);
                            }
                            else
                            {
                                return(-j);
                            }
                        }
                    }

                    return(0);
                });

                this.e = Items.GetEnumerator();
            }

            return(this.e.MoveNext());
        }