static IDisposable OperationLogic_SurroundOperation(IOperation operation, OperationLogEntity log, Entity?entity, object?[]?args) { if (entity != null && ShouldLog.Invoke(entity, operation)) { if (operation.OperationType == OperationType.Execute && !entity.IsNew && ((IEntityOperation)operation).CanBeModified) { entity = RetrieveFresh(entity); } using (CultureInfoUtils.ChangeBothCultures(Schema.Current.ForceCultureInfo)) { log.Mixin <DiffLogMixin>().InitialState = entity.Dump(); } } return(new Disposable(() => { var target = log.GetTemporalTarget(); if (target != null && ShouldLog.Invoke(target, operation) && operation.OperationType != OperationType.Delete) { using (CultureInfoUtils.ChangeBothCultures(Schema.Current.ForceCultureInfo)) { log.Mixin <DiffLogMixin>().FinalState = target.Dump(); } } })); }
public static MinMax <OperationLogEntity?> OperationLogNextPrev(OperationLogEntity log) { var logs = Database.Query <OperationLogEntity>().Where(a => a.Exception == null && a.Target == log.Target); return(new MinMax <OperationLogEntity?>( log.Mixin <DiffLogMixin>().InitialState == null ? null : logs.Where(a => a.End < log.Start).OrderByDescending(a => a.End).FirstOrDefault(), log.Mixin <DiffLogMixin>().FinalState == null ? null : logs.Where(a => a.Start > log.End).OrderBy(a => a.Start).FirstOrDefault())); }
void OperationLog_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { tabs.Items.Clear(); OperationLogEntity log = (OperationLogEntity)e.NewValue; if (log == null) { return; } var mixin = log.Mixin <DiffLogMixin>(); var minMax = Server.Return((IDiffLogServer s) => s.OperationLogNextPrev(log)); TabItem selected = null; TabItem bestSelected = null; if (mixin.InitialState != null) { var prev = minMax.Min; if (prev != null && prev.Mixin <DiffLogMixin>().FinalState != null) { tabs.Items.Add(new LinkTabItem { Header = TextWithLinkIcon(DiffLogMessage.PreviousLog.NiceToString()) .Do(a => a.ToolTip = DiffLogMessage.NavigatesToThePreviousOperationLog.NiceToString()), DataContext = prev, }); tabs.Items.Add(new TabItem { Header = IconPair("fast-back.png", "back.png", prev.Mixin <DiffLogMixin>().FinalState == mixin.InitialState) .Do(a => a.ToolTip = DiffLogMessage.DifferenceBetweenFinalStateOfPreviousLogAndTheInitialState.NiceToString()), Content = Diff(prev.Mixin <DiffLogMixin>().FinalState, mixin.InitialState), }); } tabs.Items.Add(selected = new TabItem { Header = new TextBlock { Text = ReflectionTools.GetPropertyInfo(() => mixin.InitialState).NiceName() } .Do(a => a.ToolTip = DiffLogMessage.StateWhenTheOperationStarted.NiceToString()), Content = new TextBlock(new Run(mixin.InitialState)) { FontFamily = font }, }); } if (mixin.InitialState != null && mixin.FinalState != null) { tabs.Items.Add(bestSelected = new TabItem { Header = IconPair("back.png", "fore.png", mixin.InitialState == mixin.FinalState) .Do(a => a.ToolTip = DiffLogMessage.DifferenceBetweenInitialStateAndFinalState.NiceToString()), Content = Diff(mixin.InitialState, mixin.FinalState), }); } if (mixin.FinalState != null) { tabs.Items.Add(selected = new TabItem { Header = new TextBlock { Text = ReflectionTools.GetPropertyInfo(() => mixin.FinalState).NiceName() } .Do(a => a.ToolTip = DiffLogMessage.StateWhenTheOperationFinished.NiceToString()), Content = new TextBlock(new Run(mixin.FinalState)) { FontFamily = font }, }); var next = minMax.Max; if (next != null && next.Mixin <DiffLogMixin>().InitialState != null) { tabs.Items.Add(new TabItem { Header = IconPair("fore.png", "fast-fore.png", mixin.FinalState == next.Mixin <DiffLogMixin>().InitialState) .Do(a => a.ToolTip = DiffLogMessage.DifferenceBetweenFinalStateAndTheInitialStateOfNextLog.NiceToString()), Content = Diff(mixin.FinalState, next.Mixin <DiffLogMixin>().InitialState), }); tabs.Items.Add(new LinkTabItem { Header = TextWithLinkIcon(DiffLogMessage.NextLog.NiceToString()) .Do(a => a.ToolTip = DiffLogMessage.NavigatesToTheNextOperationLog.NiceToString()), DataContext = next, }); } else { var entity = Server.Exists(log.Target) ? log.Target.RetrieveAndForget() : null; if (entity != null) { var dump = entity.Dump(); tabs.Items.Add(new TabItem { Header = IconPair("fore.png", "fast-fore.png", mixin.FinalState == dump) .Do(a => a.ToolTip = DiffLogMessage.DifferenceBetweenFinalStateAndTheInitialStateOfNextLog.NiceToString()), Content = Diff(mixin.FinalState, dump), }); tabs.Items.Add(new LinkTabItem { Header = TextWithLinkIcon(DiffLogMessage.CurrentEntity.NiceToString()) .Do(a => a.ToolTip = DiffLogMessage.NavigatesToTheCurrentEntity.NiceToString()), DataContext = entity, }); } } } tabs.SelectedItem = bestSelected ?? selected; }