示例#1
0
        /// <summary>
        /// Executes this operation
        /// </summary>
        /// <param name="rows">The pre-sorted rows.</param>
        /// <returns></returns>
        public override IEnumerable <Row> Execute(IEnumerable <Row> rows)
        {
            ObjectArrayKeys previousKey = null;
            var             aggregate   = new Row();
            var             groupBy     = GetColumnsToGroupBy();

            foreach (var row in rows)
            {
                var key = row.CreateKey(groupBy);

                if (previousKey != null && !previousKey.Equals(key))
                {
                    FinishAggregation(aggregate);
                    yield return(aggregate);

                    aggregate = new Row();
                }

                Accumulate(row, aggregate);
                previousKey = key;
            }

            FinishAggregation(aggregate);
            yield return(aggregate);
        }
        /// <summary>
        /// Executes this operation
        /// </summary>
        /// <param name="rows">The pre-sorted rows.</param>
        /// <param name="cancellationToken">A CancellationToken to stop execution</param>
        /// <returns></returns>
        public override IAsyncEnumerable <Row> Execute(IAsyncEnumerable <Row> rows, CancellationToken cancellationToken = default)
        {
            return(new AsyncEnumerable <Row>(async yield => {
                ObjectArrayKeys previousKey = null;
                var aggregate = new Row();
                var groupBy = GetColumnsToGroupBy();

                await rows.ForEachAsync(async row =>
                {
                    var key = row.CreateKey(groupBy);

                    if (previousKey != null && !previousKey.Equals(key))
                    {
                        FinishAggregation(aggregate);
                        await yield.ReturnAsync(aggregate);
                        aggregate = new Row();
                    }

                    Accumulate(row, aggregate);
                    previousKey = key;
                }, cancellationToken);

                FinishAggregation(aggregate);
                await yield.ReturnAsync(aggregate);
            }));
        }
示例#3
0
        /// <summary>
        /// Executes this operation
        /// </summary>
        /// <param name="rows">Rows in pipeline. These are only used if a left part of the join was not specified.</param>
        /// <param name="cancellationToken">A CancellationToken to stop execution</param>
        /// <returns></returns>
        public override IAsyncEnumerable <Row> Execute(IAsyncEnumerable <Row> rows, CancellationToken cancellationToken = default)
        {
            return(new AsyncEnumerable <Row>(async yield => {
                PrepareForJoin();

                SetupJoinConditions();
                Guard.Against(leftColumns == null, "You must setup the left columns");
                Guard.Against(rightColumns == null, "You must setup the right columns");

                IAsyncEnumerable <Row> rightEnumerable = await GetRightEnumerable(cancellationToken);

                IAsyncEnumerable <Row> execute = left.Execute(leftRegistered ? null : rows, cancellationToken);
                await new EventRaisingEnumerator(left, execute)
                .ForEachAsync(async leftRow =>
                {
                    ObjectArrayKeys key = leftRow.CreateKey(leftColumns);
                    List <Row> rightRows;
                    if (this.rightRowsByJoinKey.TryGetValue(key, out rightRows))
                    {
                        foreach (Row rightRow in rightRows)
                        {
                            rightRowsWereMatched[rightRow] = null;
                            await yield.ReturnAsync(MergeRows(leftRow, rightRow));
                        }
                    }
                    else if ((jointype & JoinType.Left) != 0)
                    {
                        Row emptyRow = new Row();
                        await yield.ReturnAsync(MergeRows(leftRow, emptyRow));
                    }
                    else
                    {
                        LeftOrphanRow(leftRow);
                    }
                }, cancellationToken);

                await rightEnumerable.ForEachAsync(async rightRow =>
                {
                    if (rightRowsWereMatched.ContainsKey(rightRow))
                    {
                        return;
                    }
                    Row emptyRow = new Row();
                    if ((jointype & JoinType.Right) != 0)
                    {
                        await yield.ReturnAsync(MergeRows(emptyRow, rightRow));
                    }
                    else
                    {
                        RightOrphanRow(rightRow);
                    }
                }, cancellationToken);
            }));
        }
