/// <summary> /// Construct a new placeholder with the shape of the given placeholder. Key values are /// injected into the resulting place holder and default values are substituted with /// either propagator constants or progagator nulls depending on the mode established /// by the <paramref name="mode"/> flag. /// </summary> /// <remarks> /// The key is essentially an array of values. The key map indicates that for a particular /// placeholder an expression (keyMap.Keys) corresponds to some ordinal in the key array. /// </remarks> /// <param name="placeholder">Placeholder to clone</param> /// <param name="key">Key to substitute</param> /// <param name="placeholderKey">Key elements in the placeholder (ordinally aligned with 'key')</param> /// <param name="mode">Mode of operation.</param> /// <param name="translator">Translator context.</param> /// <returns>Cloned placeholder with key values</returns> internal static PropagatorResult Populate(PropagatorResult placeholder, CompositeKey key, CompositeKey placeholderKey, PopulateMode mode, UpdateTranslator translator) { EntityUtil.CheckArgumentNull(placeholder, "placeholder"); EntityUtil.CheckArgumentNull(key, "key"); EntityUtil.CheckArgumentNull(placeholderKey, "placeholderKey"); EntityUtil.CheckArgumentNull(translator, "translator"); // Figure out which flags to apply to generated elements. bool isNull = mode == PopulateMode.NullModified || mode == PopulateMode.NullPreserve; bool preserve = mode == PopulateMode.NullPreserve || mode == PopulateMode.Unknown; PropagatorFlags flags = PropagatorFlags.NoFlags; if (!isNull) { flags |= PropagatorFlags.Unknown; } // only null values are known if (preserve) { flags |= PropagatorFlags.Preserve; } PropagatorResult result = placeholder.Replace(node => { // See if this is a key element int keyIndex = -1; for (int i = 0; i < placeholderKey.KeyComponents.Length; i++) { if (placeholderKey.KeyComponents[i] == node) { keyIndex = i; break; } } if (keyIndex != -1) { // Key value. return(key.KeyComponents[keyIndex]); } else { // for simple entries, just return using the markup context for this // populator object value = isNull ? null : node.GetSimpleValue(); return(PropagatorResult.CreateSimpleValue(flags, value)); } }); return(result); }
/// <summary> /// Produce a tuple containing joined rows. /// </summary> /// <param name="left">Left row.</param> /// <param name="right">Right row.</param> /// <param name="leftKey">Key used to join left element.</param> /// <param name="rightKey">Key used to join right element.</param> /// <param name="result">Result change node; used for type information.</param> /// <returns>Result of joining the input rows.</returns> private PropagatorResult CreateResultTuple(Tuple <CompositeKey, PropagatorResult> left, Tuple <CompositeKey, PropagatorResult> right, ChangeNode result) { // using ref compare to avoid triggering value based CompositeKey leftKey = left.Item1; CompositeKey rightKey = right.Item1; Dictionary <PropagatorResult, PropagatorResult> map = null; if (!object.ReferenceEquals(null, leftKey) && !object.ReferenceEquals(null, rightKey) && !object.ReferenceEquals(leftKey, rightKey)) { // Merge key values from the left and the right (since they're equal, there's a possibility we'll // project values only from the left or the right hand side and lose important context.) CompositeKey mergedKey = leftKey.Merge(m_parent.m_updateTranslator.KeyManager, rightKey); // create a dictionary so that we can replace key values with merged key values (carrying context // from both sides) map = new Dictionary <PropagatorResult, PropagatorResult>(); for (int i = 0; i < leftKey.KeyComponents.Length; i++) { map[leftKey.KeyComponents[i]] = mergedKey.KeyComponents[i]; map[rightKey.KeyComponents[i]] = mergedKey.KeyComponents[i]; } } PropagatorResult[] joinRecordValues = new PropagatorResult[2]; joinRecordValues[0] = left.Item2; joinRecordValues[1] = right.Item2; PropagatorResult join = PropagatorResult.CreateStructuralValue(joinRecordValues, (StructuralType)result.ElementType.EdmType, false); // replace with merged key values as appropriate if (null != map) { PropagatorResult replacement; join = join.Replace(original => map.TryGetValue(original, out replacement) ? replacement : original); } return(join); }
/// <summary> /// Construct a new placeholder with the shape of the given placeholder. Key values are /// injected into the resulting place holder and default values are substituted with /// either propagator constants or progagator nulls depending on the mode established /// by the <paramref name="mode"/> flag. /// </summary> /// <remarks> /// The key is essentially an array of values. The key map indicates that for a particular /// placeholder an expression (keyMap.Keys) corresponds to some ordinal in the key array. /// </remarks> /// <param name="placeholder">Placeholder to clone</param> /// <param name="key">Key to substitute</param> /// <param name="placeholderKey">Key elements in the placeholder (ordinally aligned with 'key')</param> /// <param name="mode">Mode of operation.</param> /// <param name="translator">Translator context.</param> /// <returns>Cloned placeholder with key values</returns> internal static PropagatorResult Populate(PropagatorResult placeholder, CompositeKey key, CompositeKey placeholderKey, PopulateMode mode, UpdateTranslator translator) { EntityUtil.CheckArgumentNull(placeholder, "placeholder"); EntityUtil.CheckArgumentNull(key, "key"); EntityUtil.CheckArgumentNull(placeholderKey, "placeholderKey"); EntityUtil.CheckArgumentNull(translator, "translator"); // Figure out which flags to apply to generated elements. bool isNull = mode == PopulateMode.NullModified || mode == PopulateMode.NullPreserve; bool preserve = mode == PopulateMode.NullPreserve || mode == PopulateMode.Unknown; PropagatorFlags flags = PropagatorFlags.NoFlags; if (!isNull) { flags |= PropagatorFlags.Unknown; } // only null values are known if (preserve) { flags |= PropagatorFlags.Preserve; } PropagatorResult result = placeholder.Replace(node => { // See if this is a key element int keyIndex = -1; for (int i = 0; i < placeholderKey.KeyComponents.Length; i++) { if (placeholderKey.KeyComponents[i] == node) { keyIndex = i; break; } } if (keyIndex != -1) { // Key value. return key.KeyComponents[keyIndex]; } else { // for simple entries, just return using the markup context for this // populator object value = isNull ? null : node.GetSimpleValue(); return PropagatorResult.CreateSimpleValue(flags, value); } }); return result; }
/// <summary> /// Construct a new placeholder with the shape of the given placeholder. Key values are /// injected into the resulting place holder and default values are substituted with /// either propagator constants or progagator nulls depending on the mode established /// by the <paramref name="mode"/> flag. /// </summary> /// <remarks> /// The key is essentially an array of values. The key map indicates that for a particular /// placeholder an expression (keyMap.Keys) corresponds to some ordinal in the key array. /// </remarks> /// <param name="placeholder">Placeholder to clone</param> /// <param name="key">Key to substitute</param> /// <param name="placeholderKey">Key elements in the placeholder (ordinally aligned with 'key')</param> /// <param name="mode">Mode of operation.</param> /// <returns>Cloned placeholder with key values</returns> internal static PropagatorResult Populate( PropagatorResult placeholder, CompositeKey key, CompositeKey placeholderKey, PopulateMode mode) { //Contract.Requires(placeholder != null); //Contract.Requires(key != null); //Contract.Requires(placeholderKey != null); // Figure out which flags to apply to generated elements. var isNull = mode == PopulateMode.NullModified || mode == PopulateMode.NullPreserve; var preserve = mode == PopulateMode.NullPreserve || mode == PopulateMode.Unknown; var flags = PropagatorFlags.NoFlags; if (!isNull) { flags |= PropagatorFlags.Unknown; } // only null values are known if (preserve) { flags |= PropagatorFlags.Preserve; } var result = placeholder.Replace( node => { // See if this is a key element var keyIndex = -1; for (var i = 0; i < placeholderKey.KeyComponents.Length; i++) { if (placeholderKey.KeyComponents[i] == node) { keyIndex = i; break; } } if (keyIndex != -1) { // Key value. return key.KeyComponents[keyIndex]; } else { // for simple entries, just return using the markup context for this // populator var value = isNull ? null : node.GetSimpleValue(); return PropagatorResult.CreateSimpleValue(flags, value); } }); return result; }