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