public IList <IBinaryDataListItem> this[int key, bool removeFromGaps = true]
        {
            get
            {
                if (key >= 0)
                {
                    ScrubInternalTo();

                    // Generate entry 1 key, generate entry 2 key.
                    var fetchKeys = GenerateFederatedKey(key);

                    short colCnt = 1;
                    if (Columns != null)
                    {
                        colCnt = (short)Columns.Count;
                    }

                    // I am going to look up all the different pieces then, push them together?!
                    foreach (var fedKey in fetchKeys.FetchAsList())
                    {
                        BinaryDataListRow theRow;
                        _itemStorage.TryGetValue(fedKey.TheKey, colCnt, out theRow);

                        if (theRow != null)
                        {
                            var myCols = fedKey.ImpactedColumns;

                            if (myCols != null)
                            {
                                foreach (var col in myCols)
                                {
                                    // Fetch index value
                                    var internalIdx = InternalFetchColumnIndex(col);

                                    // adjust if there is a mapping ;)
                                    // The datalist in the studio used to sort
                                    // hence we always had the correct ordering in the inner and outer xml shape
                                    // Now that this is not happening we need to account for swapped shapes
                                    // This code resolves an issue for certain cases but causes others to fail.
                                    // Need to find a better solution for the case it is trying to solve.


                                    // FOR : Bug_10247_Outter
                                    // if -1 skip and try next key ;)
                                    if (internalIdx != -1)
                                    {
                                        IBinaryDataListItem tmp = _internalReturnValue[internalIdx];

                                        //                                        if(keyAlias != null)
                                        //                                        {
                                        //                                            tmp.UpdateField(col);
                                        //                                        }

                                        // normal object build
                                        tmp.UpdateValue(theRow.FetchValue(internalIdx, colCnt));
                                        tmp.UpdateIndex(key);
                                    }
                                }
                            }
                            else
                            {
                                // we have a scalar value we are dealing with ;)
                                IBinaryDataListItem tmp = _internalReturnValue[0];
                                tmp.UpdateValue(theRow.FetchValue(0, 1));
                            }
                        }
                    }

                    return(_internalReturnValue);
                }

                return(null);
            }

            set
            {
                if (key >= 0)
                {
                    // we need to fetch federated parts if possible ;)
                    short colCnt = 1;
                    if (Columns != null)
                    {
                        colCnt = (short)Columns.Count;
                    }

                    var fetchKeys = GenerateFederatedKey(key);

                    BinaryDataListRow parentRow = null; // Master location
                    BinaryDataListRow childRow;         // Child location

                    // Fetch master location
                    if (fetchKeys.HasParentKey())
                    {
                        if (!_itemStorage.TryGetValue(fetchKeys.ParentKey.TheKey, colCnt, out parentRow))
                        {
                            throw new Exception("Fatal Internal DataList Storage Error");
                        }
                    }

                    // fetch child location
                    if (!_itemStorage.TryGetValue(fetchKeys.ChildKey.TheKey, colCnt, out childRow))
                    {
                        throw new Exception("Fatal Internal DataList Storage Error");
                    }

                    // we got the row object, now update it ;)
                    foreach (IBinaryDataListItem itm in value)
                    {
                        if (!string.IsNullOrEmpty(itm.FieldName))
                        {
                            int idx = InternalFetchColumnIndex(itm.FieldName); // Fetch correct index
                            BinaryDataListAlias keyAlias;

                            // adjust if there is a mapping ;)
                            if (_keyToAliasMap.TryGetValue(itm.FieldName, out keyAlias))
                            {
                                var parentColumns = keyAlias.MasterEntry.Columns;
                                var parentColumn  = keyAlias.MasterColumn;

                                idx = InternalParentFetchColumnIndex(parentColumn, parentColumns);

                                colCnt = (short)parentColumns.Count;
                            }

                            if (idx == -1 && !IsRecordset)
                            {
                                idx = 0; // adjust for scalar
                            }

                            if (idx >= 0)
                            {
                                // it is an alias mapping ;)
                                if (keyAlias != null)
                                {
                                    // alias update, use row 1
                                    if (parentRow != null)
                                    {
                                        try
                                        {
                                            parentRow.UpdateValue(itm.TheValue, idx, colCnt);
                                        }
                                        catch (Exception)
                                        {
                                            parentRow.UpdateValue(null, idx, colCnt);
                                        }
                                    }
                                }
                                else
                                {
                                    // normal update ;)
                                    try
                                    {
                                        childRow.UpdateValue(itm.TheValue, idx, colCnt);
                                    }
                                    catch (Exception)
                                    {
                                        childRow.UpdateValue(null, idx, colCnt);
                                    }
                                }
                            }
                        }
                    }

                    // adjust correctly ;)
                    if ((parentRow != null && !parentRow.IsEmpty) || (!childRow.IsEmpty))
                    {
                        _myKeys.SetMaxValue(key, IsEmtpy);
                    }
                    else
                    {
                        //we removed it?!
                        _myKeys.AddGap(key);
                    }

                    // update federated values ;)
                    if (parentRow != null)
                    {
                        // TODO : Make Faster, AND Adjust for when my view is different to the row's view!

                        // we need to signal master entry to update its view ;)
                        var me = fetchKeys.MasterEntry;
                        if (me != null)
                        {
                            me.AdjustIndexView(_myKeys.Gaps, _myKeys.GetMinIndex(), _myKeys.GetMaxIndex());
                        }

                        _itemStorage.TrySetValue(fetchKeys.ParentKey.TheKey, colCnt, parentRow);
                    }

                    if (childRow != null)
                    {
                        _itemStorage.TrySetValue(fetchKeys.ChildKey.TheKey, colCnt, childRow);
                    }
                }
            }
        }
