Applies the parsed table update (delta) to this table. This updates the internal data structures and indices, but does not invoke user callbacks. Should be called before PostApply, after PreApply.
(IEventContext context, IParsedTableUpdate parsedTableUpdate)
| 446 | /// Should be called before PostApply, after PreApply. |
| 447 | /// </summary> |
| 448 | void IRemoteTableHandle.Apply(IEventContext context, IParsedTableUpdate parsedTableUpdate) |
| 449 | { |
| 450 | var delta = (ParsedTableUpdate)parsedTableUpdate; |
| 451 | |
| 452 | if (IsEventTable) |
| 453 | { |
| 454 | // Event tables: don't store rows in the cache or update indices. |
| 455 | // Just collect the event rows so PostApply can fire OnInsert callbacks. |
| 456 | if (delta.EventRows != null) |
| 457 | { |
| 458 | foreach (var row in delta.EventRows) |
| 459 | { |
| 460 | wasInserted.Add(new KeyValuePair<object, Row>(row, row)); |
| 461 | } |
| 462 | } |
| 463 | return; |
| 464 | } |
| 465 | |
| 466 | try |
| 467 | { |
| 468 | Entries.Apply(delta.Delta, wasInserted, wasUpdated, wasRemoved); |
| 469 | } |
| 470 | catch (Exception e) |
| 471 | { |
| 472 | var deltaString = parsedTableUpdate.ToString(); |
| 473 | deltaString = deltaString[..Math.Min(deltaString.Length, 10_000)]; |
| 474 | var entriesString = Entries.ToString(); |
| 475 | entriesString = entriesString[..Math.Min(entriesString.Length, 10_000)]; |
| 476 | throw new Exception($"While table `{RemoteTableName}` was applying:\n{deltaString} \nto:\n{entriesString}", e); |
| 477 | } |
| 478 | |
| 479 | // Update indices. |
| 480 | // This is a local operation -- it only looks at our indices and doesn't invoke user code. |
| 481 | // So we don't need to wait for other tables to be updated to do it. |
| 482 | // (And we need to do it before any PostApply is called.) |
| 483 | // Reminder: We need to loop through the removed entries to delete them prior to inserting the new entries, |
| 484 | // in order to avoid keys an error with the same key already added. |
| 485 | foreach (var (_, value) in wasRemoved) |
| 486 | { |
| 487 | if (value is Row oldRow) |
| 488 | { |
| 489 | OnInternalDeleteHandler.Invoke(oldRow); |
| 490 | } |
| 491 | } |
| 492 | foreach (var (_, value) in wasInserted) |
| 493 | { |
| 494 | if (value is Row newRow) |
| 495 | { |
| 496 | OnInternalInsertHandler.Invoke(newRow); |
| 497 | } |
| 498 | else |
| 499 | { |
| 500 | throw new Exception($"Invalid row type for table {RemoteTableName}: {value.GetType().Name}"); |
| 501 | } |
| 502 | } |
| 503 | foreach (var (_, oldValue, newValue) in wasUpdated) |
| 504 | { |
| 505 | if (oldValue is Row oldRow) |