예제 #1
0
 private void ResolveSourceKey(StateChange <TEntityA, TEntityB> stateChange)
 {
     TimedAction(() =>
     {
         stateChange.SourceKey = stateChange.CurrentSyncState?.Key ?? stateChange.LastSyncState?.Key;
         Log.Debug($"{stateChange}");
     }, nameof(ResolveSourceKey));
 }
예제 #2
0
        protected virtual List <StateChange <TEntityA, TEntityB> > GetStateChanges()
        {
            var result        = new List <StateChange <TEntityA, TEntityB> >();
            var currentStates = DataSource.GetStates().ToList();
            var lastStates    = SyncStateStorage.GetStates(Context).ToList();

            foreach (var currentState in currentStates)
            {
                var lastState = lastStates.FirstOrDefault(x => x.Key == currentState.Key);

                if (lastState == null)
                {
                    var insert = new StateChange <TEntityA, TEntityB>
                    {
                        CurrentSyncState = currentState
                    };
                    result.Add(insert);
                    Log.Debug(
                        $"Theoretical INSERT: CurrentState = '{insert.CurrentSyncState}', LastState = '{insert.LastSyncState}'");
                }
                else
                {
                    if (lastState.Hash != currentState.Hash)
                    {
                        var update = new StateChange <TEntityA, TEntityB>
                        {
                            CurrentSyncState = currentState,
                            LastSyncState    = lastState
                        };
                        result.Add(update);
                        Log.Debug(
                            $"Theoretical UPDATE: CurrentState = '{update.CurrentSyncState}', LastState = '{update.LastSyncState}'");
                    }
                }
            }

            foreach (var lastState in lastStates)
            {
                var currentState = currentStates.SingleOrDefault(x => x.Key == lastState.Key);

                if (currentState == null)
                {
                    var delete = new StateChange <TEntityA, TEntityB>
                    {
                        LastSyncState = lastState
                    };
                    result.Add(delete);
                    Log.Debug(
                        $"Theoretical DELETE: CurrentState = '{delete.CurrentSyncState}', LastState = '{delete.LastSyncState}'");
                }
            }

            Log.Info($"Detected {result.Count} changes. Inserts: {result.Count(c => c.Operation == OperationEnum.Insert)}, Updates: {result.Count(c => c.Operation == OperationEnum.Update)}, Deletes: {result.Count(c => c.Operation == OperationEnum.Delete)}, Unknowns: {result.Count(c => c.Operation == OperationEnum.None)}");
            return(result);
        }
예제 #3
0
 private void LookupSourceItem(StateChange <TEntityA, TEntityB> stateChange)
 {
     TimedAction(() =>
     {
         if (stateChange.SourceKey == null)
         {
             return;
         }
         stateChange.SourceItem = DataSource.GetByKey(stateChange.SourceKey);
         Log.Debug($"{stateChange}");
     }, nameof(LookupSourceItem));
 }
예제 #4
0
        private void ResolveTargetKey(StateChange <TEntityA, TEntityB> stateChange)
        {
            TimedAction(() =>
            {
                if (stateChange.SourceKey == null)
                {
                    return;
                }

                stateChange.SyncKeyMap = SyncKeyMapStorage.GetBySourceKey(Context, stateChange.SourceKey);
                stateChange.TargetKey  = stateChange.SyncKeyMap?.TargetKey;

                Log.Debug($"{stateChange}");
            }, nameof(ResolveTargetKey));
        }
예제 #5
0
        private void LookupTargetItemFallback(StateChange <TEntityA, TEntityB> stateChange)
        {
            TimedAction(() =>
            {
                if (stateChange.TargetItem != null)
                {
                    return;
                }

                if (stateChange.SourceItem != null)
                {
                    // lets try to get target item key by source item
                    stateChange.TargetKey = DataTarget.GetKeyBySourceItem(stateChange.SourceItem);
                    LookupTargetItem(stateChange);
                }
                Log.Debug($"{stateChange}");
            }, nameof(LookupTargetItemFallback));
        }
예제 #6
0
        private void PerformDataOperation(StateChange <TEntityA, TEntityB> stateChange)
        {
            TimedAction(() =>
            {
                Log.Debug($"Performing Data Operation ({stateChange.Operation}) on Entity: {stateChange}");

                switch (stateChange.Operation)
                {
                case OperationEnum.Insert:
                    stateChange.TargetKey = DataTarget.Insert(stateChange.SourceItem);
                    Log.Debug(
                        $"INSERT: SourceKey = '{stateChange.SourceKey}', TargetKey = '{stateChange.TargetKey}'");
                    ExecuteNestedTasks?.Invoke(stateChange.SourceKey, stateChange.TargetKey, stateChange.SourceItem,
                                               stateChange.TargetItem, stateChange);
                    break;

                case OperationEnum.Update:
                    stateChange.TargetKey = DataTarget.Update(stateChange.SourceItem, stateChange.TargetItem);
                    Log.Debug(
                        $"UPDATE: SourceKey = '{stateChange.SourceKey}', TargetKey = '{stateChange.TargetKey}'");
                    ExecuteNestedTasks?.Invoke(stateChange.SourceKey, stateChange.TargetKey, stateChange.SourceItem,
                                               stateChange.TargetItem, stateChange);
                    break;

                case OperationEnum.Delete:
                    Log.Debug(
                        $"DELETE: SourceKey = '{stateChange.SourceKey}', TargetKey = '{stateChange.TargetKey}'");
                    ExecuteNestedTasks?.Invoke(stateChange.SourceKey, stateChange.TargetKey, stateChange.SourceItem,
                                               stateChange.TargetItem, stateChange);
                    DataTarget.Delete(stateChange.TargetItem);
                    stateChange.TargetKey = null;
                    break;

                case OperationEnum.None:
                    break;
                }
            }, nameof(PerformDataOperation));
        }
예제 #7
0
        private void DetectDataOperation(StateChange <TEntityA, TEntityB> stateChange)
        {
            TimedAction(() =>
            {
                if ((stateChange.SourceItem != null) && (stateChange.TargetItem == null))
                {
                    stateChange.Operation = OperationEnum.Insert;
                    return;
                }
                if ((stateChange.SourceItem != null) && (stateChange.TargetItem != null))
                {
                    stateChange.Operation = OperationEnum.Update;
                    return;
                }

                if ((stateChange.SourceItem == null) && (stateChange.TargetItem != null))
                {
                    Log.Debug($"DELETE: TargetKey = '{stateChange.TargetKey}'");
                    stateChange.Operation = OperationEnum.Delete;
                }
                Log.Debug($"{stateChange}");
            }, nameof(DetectDataOperation));
        }
예제 #8
0
        private void UpdateSyncState(StateChange <TEntityA, TEntityB> stateChange)
        {
            TimedAction(() =>
            {
                switch (stateChange.Operation)
                {
                case OperationEnum.Insert:
                case OperationEnum.Update:

                    if (stateChange.LastSyncState == null)
                    {
                        SyncStateStorage.Create(Context, stateChange.CurrentSyncState.Key,
                                                stateChange.CurrentSyncState.Hash);
                    }
                    else
                    {
                        var syncState     = stateChange.LastSyncState;
                        syncState.Context = Context;
                        syncState.Hash    = stateChange.CurrentSyncState.Hash;
                        SyncStateStorage.Update(syncState);
                    }
                    break;

                case OperationEnum.None:
                case OperationEnum.Delete:
                    if (stateChange.LastSyncState != null)
                    {
                        SyncStateStorage.Delete(stateChange.LastSyncState);
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                Log.Debug($"{stateChange}");
            }, nameof(UpdateSyncState));
        }