protected override async Task <ReturnValue <object[]> > ReadRecord(CancellationToken cancellationToken)
        {
            try
            {
                if (await ReferenceTransform.ReadAsync(cancellationToken) == false)
                {
                    return(new ReturnValue <object[]>(false, null));
                }
                else
                {
                    List <Filter> filters = new List <Filter>();

                    foreach (JoinPair join in JoinPairs)
                    {
                        var joinValue = join.JoinColumn == null ? join.JoinValue : ReferenceTransform[join.JoinColumn].ToString();

                        filters.Add(new Filter()
                        {
                            Column1         = join.SourceColumn,
                            CompareDataType = ETypeCode.String,
                            Operator        = Filter.ECompare.IsEqual,
                            Value2          = joinValue
                        });
                    }

                    var result = await LookupRow(filters, cancellationToken);

                    return(result);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("The restful service failed due to the following error: " + ex.Message, ex);
            }
        }
        protected override async Task <object[]> ReadRecord(CancellationToken cancellationToken)
        {
            try
            {
                if (!_isOpen)
                {
                    throw new ConnectionException($"The web service is not open");
                }

                if (_cachedRows == null && await ReferenceTransform.ReadAsync(cancellationToken) == false)
                {
                    return(null);
                }

                if (_cachedRows != null)
                {
                    if (!_cachedRows.MoveNext())
                    {
                        _cachedRows = null;
                        if (await ReferenceTransform.ReadAsync(cancellationToken) == false)
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        var row = _cachedRows.Current;
                        return(row);
                    }
                }

                var rows = await((ConnectionRestful)ReferenceConnection).LookupRow(CacheTable, _filter, cancellationToken);
                if (rows != null && rows.Any())
                {
                    _cachedRows = rows.GetEnumerator();
                    _cachedRows.MoveNext();

                    return(_cachedRows.Current);
                }

                return(null);
            }
            catch (Exception ex)
            {
                throw new ConnectionException($"Read web service record failed. {ex.Message}", ex);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Reads the next group of rows (based on join key) from the reference transform.
        /// </summary>
        /// <returns></returns>
        private async Task <bool> ReadNextGroup()
        {
            _groupData = new List <object[]>();

            if (_joinReaderOpen)
            {
                _groupData.Add(ReferenceTransform.CurrentRow);
            }

            while (_joinReaderOpen)
            {
                // if no joins, then the whole reference table is the group
                if (_joinColumns == null)
                {
                    _joinReaderOpen = await ReferenceTransform.ReadAsync();

                    _groupFields = new object[0];
                    if (!_joinReaderOpen)
                    {
                        break;
                    }

                    _groupData.Add(ReferenceTransform.CurrentRow);
                }
                else
                {
                    _groupFields = new object[_joinColumns.Length];
                    for (var i = 0; i < _groupFields.Length; i++)
                    {
                        _groupFields[i] = ReferenceTransform[_joinKeyOrdinals[i]];
                    }

                    _joinReaderOpen = await ReferenceTransform.ReadAsync();

                    if (!_joinReaderOpen)
                    {
                        break;
                    }

                    var duplicateCheck = true;
                    for (var i = 0; i < _joinColumns.Length; i++)
                    {
                        if (!Equals(_groupFields[i], ReferenceTransform[_joinKeyOrdinals[i]]))
                        {
                            duplicateCheck = false;
                            break;
                        }
                    }

                    if (duplicateCheck)
                    {
                        _groupData.Add(ReferenceTransform.CurrentRow);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(_groupData.Count > 0);
        }
Beispiel #4
0
        protected override async Task <object[]> ReadRecord(CancellationToken cancellationToken)
        {
            // sorted merge will concatenate 2 sorted incoming datasets, and maintain the sort order.
            if (_sortedMerge)
            {
                if (_firstRead)
                {
                    // read one row for each reader.
                    var primaryReadTask   = PrimaryTransform.ReadAsync(cancellationToken);
                    var referenceReadTask = ReferenceTransform.ReadAsync(cancellationToken);
                    await Task.WhenAll(primaryReadTask, referenceReadTask);

                    if (primaryReadTask.IsFaulted)
                    {
                        throw primaryReadTask.Exception;
                    }

                    if (referenceReadTask.IsFaulted)
                    {
                        throw referenceReadTask.Exception;
                    }

                    _primaryMoreRecords   = primaryReadTask.Result;
                    _referenceMoreRecords = referenceReadTask.Result;

                    _firstRead = false;
                }

                if (_primaryReadTask != null)
                {
                    _primaryMoreRecords = await _primaryReadTask;
                }

                if (_referenceReadTask != null)
                {
                    _referenceMoreRecords = await _referenceReadTask;
                }

                if (!_primaryMoreRecords && !_referenceMoreRecords)
                {
                    return(null);
                }

                var newRow = new object[FieldCount];

                // no more primary records, then just read from the reference
                if (!_primaryMoreRecords)
                {
                    var returnValue = CreateRecord(ReferenceTransform, _referenceMappings);
                    _primaryReadTask   = null;
                    _referenceReadTask = ReferenceTransform.ReadAsync(cancellationToken);
                    return(returnValue);
                }
                // no more reference record ,just read from the primary.
                else if (!_referenceMoreRecords)
                {
                    var returnValue = CreateRecord(PrimaryTransform, _primaryMappings);
                    PrimaryTransform.GetValues(newRow);
                    _referenceReadTask = null;
                    _primaryReadTask   = ReferenceTransform.ReadAsync(cancellationToken);
                    return(returnValue);
                }
                else
                {
                    //more records in both, then compare the rows and take the next in sort order.

                    var usePrimary = true;

                    for (var i = 0; i < _primarySortOrdinals.Count; i++)
                    {
                        var compareResult = Dexih.Utils.DataType.DataType.Compare(
                            PrimaryTransform.CacheTable.Columns[_primarySortOrdinals[i]].DataType,
                            PrimaryTransform[_primarySortOrdinals[i]], ReferenceTransform[_referenceSortOrdinals[i]]);

                        if ((compareResult == DataType.ECompareResult.Greater &&
                             SortFields[i].Direction == Sort.EDirection.Ascending) ||
                            (compareResult == DataType.ECompareResult.Less &&
                             SortFields[i].Direction == Sort.EDirection.Descending))
                        {
                            usePrimary = false;
                            break;
                        }
                    }

                    if (usePrimary)
                    {
                        var returnValue = CreateRecord(PrimaryTransform, _primaryMappings);
                        _primaryReadTask = PrimaryTransform.ReadAsync(cancellationToken);
                        return(returnValue);
                    }
                    else
                    {
                        var returnValue = CreateRecord(ReferenceTransform, _referenceMappings);
                        _referenceReadTask = ReferenceTransform.ReadAsync(cancellationToken);
                        return(returnValue);
                    }
                }
            }
            else
            {
                // if no sorting specified, concatenate will be in any order as the records arrive.
                if (_firstRead)
                {
                    _primaryReadTask   = PrimaryTransform.ReadAsync(cancellationToken);
                    _referenceReadTask = ReferenceTransform.ReadAsync(cancellationToken);
                    _firstRead         = false;
                }

                if (_primaryReadTask != null && _referenceReadTask != null)
                {
                    await Task.WhenAny(_primaryReadTask, _referenceReadTask);

                    if (_primaryReadTask.IsCanceled || _referenceReadTask.IsCanceled ||
                        cancellationToken.IsCancellationRequested)
                    {
                        throw new OperationCanceledException("The read record task was cancelled");
                    }

                    if (_primaryReadTask.IsFaulted)
                    {
                        throw _primaryReadTask.Exception;
                    }

                    if (_referenceReadTask.IsFaulted)
                    {
                        throw _referenceReadTask.Exception;
                    }

                    if (_primaryReadTask.IsCompleted)
                    {
                        var result = _primaryReadTask.Result;
                        if (result)
                        {
                            var returnValue = CreateRecord(PrimaryTransform, _primaryMappings);
                            _primaryReadTask = PrimaryTransform.ReadAsync(cancellationToken);
                            return(returnValue);
                        }
                        _primaryReadTask = null;
                    }

                    if (_referenceReadTask.IsCompleted)
                    {
                        var result = _referenceReadTask.Result;
                        if (result)
                        {
                            var returnValue = CreateRecord(ReferenceTransform, _referenceMappings);
                            _referenceReadTask = ReferenceTransform.ReadAsync(cancellationToken);
                            return(returnValue);
                        }
                        _primaryReadTask = null;
                    }
                }

                if (_primaryReadTask != null)
                {
                    var result = await _primaryReadTask;
                    if (result)
                    {
                        var returnValue = CreateRecord(PrimaryTransform, _primaryMappings);
                        _primaryReadTask = PrimaryTransform.ReadAsync(cancellationToken);
                        return(returnValue);
                    }
                    _primaryReadTask = null;
                }

                if (_referenceReadTask != null)
                {
                    var result = await _referenceReadTask;
                    if (result)
                    {
                        var returnValue = CreateRecord(ReferenceTransform, _referenceMappings);
                        _referenceReadTask = ReferenceTransform.ReadAsync(cancellationToken);
                        return(returnValue);
                    }
                    _referenceReadTask = null;
                }
            }

            return(null);
        }
Beispiel #5
0
        protected override async Task <object[]> ReadRecord(CancellationToken cancellationToken)
        {
            object[] newRow = null;
            var      pos    = 0;

            //this writes out duplicates of the primary reader when a duplicate match occurrs on the join table
            //i.e. outer join.
            if (_writeGroup)
            {
                //create a new row and write the primary fields out
                newRow = new object[FieldCount];
                for (var i = 0; i < _primaryFieldCount; i++)
                {
                    newRow[pos] = PrimaryTransform[i];
                    pos++;
                }

                var joinRow = _filterdGroupData[_writeGroupPosition];

                for (var i = 0; i < _referenceFieldCount; i++)
                {
                    newRow[pos] = joinRow[i];
                    pos++;
                }

                _writeGroupPosition++;

                //if last join record, then set the flag=false so the next read will read another primary row record.
                if (_writeGroupPosition >= _filterdGroupData.Count)
                {
                    _writeGroup = false;
                }

                return(newRow);
            }

            //read a new row from the primary table.
            if (await PrimaryTransform.ReadAsync(cancellationToken) == false)
            {
                return(null);
            }

            var joinMatchFound = false;

            //if input is sorted, then run a sortedjoin
            if (JoinAlgorithm == EJoinAlgorithm.Sorted)
            {
                //first read get a row from the join table.
                if (_firstRead)
                {
                    //get the first two rows from the join table.
                    _joinReaderOpen = await ReferenceTransform.ReadAsync(cancellationToken);

                    _groupsOpen = await ReadNextGroup();

                    _firstRead = false;
                }

                //loop through join table until we find a matching row.
                if (_joinColumns != null)
                {
                    while (_groupsOpen)
                    {
                        var joinFields = new object[_joinColumns.Length];
                        for (var i = 0; i < _joinColumns.Length; i++)
                        {
                            joinFields[i] = _joinColumns[i].SourceColumn == null ? _joinColumns[i].JoinValue : PrimaryTransform[_sourceKeyOrdinals[i]];
                        }

                        var compare = _joinKeyComparer.Compare(_groupFields, joinFields);
                        var done    = false;

                        switch (compare)
                        {
                        case 1:
                            joinMatchFound = false;
                            done           = true;
                            break;

                        case -1:
                            if (_groupsOpen)
                            {
                                _groupsOpen = await ReadNextGroup();
                            }

                            break;

                        case 0:
                            joinMatchFound = true;
                            done           = true;
                            break;
                        }

                        if (done)
                        {
                            break;
                        }
                    }
                }
            }
            else //if input is not sorted, then run a hash join.
            {
                //first read load the join table into memory
                if (_firstRead)
                {
                    _joinHashData   = new SortedDictionary <object[], List <object[]> >(new JoinKeyComparer());
                    _joinReaderOpen = await ReferenceTransform.ReadAsync(cancellationToken);

                    _groupsOpen = await ReadNextGroup();

                    //load all the join data into an a dictionary
                    while (_groupsOpen)
                    {
                        _joinHashData.Add(_groupFields, _groupData);
                        _groupsOpen = await ReadNextGroup();
                    }

                    _firstRead = false;
                }

                object[] sourceKeys;

                //set the values for the lookup
                if (_joinColumns != null)
                {
                    sourceKeys = new object[_joinColumns.Length];
                    for (var i = 0; i < _joinColumns.Length; i++)
                    {
                        sourceKeys[i] = _joinColumns[i].SourceColumn == null ? _joinColumns[i].JoinValue : PrimaryTransform[_sourceKeyOrdinals[i]];
                    }
                }
                else
                {
                    sourceKeys = new object[0];
                }

                if (_joinHashData.Keys.Contains(sourceKeys))
                {
                    _groupData     = _joinHashData[sourceKeys];
                    _groupsOpen    = true;
                    joinMatchFound = true;
                }
                else
                {
                    joinMatchFound = false;
                }
            }

            //create a new row and write the primary fields out
            newRow = new object[FieldCount];
            for (var i = 0; i < _primaryFieldCount; i++)
            {
                newRow[pos] = PrimaryTransform[i];
                pos++;
            }

            if (joinMatchFound)
            {
                //if there are additional join functions, we run them
                if (_joinFilters.Count == 0)
                {
                    _filterdGroupData = _groupData;
                }
                else
                {
                    _filterdGroupData = new List <object[]>();

                    //filter out the current group based on the functions defined.
                    foreach (var row in _groupData)
                    {
                        var matchFound = true;
                        foreach (var condition in _joinFilters)
                        {
                            foreach (var input in condition.Inputs.Where(c => c.IsColumn))
                            {
                                object value = null;
                                try
                                {
                                    if (input.Column.ReferenceTable == _referenceTableName)
                                    {
                                        value = row[ReferenceTransform.GetOrdinal(input.Column)];
                                    }
                                    else
                                    {
                                        value = PrimaryTransform[input.Column];
                                    }

                                    input.SetValue(value);
                                }
                                catch (Exception ex)
                                {
                                    throw new TransformException($"The join tansform {Name} failed setting parameters on the condition {condition.FunctionName} with the parameter {input.Name}.  {ex.Message}.", ex, value);
                                }
                            }

                            try
                            {
                                var invokeresult = condition.Invoke();

                                if ((bool)invokeresult == false)
                                {
                                    matchFound = false;
                                    break;
                                }
                            }
                            catch (FunctionIgnoreRowException)
                            {
                                matchFound = false;
                                TransformRowsIgnored++;
                                break;
                            }
                            catch (Exception ex)
                            {
                                throw new TransformException($"The join transform {Name} failed calling the function {condition.FunctionName}.  {ex.Message}.", ex);
                            }
                        }

                        if (matchFound)
                        {
                            _filterdGroupData.Add(row);
                        }
                    }
                }

                object[] joinRow = null;

                if (_filterdGroupData.Count > 0)
                {
                    if (_filterdGroupData.Count > 1)
                    {
                        switch (JoinDuplicateStrategy)
                        {
                        case EDuplicateStrategy.Abend:
                            throw new DuplicateJoinKeyException("The join transform failed as the selected columns on the join table " + ReferenceTableAlias + " are not unique.  To continue when duplicates occur set the join strategy to first, last or all.", ReferenceTableAlias, _groupFields);

                        case EDuplicateStrategy.First:
                            joinRow = _filterdGroupData[0];
                            break;

                        case EDuplicateStrategy.Last:
                            joinRow = _filterdGroupData.Last();
                            break;

                        case EDuplicateStrategy.All:
                            joinRow             = _filterdGroupData[0];
                            _writeGroup         = true;
                            _writeGroupPosition = 1;
                            break;

                        default:
                            throw new TransformException("The join transform failed due to an unknown join strategy " + JoinDuplicateStrategy);
                        }
                    }
                    else
                    {
                        joinRow = _filterdGroupData[0];
                    }

                    for (var i = 0; i < _referenceFieldCount; i++)
                    {
                        newRow[pos] = joinRow[i];
                        pos++;
                    }
                }
            }

            return(newRow);
        }