示例#4
0
        /// <summary>
        /// Executes this operation
        /// </summary>
        /// <param name="rows">Rows in pipeline. These are only used if a left part of the join was not specified.</param>
        /// <returns></returns>
        public override IEnumerable <Row> Execute(IEnumerable <Row> rows)
        {
            PrepareForJoin();

            SetupJoinConditions();
            Guard.Against(leftColumns == null, "You must setup the left columns");
            Guard.Against(rightColumns == null, "You must setup the right columns");

            IEnumerable <Row> rightEnumerable = GetRightEnumerable();

            IEnumerable <Row> execute = left.Execute(leftRegistered ? null : rows);

            foreach (Row leftRow in new EventRaisingEnumerator(left, execute))
            {
                ObjectArrayKeys key = leftRow.CreateKey(leftColumns);
                List <Row>      rightRows;
                if (this.rightRowsByJoinKey.TryGetValue(key, out rightRows))
                {
                    foreach (Row rightRow in rightRows)
                    {
                        rightRowsWereMatched[rightRow] = null;
                        yield return(MergeRows(leftRow, rightRow));
                    }
                }
                else if ((jointype & JoinType.Left) != 0)
                {
                    Row emptyRow = new Row();
                    yield return(MergeRows(leftRow, emptyRow));
                }
                else
                {
                    LeftOrphanRow(leftRow);
                }
            }
            foreach (Row rightRow in rightEnumerable)
            {
                if (rightRowsWereMatched.ContainsKey(rightRow))
                {
                    continue;
                }
                Row emptyRow = new Row();
                if ((jointype & JoinType.Right) != 0)
                {
                    yield return(MergeRows(emptyRow, rightRow));
                }
                else
                {
                    RightOrphanRow(rightRow);
                }
            }
        }
        /// <summary>
        /// Executes this operation
        /// </summary>
        /// <param name="ignored">Ignored rows</param>
        /// <returns></returns>
        public override IEnumerable <FdoRow> Execute(IEnumerable <FdoRow> ignored)
        {
            PrepareForJoin();

            IEnumerable <FdoRow> rightEnumerable = GetRightEnumerable();

            IEnumerable <FdoRow> execute = left.Execute(null);

            foreach (FdoRow leftRow in new EventRaisingEnumerator(left, execute))
            {
                ObjectArrayKeys key = leftRow.CreateKey(leftColumns);
                List <FdoRow>   rightRows;
                if (this.rightRowsByJoinKey.TryGetValue(key, out rightRows))
                {
                    foreach (FdoRow rightRow in rightRows)
                    {
                        rightRowsWereMatched[rightRow] = null;
                        yield return(MergeRows(leftRow, rightRow));
                    }
                }
                else if ((jointype & JoinType.Left) != 0)
                {
                    FdoRow emptyRow = new FdoRow();
                    yield return(MergeRows(leftRow, emptyRow));
                }
                else
                {
                    LeftOrphanRow(leftRow);
                }
            }
            foreach (FdoRow rightRow in rightEnumerable)
            {
                if (rightRowsWereMatched.ContainsKey(rightRow))
                {
                    continue;
                }
                FdoRow emptyRow = new FdoRow();
                if ((jointype & JoinType.Right) != 0)
                {
                    yield return(MergeRows(emptyRow, rightRow));
                }
                else
                {
                    RightOrphanRow(rightRow);
                }
            }
        }
        private IEnumerable <FdoRow> GetRightEnumerable()
        {
            IEnumerable <FdoRow> rightEnumerable = new CachingEnumerable <FdoRow>(
                new EventRaisingEnumerator(right, right.Execute(null))
                );

            foreach (FdoRow row in rightEnumerable)
            {
                ObjectArrayKeys key = row.CreateKey(rightColumns);
                List <FdoRow>   rowsForKey;
                if (this.rightRowsByJoinKey.TryGetValue(key, out rowsForKey) == false)
                {
                    this.rightRowsByJoinKey[key] = rowsForKey = new List <FdoRow>();
                }
                rowsForKey.Add(row);
            }
            return(rightEnumerable);
        }
示例#7
0
        private async Task <IAsyncEnumerable <Row> > GetRightEnumerable(CancellationToken cancellationToken = default)
        {
            IAsyncEnumerable <Row> rightEnumerable = new CachingEnumerable <Row>(new EventRaisingEnumerator(right, right.Execute(null, cancellationToken)),
                                                                                 cancellationToken);
            await rightEnumerable.ForEachAsync(row =>
            {
                ObjectArrayKeys key = row.CreateKey(rightColumns);
                List <Row> rowsForKey;
                if (this.rightRowsByJoinKey.TryGetValue(key, out rowsForKey) == false)
                {
                    this.rightRowsByJoinKey[key] = rowsForKey = new List <Row>();
                }

                rowsForKey.Add(row);
            }, cancellationToken);

            return(rightEnumerable);
        }
示例#8
0
        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
        /// </returns>
        /// <exception cref="T:System.NullReferenceException">The <paramref name="obj"/> parameter is null.</exception>
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return(true);
            }
            ObjectArrayKeys other = obj as ObjectArrayKeys;

            if (other == null || other.columnValues.Length != this.columnValues.Length)
            {
                return(false);
            }
            for (int i = 0; i < columnValues.Length; i++)
            {
                if (Equals(this.columnValues[i], other.columnValues[i]) == false)
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// Executes this operation
        /// </summary>
        /// <param name="rows">The rows.</param>
        /// <returns></returns>
        public override IEnumerable <Row> Execute(IEnumerable <Row> rows)
        {
            IDictionary <ObjectArrayKeys, Row> aggregations = new Dictionary <ObjectArrayKeys, Row>();

            string[] groupBy = GetColumnsToGroupBy();
            foreach (Row row in rows)
            {
                ObjectArrayKeys key = row.CreateKey(groupBy);
                Row             aggregate;
                if (aggregations.TryGetValue(key, out aggregate) == false)
                {
                    aggregations[key] = aggregate = new Row();
                }
                Accumulate(row, aggregate);
            }
            foreach (Row row in aggregations.Values)
            {
                FinishAggregation(row);
                yield return(row);
            }
        }
        /// <summary>
        /// Executes this operation
        /// </summary>
        /// <param name="rows">The rows.</param>
        /// <param name="cancellationToken">A CancellationToken to stop execution</param>
        /// <returns></returns>
        public override IAsyncEnumerable <Row> Execute(IAsyncEnumerable <Row> rows, CancellationToken cancellationToken = default)
        {
            return(new AsyncEnumerable <Row>(async yield => {
                IDictionary <ObjectArrayKeys, Row> aggregations = new Dictionary <ObjectArrayKeys, Row>();
                string[] groupBy = GetColumnsToGroupBy();
                await rows.ForEachAsync(row =>
                {
                    ObjectArrayKeys key = row.CreateKey(groupBy);
                    Row aggregate;
                    if (aggregations.TryGetValue(key, out aggregate) == false)
                    {
                        aggregations[key] = aggregate = new Row();
                    }
                    Accumulate(row, aggregate);

                    return Task.CompletedTask;
                }, cancellationToken);
                foreach (Row row in aggregations.Values)
                {
                    FinishAggregation(row);
                    await yield.ReturnAsync(row);
                }
            }));
        }