Exemplo n.º 2
0
        // 2 seconds for 10k entries with 75 columns ;)
        public void FlushIterations(PayloadIterationFrame <string> scopedFrame, bool isFramed, bool isTerminalFlush)
        {
            string error;

            Dev2TokenConverter tc = new Dev2TokenConverter();

            bool amendedData = false;

            // We do not care about data language in these cases, skip all the junk and get it done son ;)

            while (scopedFrame.HasData())
            {
                DataListPayloadFrameTO <string> tmp = scopedFrame.FetchNextFrameItem();
                string exp = tmp.Expression; //.Replace("(*)", "()"); // force conversion ;)
                string val = tmp.Value;

                // correction, we now need to support recursive evaluation ;(
                if (!DataListUtil.IsRootVariable(exp))
                {
                    ErrorResultTO errors;
                    var           tmpToken = _c.Evaluate(_bdl.UID, enActionType.User, exp, true, out errors);
                    if (errors.HasErrors())
                    {
                        throw new Exception(errors.MakeDisplayReady());
                    }
                    var scalar = tmpToken.FetchScalar();
                    if (scalar == null)
                    {
                        // ReSharper disable RedundantAssignment
                        exp = null;
                        // ReSharper restore RedundantAssignment
                    }
                    exp = tmpToken.FetchScalar().TheValue;
                }

                IIntellisenseResult token = tc.ParseTokenForMatch(exp, _bdl.FetchIntellisenseParts());

                if (token != null)
                {
                    // Get rs and field
                    string rs    = token.Option.Recordset;
                    string field = token.Option.Field;
                    string idx   = token.Option.RecordsetIndex;

                    if (rs != _lastRs && !string.IsNullOrEmpty(rs))
                    {
                        // Flush any existing row data for a different recordset ;)
                        if (_rowData != null)
                        {
                            if (!token.Option.IsScalar)
                            {
                                DumpColAtATime();
                            }

                            amendedData = false;
                        }

                        _bdl.TryGetEntry(rs, out _entry, out error);
                        if (error != string.Empty || _entry == null)
                        {
                            throw new Exception("Upsert Exception : " + error);
                        }

                        // stash last rs
                        _lastRs = rs;

                        // build new row data
                        int cnt = _entry.Columns.Count;
                        _rowData = new List <IBinaryDataListItem>(cnt);
                        InitRowBuffer(cnt);
                    }


                    if (!token.Option.IsScalar)
                    {
                        // set commit flag ;)
                        amendedData = true;

                        int colIdx = _entry.InternalFetchColumnIndex(field);

                        IBinaryDataListItem itm = _rowData[colIdx];

                        enRecordsetIndexType idxType = DataListUtil.GetRecordsetIndexTypeRaw(idx);

                        int tmpIdx = _dris.FetchRecordsetIndex(token, _entry, isFramed);

                        if (tmpIdx != _upsertIdx)
                        {
                            // silly users making algorithms slow ;(
                            // we need to dump data at this point... 1 fliping column at a time
                            DumpColAtATime();
                        }

                        _upsertIdx = tmpIdx;

                        if (_upsertIdx == 0)
                        {
                            throw new Exception("Invalid recordset index of 0");
                        }

                        // if numeric fetch the index
                        if (idxType == enRecordsetIndexType.Numeric)
                        {
                            Int32.TryParse(idx, out _upsertIdx);
                        }


                        itm.UpdateIndex(_upsertIdx);
                        itm.UpdateField(field);
                        itm.UpdateValue(val);

                        if (_rowData == null)
                        {
                            throw new Exception("Invalid Bulk Load Data");
                        }

                        _rowData[colIdx] = itm;
                    }
                    else
                    {
                        IBinaryDataListItem itm = DataListConstants.baseItem.Clone();

                        // else scalar and we need to get the entry ;(
                        IBinaryDataListEntry scalarEntry;
                        _bdl.TryGetEntry(field, out scalarEntry, out error);
                        itm.UpdateField(field);
                        itm.UpdateValue(val);

                        scalarEntry.TryPutScalar(itm, out error);

                        if (error != string.Empty)
                        {
                            throw new Exception(error);
                        }
                    }
                }
                else
                {
                    throw new Exception("Null token for [ " + exp + " ]");
                }
            }

            // flush the rowData out ;)
            if (_entry != null && _entry.IsRecordset && amendedData)
            {
                _entry.TryPutRecordRowAt(_rowData, _upsertIdx, out error);
                if (error != string.Empty)
                {
                    throw new Exception(error);
                }

                _dris.MoveIndexesToNextPosition();
            }

            if (isTerminalFlush)
            {
                ErrorResultTO errors;
                _c.PushBinaryDataListInServerScope(_liveFlushingLocation, _bdl, out errors);
            }

            // clear out the buffer
            ClearRowBuffer();
        }