/// <summary> /// Body of CreateX12Segment methods that create empty X12 segment /// </summary> /// <param name="name"></param> /// <param name="elementCount"></param> /// <returns></returns> private KeyValRecord CreateEmptyX12Segment_body(string name, int elementCount) { var elems = Enumerable.Repeat(KeyValItem.CreateItem("Segment", name, _typeDefinitions), 1). Concat(Enumerable.Range(0, elementCount).Select(i => KeyValItem.CreateItem(string.Format("Elem{0:000}", i + 1), string.Empty, _typeDefinitions))); //alternatively: var elems = Enumerable.Range(0, elementCount + 1).Select(i => KeyValItem.CreateItem(i == 0 ? "Segment" : string.Format("Elem{0:000}", i), i == 0 ? name : string.Empty, _typeDefinitions)); //Note that each element has empty string assigned (however, user can assign null afterwards). return(new KeyValRecord(elems, RecNo, SourceNo, ClstrNo, GlobalCache, null, null, this._typeDefinitions, this._config, _processingStatusSupplier, ActionOnDuplicateKey.IgnoreItem)); //note that ActionOnDuplicateKey.IgnoreItem is appropriate as no dups are possible in a list of consecutively named keys, i.e. Segment, Elem001, Elem002, ... }
/// <summary> /// Body of CreateX12Segment methods that take entire segment contents as a parameter /// </summary> /// <param name="contents">The contents of the entire segment using DefaultX12FieldDelimiter between fields, but no segment delimiter at end.</param> /// <param name="fieldDelimiter">Field delimiter character used within contents.</param> /// <returns></returns> private KeyValRecord CreateFilledX12Segment_body(string contents, char fieldDelimiter) { //note that null char is the default value for _config.DefaultX12FieldDelimiter var delimiterInEffect = fieldDelimiter == '\0' ? _config.DefaultX12FieldDelimiter == '\0' ? '*' : _config.DefaultX12FieldDelimiter : fieldDelimiter; var i = 0; var elems = contents.Split(delimiterInEffect).Select(v => KeyValItem.CreateItem(i++ == 0 ? "Segment" : string.Format("Elem{0:000}", i - 1), v, _typeDefinitions)); return(new KeyValRecord(elems, RecNo, SourceNo, ClstrNo, GlobalCache, null, null, _typeDefinitions, _config, _processingStatusSupplier, ActionOnDuplicateKey.IgnoreItem)); //note that ActionOnDuplicateKey.IgnoreItem is appropriate as no dups are possible in a list of consecutively named keys, i.e. Segment, Elem001, Elem002, ... }
/// <summary> /// Return a clone of a given item with a new value. /// </summary> /// <param name="item">Item to clone</param> /// <param name="value">New (typed) value for the clone</param> /// <returns>A clone of a given item.</returns> public IItem GetItemClone(IItem item, object value) { //cloning should be confined to items "owned" by record if (!_itemColl.Contains(item)) { //this can happen if client app uses an item from a different record of a cluster _config.Logger.LogWarning(() => $"Attempt to clone item '{item.Key}' within record #{RecNo}, but there is no such item in the record."); return(new VoidKeyValItem(item.Key)); } return(KeyValItem.CreateItem(item.Key, value, _typeDefinitions)); }
/// <summary> /// Assign a value for a dynamic property, i.e. an item for a specified key. /// </summary> /// <param name="binder"></param> /// <param name="value"></param> /// <returns></returns> public override bool TrySetMember(SetMemberBinder binder, object value) { var key = binder.Name; //TODO: Not thread-safe, verify and fix if needed if (_itemColl.Contains(key)) { SetItemValue(IndexForKey(key), value); } else //add a property "on-the-fly", but only if allowed (config.AllowTransformToAlterFields is true) { if (!this._fieldsCanBeAltered) { return(true); //TODO: Consider returning false to indicate adding field was disallowed (research how this should be handled) } _itemColl.Add(KeyValItem.CreateItem(key, value, _typeDefinitions)); } return(true); }
/// <summary> /// Body of GetClone methods (also called by KeyValCluster.GetClone method). /// </summary> /// <returns></returns> internal KeyValRecord GetClone_body() { return(new KeyValRecord(Items.Select(itm => KeyValItem.CreateItem(itm.Key, itm.Value, _typeDefinitions)), RecNo, SourceNo, ClstrNo, GlobalCache, TraceBin, PropertyBin, _typeDefinitions, _config, _processingStatusSupplier, ActionOnDuplicateKey.IgnoreItem)); //Note that ActionOnDuplicateKey.IgnoreItem is appropriate as no dups are possible in existing KeyValRecord (IOW, we don't need something like _actionOnDuplicateKey) }
/// <summary> /// Helper method to replace existing item with a new one created from a submitted strongly typed value /// </summary> /// <param name="index">Position of the item to replace (0 based)</param> /// <param name="newValue"></param> private void SetItemValue(int index, object newValue) { SetItemValue(index, KeyValItem.CreateItem(KeyForIndex(index), newValue, _typeDefinitions)); }
/// <summary> /// Return a clone of a given item with a new value /// </summary> /// <param name="item">Item to clone</param> /// <param name="value">String representation of a new value for the clone</param> /// <returns>Cloned item</returns> IItem IUntypedRecord.GetItemClone(IItem item, string value) { return(KeyValItem.CreateItem(item.Key, value, _typeDefinitions)); }
/// <summary> /// Add an item for a given key and value at the end of the record /// </summary> /// <param name="key">Key of an item to add</param> /// <param name="value">String representation of a value of an item to add</param> /// <returns>The item added or void item if key already existed (and thus no item was added); if item was not added because additions/removals are disallowed return null.</returns> IItem IUntypedRecord.AddItem(string key, string value) { return(AddItem_body(key, () => KeyValItem.CreateItem(key, value, _typeDefinitions))); }
/// <summary> /// Add an item for a given key and value at the end of the record /// </summary> /// <param name="key">Key of an item to add</param> /// <param name="value">Typed value of an item to add</param> /// <returns>The item added or void item if key already existed (and thus no item was added); if item was not added because additions/removals are disallowed return null.</returns> public IItem AddItem(string key, object value) { return(AddItem_body(key, () => KeyValItem.CreateItem(key, value, _typeDefinitions))); }