1 //---------------------------------------------------------------------
2 // <copyright file="PropagatorResult.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9 
10 using System.Data.Metadata.Edm;
11 using System.Collections.Generic;
12 using System.Globalization;
13 using System.Diagnostics;
14 using System.Data.Common.Utils;
15 using System.Data.Objects;
16 using System.Collections;
17 using System.Data.Common;
18 using System.Text;
19 using System.Linq;
20 namespace System.Data.Mapping.Update.Internal
21 {
22     /// <summary>
23     /// requires: for structural types, member values are ordinally aligned with the members of the
24     /// structural type.
25     ///
26     /// Stores a 'row' (or element within a row) being propagated through the update pipeline, including
27     /// markup information and metadata. Internally, we maintain several different classes so that we only
28     /// store the necessary state.
29     ///
30     /// - StructuralValue (complex types, entities, and association end keys): type and member values,
31     ///   one version for modified structural values and one version for unmodified structural values
32     ///   (a structural type is modified if its _type_ is changed, not its values
33     /// - SimpleValue (scalar value): flags to describe the state of the value (is it a concurrency value,
34     ///   is it modified) and the value itself
35     /// - ServerGenSimpleValue: adds back-prop information to the above (record and position in record
36     ///   so that we can set the value on back-prop)
37     /// - KeyValue: the originating IEntityStateEntry also travels with keys. These entries are used purely for
38     ///   error reporting. We send them with keys so that every row containing an entity (which must also
39     ///   contain the key) has enough context to recover the state entry.
40     /// </summary>
41     /// <remarks>
42     /// Not all memebers of a PropagatorResult are available for all specializations. For instance, GetSimpleValue
43     /// is available only on simple types
44     /// </remarks>
45     internal abstract class PropagatorResult
46     {
47         #region Constructors
48         // private constructor: only nested classes may derive from propagator result
PropagatorResult()49         private PropagatorResult()
50         {
51         }
52         #endregion
53 
54         #region Fields
55         internal const int NullIdentifier = -1;
56         internal const int NullOrdinal = -1;
57         #endregion
58 
59         #region Properties
60         /// <summary>
61         /// Gets a value indicating whether this result is null.
62         /// </summary>
63         internal abstract bool IsNull { get; }
64 
65         /// <summary>
66         /// Gets a value indicating whether this is a simple (scalar) or complex
67         /// structural) result.
68         /// </summary>
69         internal abstract bool IsSimple { get; }
70 
71         /// <summary>
72         /// Gets flags describing the behaviors for this element.
73         /// </summary>
74         internal virtual PropagatorFlags PropagatorFlags
75         {
76             get { return PropagatorFlags.NoFlags; }
77         }
78 
79         /// <summary>
80         /// Gets all state entries from which this result originated. Only set for key
81         /// values (to ensure every row knows all of its source entries)
82         /// </summary>
83         internal virtual IEntityStateEntry StateEntry
84         {
85             get { return null; }
86         }
87 
88         /// <summary>
89         /// Gets record from which this result originated. Only set for server generated
90         /// results (where the record needs to be synchronized).
91         /// </summary>
92         internal virtual CurrentValueRecord Record
93         {
94             get { return null; }
95         }
96 
97         /// <summary>
98         /// Gets structural type for non simple results. Only available for entity and complex type
99         /// results.
100         /// </summary>
101         internal virtual StructuralType StructuralType
102         {
103             get { return null; }
104         }
105 
106         /// <summary>
107         /// Gets the ordinal within the originating record for this result. Only set
108         /// for server generated results (otherwise, returns -1)
109         /// </summary>
110         internal virtual int RecordOrdinal
111         {
112             get { return NullOrdinal; }
113         }
114 
115         /// <summary>
116         /// Gets the identifier for this entry if it is a server-gen key value (otherwise
117         /// returns -1)
118         /// </summary>
119         internal virtual int Identifier
120         {
121             get { return NullIdentifier; }
122         }
123 
124         /// <summary>
125         /// Where a single result corresponds to multiple key inputs, they are chained using this linked list.
126         /// By convention, the first entry in the chain is the 'dominant' entry (the principal key).
127         /// </summary>
128         internal virtual PropagatorResult Next
129         {
130             get { return null; }
131         }
132         #endregion
133 
134         #region Methods
135         /// <summary>
136         /// Returns simple value stored in this result. Only valid when <see cref="IsSimple" /> is
137         /// true.
138         /// </summary>
139         ///
140         /// <returns>Concrete value.</returns>
GetSimpleValue()141         internal virtual object GetSimpleValue()
142         {
143             throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.UpdatePipelineResultRequestInvalid, 0, "PropagatorResult.GetSimpleValue");
144         }
145 
146         /// <summary>
147         /// Returns nested value. Only valid when <see cref="IsSimple" /> is false.
148         /// </summary>
149         /// <param name="ordinal">Ordinal of value to return (ordinal based on type definition)</param>
150         /// <returns>Nested result.</returns>
GetMemberValue(int ordinal)151         internal virtual PropagatorResult GetMemberValue(int ordinal)
152         {
153             throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.UpdatePipelineResultRequestInvalid, 0, "PropagatorResult.GetMemberValue");
154         }
155 
156         /// <summary>
157         /// Returns nested value. Only valid when <see cref="IsSimple" /> is false.
158         /// </summary>
159         /// <param name="member">Member for which to return a value</param>
160         /// <returns>Nested result.</returns>
GetMemberValue(EdmMember member)161         internal PropagatorResult GetMemberValue(EdmMember member)
162         {
163             int ordinal = TypeHelpers.GetAllStructuralMembers(this.StructuralType).IndexOf(member);
164             return GetMemberValue(ordinal);
165         }
166 
167         /// <summary>
168         /// Returns all structural values. Only valid when <see cref="IsSimple" /> is false.
169         /// </summary>
170         /// <returns>Values of all structural members.</returns>
GetMemberValues()171         internal virtual PropagatorResult[] GetMemberValues()
172         {
173             throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.UpdatePipelineResultRequestInvalid, 0, "PropagatorResult.GetMembersValues");
174         }
175 
176         /// <summary>
177         /// Produces a replica of this propagator result with different flags.
178         /// </summary>
179         /// <param name="flags">New flags for the result.</param>
180         /// <returns>This result with the given flags.</returns>
ReplicateResultWithNewFlags(PropagatorFlags flags)181         internal abstract PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags);
182 
183         /// <summary>
184         /// Copies this result replacing its value. Used for cast. Requires a simple result.
185         /// </summary>
186         /// <param name="value">New value for result</param>
187         /// <returns>Copy of this result with new value.</returns>
ReplicateResultWithNewValue(object value)188         internal virtual PropagatorResult ReplicateResultWithNewValue(object value)
189         {
190             throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.UpdatePipelineResultRequestInvalid, 0, "PropagatorResult.ReplicateResultWithNewValue");
191         }
192 
193         /// <summary>
194         /// Replaces parts of the structured result.
195         /// </summary>
196         /// <param name="map">A replace-with map applied to simple (i.e. not structural) values.</param>
197         /// <returns>Result with requested elements replaced.</returns>
Replace(Func<PropagatorResult, PropagatorResult> map)198         internal abstract PropagatorResult Replace(Func<PropagatorResult, PropagatorResult> map);
199 
200         /// <summary>
201         /// A result is merged with another when it is merged as part of an equi-join.
202         /// </summary>
203         /// <remarks>
204         /// In theory, this should only ever be called on two keys (since we only join on
205         /// keys). We throw in the base implementation, and override in KeyResult. By convention
206         /// the principal key is always the first result in the chain (in case of an RIC). In
207         /// addition, entity entries always appear before relationship entries.
208         /// </remarks>
209         /// <param name="other">Result to merge with.</param>
210         /// <returns>Merged result.</returns>
Merge(KeyManager keyManager, PropagatorResult other)211         internal virtual PropagatorResult Merge(KeyManager keyManager, PropagatorResult other)
212         {
213             throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.UpdatePipelineResultRequestInvalid, 0, "PropagatorResult.Merge");
214         }
215 
216 
217 #if DEBUG
ToString()218         public override string ToString()
219         {
220             StringBuilder builder = new StringBuilder();
221             if (PropagatorFlags.NoFlags != PropagatorFlags)
222             {
223                 builder.Append(PropagatorFlags.ToString()).Append(":");
224             }
225             if (NullIdentifier != Identifier)
226             {
227                 builder.Append("id").Append(Identifier.ToString(CultureInfo.InvariantCulture)).Append(":");
228             }
229             if (NullOrdinal != RecordOrdinal)
230             {
231                 builder.Append("ord").Append(RecordOrdinal.ToString(CultureInfo.InvariantCulture)).Append(":");
232             }
233             if (IsSimple)
234             {
235                 builder.AppendFormat(CultureInfo.InvariantCulture, "{0}", GetSimpleValue());
236             }
237             else
238             {
239                 if (!Helper.IsRowType(StructuralType))
240                 {
241                     builder.Append(StructuralType.Name).Append(":");
242                 }
243                 builder.Append("{");
244                 bool first = true;
245                 foreach (KeyValuePair<EdmMember, PropagatorResult> memberValue in Helper.PairEnumerations(
246                     TypeHelpers.GetAllStructuralMembers(this.StructuralType), GetMemberValues()))
247                 {
248                     if (first) { first = false; }
249                     else { builder.Append(", "); }
250                     builder.Append(memberValue.Key.Name).Append("=").Append(memberValue.Value.ToString());
251                 }
252                 builder.Append("}");
253             }
254             return builder.ToString();
255         }
256 #endif
257         #endregion
258 
259         #region Nested types and factory methods
CreateSimpleValue(PropagatorFlags flags, object value)260         internal static PropagatorResult CreateSimpleValue(PropagatorFlags flags, object value)
261         {
262             return new SimpleValue(flags, value);
263         }
264 
265         private class SimpleValue : PropagatorResult
266         {
SimpleValue(PropagatorFlags flags, object value)267             internal SimpleValue(PropagatorFlags flags, object value)
268             {
269                 m_flags = flags;
270                 m_value = value ?? DBNull.Value;
271             }
272 
273             private readonly PropagatorFlags m_flags;
274             protected readonly object m_value;
275 
276             internal override PropagatorFlags PropagatorFlags
277             {
278                 get { return m_flags; }
279             }
280 
281             internal override bool IsSimple
282             {
283                 get { return true; }
284             }
285 
286             internal override bool IsNull
287             {
288                 get
289                 {
290                     // The result is null if it is not associated with an identifier and
291                     // the value provided by the user is also null.
292                     return NullIdentifier == this.Identifier && DBNull.Value == m_value;
293                 }
294             }
295 
GetSimpleValue()296             internal override object GetSimpleValue()
297             {
298                 return m_value;
299             }
300 
ReplicateResultWithNewFlags(PropagatorFlags flags)301             internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
302             {
303                 return new SimpleValue(flags, m_value);
304             }
305 
ReplicateResultWithNewValue(object value)306             internal override PropagatorResult ReplicateResultWithNewValue(object value)
307             {
308                 return new SimpleValue(PropagatorFlags, value);
309             }
310 
Replace(Func<PropagatorResult, PropagatorResult> map)311             internal override PropagatorResult Replace(Func<PropagatorResult, PropagatorResult> map)
312             {
313                 return map(this);
314             }
315         }
316 
CreateServerGenSimpleValue(PropagatorFlags flags, object value, CurrentValueRecord record, int recordOrdinal)317         internal static PropagatorResult CreateServerGenSimpleValue(PropagatorFlags flags, object value, CurrentValueRecord record, int recordOrdinal)
318         {
319             return new ServerGenSimpleValue(flags, value, record, recordOrdinal);
320         }
321         private class ServerGenSimpleValue : SimpleValue
322         {
ServerGenSimpleValue(PropagatorFlags flags, object value, CurrentValueRecord record, int recordOrdinal)323             internal ServerGenSimpleValue(PropagatorFlags flags, object value, CurrentValueRecord record, int recordOrdinal)
324                 : base(flags, value)
325             {
326                 Debug.Assert(null != record);
327 
328                 m_record = record;
329                 m_recordOrdinal = recordOrdinal;
330             }
331 
332             private readonly CurrentValueRecord m_record;
333             private readonly int m_recordOrdinal;
334 
335             internal override CurrentValueRecord Record
336             {
337                 get { return m_record; }
338             }
339 
340             internal override int RecordOrdinal
341             {
342                 get { return m_recordOrdinal; }
343             }
344 
ReplicateResultWithNewFlags(PropagatorFlags flags)345             internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
346             {
347                 return new ServerGenSimpleValue(flags, m_value, Record, RecordOrdinal);
348             }
349 
ReplicateResultWithNewValue(object value)350             internal override PropagatorResult ReplicateResultWithNewValue(object value)
351             {
352                 return new ServerGenSimpleValue(PropagatorFlags, value, Record, RecordOrdinal);
353             }
354         }
355 
CreateKeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier)356         internal static PropagatorResult CreateKeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier)
357         {
358             return new KeyValue(flags, value, stateEntry, identifier, null);
359         }
360 
361         private class KeyValue : SimpleValue
362         {
KeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, KeyValue next)363             internal KeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, KeyValue next)
364                 : base(flags, value)
365             {
366                 Debug.Assert(null != stateEntry);
367 
368                 m_stateEntry = stateEntry;
369                 m_identifier = identifier;
370                 m_next = next;
371             }
372 
373             private readonly IEntityStateEntry m_stateEntry;
374             private readonly int m_identifier;
375             protected readonly KeyValue m_next;
376 
377             internal override IEntityStateEntry StateEntry
378             {
379                 get { return m_stateEntry; }
380             }
381 
382             internal override int Identifier
383             {
384                 get { return m_identifier; }
385             }
386 
387             internal override CurrentValueRecord Record
388             {
389                 get
390                 {
391                     // delegate to the state entry, which also has the record
392                     return m_stateEntry.CurrentValues;
393                 }
394             }
395 
396             internal override PropagatorResult Next
397             {
398                 get
399                 {
400                     return m_next;
401                 }
402             }
403 
ReplicateResultWithNewFlags(PropagatorFlags flags)404             internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
405             {
406                 return new KeyValue(flags, m_value, StateEntry, Identifier, m_next);
407             }
408 
ReplicateResultWithNewValue(object value)409             internal override PropagatorResult ReplicateResultWithNewValue(object value)
410             {
411                 return new KeyValue(PropagatorFlags, value, StateEntry, Identifier, m_next);
412             }
413 
ReplicateResultWithNewNext(KeyValue next)414             internal virtual KeyValue ReplicateResultWithNewNext(KeyValue next)
415             {
416                 if (m_next != null)
417                 {
418                     // push the next value to the end of the linked list
419                     next = m_next.ReplicateResultWithNewNext(next);
420                 }
421                 return new KeyValue(this.PropagatorFlags, m_value, m_stateEntry, m_identifier, next);
422             }
423 
Merge(KeyManager keyManager, PropagatorResult other)424             internal override PropagatorResult Merge(KeyManager keyManager, PropagatorResult other)
425             {
426                 KeyValue otherKey = other as KeyValue;
427                 if (null == otherKey)
428                 {
429                     EntityUtil.InternalError(EntityUtil.InternalErrorCode.UpdatePipelineResultRequestInvalid, 0, "KeyValue.Merge");
430                 }
431 
432                 // Determine which key (this or otherKey) is first in the chain. Principal keys take
433                 // precedence over dependent keys and entities take precedence over relationships.
434                 if (this.Identifier != otherKey.Identifier)
435                 {
436                     // Find principal (if any)
437                     if (keyManager.GetPrincipals(otherKey.Identifier).Contains(this.Identifier))
438                     {
439                         return this.ReplicateResultWithNewNext(otherKey);
440                     }
441                     else
442                     {
443                         return otherKey.ReplicateResultWithNewNext(this);
444                     }
445                 }
446                 else
447                 {
448                     // Entity takes precedence of relationship
449                     if (null == m_stateEntry || m_stateEntry.IsRelationship)
450                     {
451                         return otherKey.ReplicateResultWithNewNext(this);
452                     }
453                     else
454                     {
455                         return this.ReplicateResultWithNewNext(otherKey);
456                     }
457                 }
458             }
459         }
460 
CreateServerGenKeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, int recordOrdinal)461         internal static PropagatorResult CreateServerGenKeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, int recordOrdinal)
462         {
463             return new ServerGenKeyValue(flags, value, stateEntry, identifier, recordOrdinal, null);
464         }
465 
466         private class ServerGenKeyValue : KeyValue
467         {
ServerGenKeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, int recordOrdinal, KeyValue next)468             internal ServerGenKeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, int recordOrdinal, KeyValue next)
469                 : base(flags, value, stateEntry, identifier, next)
470             {
471                 m_recordOrdinal = recordOrdinal;
472             }
473 
474             private readonly int m_recordOrdinal;
475 
476             internal override int RecordOrdinal
477             {
478                 get { return m_recordOrdinal; }
479             }
480 
ReplicateResultWithNewFlags(PropagatorFlags flags)481             internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
482             {
483                 return new ServerGenKeyValue(flags, m_value, this.StateEntry, this.Identifier, this.RecordOrdinal, m_next);
484             }
485 
ReplicateResultWithNewValue(object value)486             internal override PropagatorResult ReplicateResultWithNewValue(object value)
487             {
488                 return new ServerGenKeyValue(this.PropagatorFlags, value, this.StateEntry, this.Identifier, this.RecordOrdinal, m_next);
489             }
490 
ReplicateResultWithNewNext(KeyValue next)491             internal override KeyValue ReplicateResultWithNewNext(KeyValue next)
492             {
493                 if (m_next != null)
494                 {
495                     // push the next value to the end of the linked list
496                     next = m_next.ReplicateResultWithNewNext(next);
497                 }
498                 return new ServerGenKeyValue(PropagatorFlags, m_value, StateEntry, Identifier, RecordOrdinal, next);
499             }
500         }
501 
CreateStructuralValue(PropagatorResult[] values, StructuralType structuralType, bool isModified)502         internal static PropagatorResult CreateStructuralValue(PropagatorResult[] values, StructuralType structuralType, bool isModified)
503         {
504             if (isModified)
505             {
506                 return new StructuralValue(values, structuralType);
507             }
508             else
509             {
510                 return new UnmodifiedStructuralValue(values, structuralType);
511             }
512         }
513         private class StructuralValue : PropagatorResult
514         {
StructuralValue(PropagatorResult[] values, StructuralType structuralType)515             internal StructuralValue(PropagatorResult[] values, StructuralType structuralType)
516             {
517                 Debug.Assert(null != structuralType);
518                 Debug.Assert(null != values);
519                 Debug.Assert(values.Length == TypeHelpers.GetAllStructuralMembers(structuralType).Count);
520 
521                 m_values = values;
522                 m_structuralType = structuralType;
523             }
524 
525             private readonly PropagatorResult[] m_values;
526             protected readonly StructuralType m_structuralType;
527 
528             internal override bool IsSimple
529             {
530                 get { return false; }
531             }
532 
533             internal override bool IsNull
534             {
535                 get { return false; }
536             }
537 
538             internal override StructuralType StructuralType
539             {
540                 get { return m_structuralType; }
541             }
542 
GetMemberValue(int ordinal)543             internal override PropagatorResult GetMemberValue(int ordinal)
544             {
545                 return m_values[ordinal];
546             }
547 
GetMemberValues()548             internal override PropagatorResult[] GetMemberValues()
549             {
550                 return m_values;
551             }
552 
ReplicateResultWithNewFlags(PropagatorFlags flags)553             internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
554             {
555                 throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.UpdatePipelineResultRequestInvalid, 0, "StructuralValue.ReplicateResultWithNewFlags");
556             }
557 
Replace(Func<PropagatorResult, PropagatorResult> map)558             internal override PropagatorResult Replace(Func<PropagatorResult, PropagatorResult> map)
559             {
560                 PropagatorResult[] newValues = ReplaceValues(map);
561                 return null == newValues ? this : new StructuralValue(newValues, m_structuralType);
562             }
563 
ReplaceValues(Func<PropagatorResult, PropagatorResult> map)564             protected PropagatorResult[] ReplaceValues(Func<PropagatorResult, PropagatorResult> map)
565             {
566                 PropagatorResult[] newValues = new PropagatorResult[m_values.Length];
567                 bool hasChange = false;
568                 for (int i = 0; i < newValues.Length; i++)
569                 {
570                     PropagatorResult newValue = m_values[i].Replace(map);
571                     if (!object.ReferenceEquals(newValue, m_values[i]))
572                     {
573                         hasChange = true;
574                     }
575                     newValues[i] = newValue;
576                 }
577                 return hasChange ? newValues : null;
578             }
579         }
580 
581         private class UnmodifiedStructuralValue : StructuralValue
582         {
UnmodifiedStructuralValue(PropagatorResult[] values, StructuralType structuralType)583             internal UnmodifiedStructuralValue(PropagatorResult[] values, StructuralType structuralType)
584                 : base(values, structuralType)
585             {
586             }
587 
588             internal override PropagatorFlags PropagatorFlags
589             {
590                 get
591                 {
592                     return PropagatorFlags.Preserve;
593                 }
594             }
595 
Replace(Func<PropagatorResult, PropagatorResult> map)596             internal override PropagatorResult Replace(Func<PropagatorResult, PropagatorResult> map)
597             {
598                 PropagatorResult[] newValues = ReplaceValues(map);
599                 return null == newValues ? this : new UnmodifiedStructuralValue(newValues, m_structuralType);
600             }
601         }
602         #endregion
603     }
604 }
605