public static Dictionary <Guid, IntegrityCheck> GetErrors(Modifiable mod) { var graph = GraphExplorer.PreSaving(() => GraphExplorer.FromRoot(mod)); var error = GraphExplorer.FullIntegrityCheck(graph); return(error); }
protected override string ChildPropertyValidation(ModifiableEntity sender, PropertyInfo pi) { if (sender is PanelPartEmbedded part) { if (pi.Name == nameof(part.StartColumn)) { if (part.StartColumn + part.Columns > 12) { return(DashboardMessage.Part0IsTooLarge.NiceToString(part)); } var other = Parts.TakeWhile(p => p != part) .FirstOrDefault(a => a.Row == part.Row && a.ColumnInterval().Overlaps(part.ColumnInterval())); if (other != null) { return(DashboardMessage.Part0OverlapsWith1.NiceToString(part, other)); } } if (entityType != null && pi.Name == nameof(part.Content) && part.Content != null) { var idents = GraphExplorer.FromRoot((Entity)part.Content).OfType <Entity>(); string errorsUserQuery = idents.OfType <IHasEntitytype>() .Where(uc => uc.EntityType != null && !uc.EntityType.Is(EntityType)) .ToString(uc => DashboardMessage._0Is1InstedOf2In3.NiceToString(NicePropertyName(() => EntityType), uc.EntityType, entityType, uc), "\r\n"); return(errorsUserQuery.DefaultText(null)); } } return(base.ChildPropertyValidation(sender, pi)); }
public IUserAssetEntity GetEntity(Guid guid) { return(entities.GetOrCreate(guid, () => { var element = elements.GetOrThrow(guid); Type type = UserAssetNames.GetOrThrow(element.Name.ToString()); var entity = giRetrieveOrCreate.GetInvoker(type)(guid); entity.FromXml(element, this); previews.Add(guid, new UserAssetPreviewLineEmbedded { Text = entity.ToString() !, Type = entity.GetType().ToTypeEntity(), Guid = guid, Action = entity.IsNew ? EntityAction.New : customResolutionModel.ContainsKey(entity.Guid) ? EntityAction.Different : GraphExplorer.FromRoot((Entity)entity).Any(a => a.Modified != ModifiedState.Clean) ? EntityAction.Different : EntityAction.Identical, CustomResolution = customResolutionModel.TryGetCN(entity.Guid), }); return entity; }));
private static void CleanChanges(ModelEntity rules) { var graph = GraphExplorer.FromRoot(rules); var conditions = graph.OfType <TypeAllowedAndConditions>().SelectMany(a => a.Conditions).ToList(); conditions.ForEach(con => graph.UnionWith(GraphExplorer.FromRoot(con))); GraphExplorer.CleanModifications(graph); GraphExplorer.SetDummyRowIds(graph); }
public void AddFullGraph(ModifiableEntity ie) { DirectedGraph <Modifiable> modifiables = GraphExplorer.FromRoot(ie); foreach (var ident in modifiables.OfType <Entity>().Where(ident => !ident.IsNew)) { Add(ident); } }
static T AssertEntity <T>(this T result, Entity entity) where T : IEntityOperation { if (result.Lite) { var list = GraphExplorer.FromRoot(entity).Where(a => a.Modified == ModifiedState.SelfModified); if (list.Any()) { throw new InvalidOperationException("Operation {0} needs a Lite or a clean entity, but the entity has changes:\r\n {1}" .FormatWith(result.OperationSymbol, list.ToString("\r\n"))); } } return(result); }
private bool HasErrors() { GraphExplorer.PreSaving(() => GraphExplorer.FromRoot(Request)); var errors = Request.FullIntegrityCheck(); if (errors == null) { return(false); } MessageBox.Show(Window.GetWindow(this), "There are errors in the chart settings:\r\n" + errors, "Errors in the chart", MessageBoxButton.OK, MessageBoxImage.Stop); return(true); }
public static T SetNotModifiedGraph <T>(this T entity, PrimaryKey id) where T : Entity { foreach (var item in GraphExplorer.FromRoot(entity).Where(a => a.Modified != ModifiedState.Sealed)) { item.SetNotModified(); if (item is Entity e) { e.SetId(new PrimaryKey("invalidId")); } } entity.SetId(id); return(entity); }
public async Task <List <EvalEntityError> > GetEvalErrors([Required, FromBody] QueryEntitiesRequestTS request) { var allEntities = await QueryLogic.Queries.GetEntitiesLite(request.ToQueryEntitiesRequest()).Select(a => a.Entity).ToListAsync(); return(allEntities.Select(entity => { GraphExplorer.PreSaving(() => GraphExplorer.FromRoot(entity)); return new EvalEntityError { lite = entity.ToLite(), error = entity.FullIntegrityCheck().EmptyIfNull().Select(a => a.Value).SelectMany(a => a.Errors.Values).ToString("\n") }; }) .Where(ee => ee.error.HasText()) .ToList()); }
public void SaveMList() { using (var tr = new Transaction()) using (OperationLogic.AllowSave <LabelEntity>()) using (OperationLogic.AllowSave <CountryEntity>()) using (OperationLogic.AllowSave <AlbumEntity>()) using (OperationLogic.AllowSave <ArtistEntity>()) { var prev = Database.MListQuery((AlbumEntity a) => a.Songs).Count(); Type[] types = typeof(int).Assembly.GetTypes().Where(a => a.Name.Length > 3 && a.Name.StartsWith("A")).ToArray(); AlbumEntity album = new AlbumEntity() { Name = "System Greatest hits", Author = new ArtistEntity { Name = ".Net Framework" }, Year = 2001, Songs = types.Select(t => new SongEmbedded() { Name = t.Name }).ToMList(), State = AlbumState.Saved, Label = new LabelEntity { Name = "Four Music", Country = new CountryEntity { Name = "Germany" }, Node = MusicLoader.NextLabelNode() }, }.Save(); Assert.All(GraphExplorer.FromRoot(album), a => Assert.False(a.IsGraphModified)); Assert.Equal(prev + types.Length, Database.MListQuery((AlbumEntity a) => a.Songs).Count()); album.Name += "Updated"; album.Save(); album.Songs.ForEach(a => a.Name = "Updated"); album.Save(); //tr.Commit(); } }
public EntityPackTS ExecuteEntity(EntityOperationRequest request) { Entity entity; try { entity = OperationLogic.ServiceExecute(request.entity, request.GetOperationSymbol(request.entity.GetType()), request.args); } catch (IntegrityCheckException ex) { GraphExplorer.SetValidationErrors(GraphExplorer.FromRoot(request.entity), ex); this.Validate(request, "request"); throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, this.ModelState)); } return(SignumServer.GetEntityPack(entity)); }
public ActionResult <EntityPackTS> ExecuteEntity([Required, FromBody] EntityOperationRequest request) { Entity entity; try { entity = OperationLogic.ServiceExecute(request.entity, request.GetOperationSymbol(request.entity.GetType()), request.args); } catch (IntegrityCheckException ex) { GraphExplorer.SetValidationErrors(GraphExplorer.FromRoot(request.entity), ex); this.TryValidateModel(request, "request"); return(BadRequest(this.ModelState)); } return(SignumServer.GetEntityPack(entity)); }
public ActionResult <EntityPackWithIssues> SaveWorkflow([Required, FromBody] EntityOperationRequest request) { WorkflowEntity entity; List <WorkflowIssue> issuesContainer = new List <WorkflowIssue>(); try { entity = ((WorkflowEntity)request.entity).Execute(WorkflowOperation.Save, (request.args.EmptyIfNull()).And(issuesContainer).ToArray()); } catch (IntegrityCheckException ex) { GraphExplorer.SetValidationErrors(GraphExplorer.FromRoot(request.entity), ex); this.TryValidateModel(request, "request"); this.ModelState.AddModelError("workflowIssues", JsonConvert.SerializeObject(issuesContainer, SignumServer.JsonSerializerSettings)); return(BadRequest(this.ModelState)); } return(new EntityPackWithIssues(SignumServer.GetEntityPack(entity), issuesContainer)); }
public async Task <List <EvalEntityError> > GetEvalErrors([Required, FromBody] QueryEntitiesRequestTS request) { DynamicPanelPermission.ViewDynamicPanel.AssertAuthorized(); var allEntities = await QueryLogic.Queries.GetEntitiesLite(request.ToQueryEntitiesRequest(SignumServer.JsonSerializerOptions)).Select(a => a.Entity).ToListAsync(); return(allEntities.Select(entity => { GraphExplorer.PreSaving(() => GraphExplorer.FromRoot(entity)); return new EvalEntityError { lite = entity.ToLite(), error = entity.FullIntegrityCheck().EmptyIfNull().Select(a => a.Value).SelectMany(a => a.Errors.Values).ToString("\n") }; }) .Where(ee => ee.error.HasText()) .ToList()); }
public void SaveMList() { using (Transaction tr = new Transaction()) using (OperationLogic.AllowSave <AlbumEntity>()) using (OperationLogic.AllowSave <ArtistEntity>()) { var prev = Database.MListQuery((AlbumEntity a) => a.Songs).Count(); Type[] types = typeof(int).Assembly.GetTypes().Where(a => a.Name.Length > 3 && a.Name.StartsWith("A")).ToArray(); AlbumEntity album = new AlbumEntity() { Name = "System Greatest hits", Author = new ArtistEntity { Name = ".Net Framework" }, Year = 2001, Songs = types.Select(t => new SongEntity() { Name = t.Name }).ToMList(), State = AlbumState.Saved }.Save(); Assert2.AssertAll(GraphExplorer.FromRoot(album), a => !a.IsGraphModified); Assert.AreEqual(prev + types.Length, Database.MListQuery((AlbumEntity a) => a.Songs).Count()); album.Name += "Updated"; album.Save(); album.Songs.ForEach(a => a.Name = "Updated"); album.Save(); //tr.Commit(); } }
public static FluentInclude <T> WithVirtualMList <T, L>(this FluentInclude <T> fi, Expression <Func <T, MList <L> > > mListField, Expression <Func <L, Lite <T>?> > backReference, Action <L, T>?onSave = null, Action <L, T>?onRemove = null, bool?lazyRetrieve = null, bool?lazyDelete = null) //To avoid StackOverflows where T : Entity where L : Entity { fi.SchemaBuilder.Include <L>(); var mListPropertRoute = PropertyRoute.Construct(mListField); var backReferenceRoute = PropertyRoute.Construct(backReference, avoidLastCasting: true); if (fi.SchemaBuilder.Settings.FieldAttribute <IgnoreAttribute>(mListPropertRoute) == null) { throw new InvalidOperationException($"The property {mListPropertRoute} should have an IgnoreAttribute to be used as Virtual MList"); } RegisteredVirtualMLists.GetOrCreate(typeof(T)).Add(mListPropertRoute, new VirtualMListInfo(mListPropertRoute, backReferenceRoute)); var defLazyRetrieve = lazyRetrieve ?? (typeof(L) == typeof(T)); var defLazyDelete = lazyDelete ?? (typeof(L) == typeof(T)); Func <T, MList <L> > getMList = GetAccessor(mListField); Action <L, Lite <T> >?setter = null; bool preserveOrder = fi.SchemaBuilder.Settings.FieldAttributes(mListPropertRoute) ! .OfType <PreserveOrderAttribute>() .Any(); if (preserveOrder && !typeof(ICanBeOrdered).IsAssignableFrom(typeof(L))) { throw new InvalidOperationException($"'{typeof(L).Name}' should implement '{nameof(ICanBeOrdered)}' because '{ReflectionTools.GetPropertyInfo(mListField).Name}' contains '[{nameof(PreserveOrderAttribute)}]'"); } var sb = fi.SchemaBuilder; if (defLazyRetrieve) { sb.Schema.EntityEvents <T>().Retrieved += (T e, PostRetrievingContext ctx) => { if (ShouldAvoidMListType(typeof(L))) { return; } var mlist = getMList(e); if (mlist == null) { return; } var query = Database.Query <L>() .Where(line => backReference.Evaluate(line) == e.ToLite()); MList <L> newList = preserveOrder ? query.ToVirtualMListWithOrder() : query.ToVirtualMList(); mlist.AssignAndPostRetrieving(newList, ctx); }; } if (preserveOrder) { sb.Schema.EntityEvents <T>().RegisterBinding <MList <L> >(mListField, shouldSet: () => !defLazyRetrieve && !VirtualMList.ShouldAvoidMListType(typeof(L)), valueExpression: (e, rowId) => Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMListWithOrder(), valueFunction: (e, rowId, retriever) => Schema.Current.CacheController <L>() !.Enabled ? Schema.Current.CacheController <L>() !.RequestByBackReference <T>(retriever, backReference, e.ToLite()).ToVirtualMListWithOrder(): Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMListWithOrder() ); } else { sb.Schema.EntityEvents <T>().RegisterBinding(mListField, shouldSet: () => !defLazyRetrieve && !VirtualMList.ShouldAvoidMListType(typeof(L)), valueExpression: (e, rowId) => Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMList(), valueFunction: (e, rowId, retriever) => Schema.Current.CacheController <L>() !.Enabled ? Schema.Current.CacheController <L>() !.RequestByBackReference <T>(retriever, backReference, e.ToLite()).ToVirtualMList() : Database.Query <L>().Where(line => backReference.Evaluate(line) == e.ToLite()).ExpandLite(line => backReference.Evaluate(line), ExpandLite.ToStringLazy).ToVirtualMList() ); } sb.Schema.EntityEvents <T>().PreSaving += (T e, PreSavingContext ctx) => { if (VirtualMList.ShouldAvoidMListType(typeof(L))) { return; } var mlist = getMList(e); if (mlist == null) { return; } if (mlist.Count > 0) { var graph = Saver.PreSaving(() => GraphExplorer.FromRoot(mlist).RemoveAllNodes(ctx.Graph)); GraphExplorer.PropagateModifications(graph.Inverse()); var errors = GraphExplorer.FullIntegrityCheck(graph); if (errors != null) { #if DEBUG var withEntites = errors.WithEntities(graph); throw new IntegrityCheckException(withEntites); #else throw new IntegrityCheckException(errors); #endif } } if (mlist.IsGraphModified) { e.SetSelfModified(); } }; sb.Schema.EntityEvents <T>().Saving += (T e) => { if (VirtualMList.ShouldAvoidMListType(typeof(L))) { return; } var mlist = getMList(e); if (mlist == null) { return; } if (preserveOrder) { mlist.ForEach((o, i) => ((ICanBeOrdered)o).Order = i); } if (GraphExplorer.IsGraphModified(mlist)) { e.SetModified(); } }; sb.Schema.EntityEvents <T>().Saved += (T e, SavedEventArgs args) => { if (VirtualMList.ShouldAvoidMListType(typeof(L))) { return; } var mlist = getMList(e); if (mlist != null && !GraphExplorer.IsGraphModified(mlist)) { return; } if (!(args.WasNew || ShouldConsiderNew(typeof(T)))) { var oldElements = mlist.EmptyIfNull().Where(line => !line.IsNew); var query = Database.Query <L>() .Where(p => backReference.Evaluate(p) == e.ToLite()); if (onRemove == null) { query.Where(p => !oldElements.Contains(p)).UnsafeDelete(); } else { query.Where(p => !oldElements.Contains(p)).ToList().ForEach(line => onRemove !(line, e)); } } if (mlist != null) { if (mlist.Any()) { if (setter == null) { setter = CreateSetter(backReference); } mlist.ForEach(line => setter !(line, e.ToLite())); if (onSave == null) { mlist.SaveList(); } else { mlist.ForEach(line => { if (GraphExplorer.IsGraphModified(line)) { onSave !(line, e); } }); } var priv = (IMListPrivate)mlist; for (int i = 0; i < mlist.Count; i++) { if (priv.GetRowId(i) == null) { priv.SetRowId(i, mlist[i].Id); } } } mlist.SetCleanModified(false); } }; sb.Schema.EntityEvents <T>().PreUnsafeDelete += query => { if (VirtualMList.ShouldAvoidMListType(typeof(L))) { return(null); } //You can do a VirtualMList to itself at the table level, but there should not be cycles inside the instances var toDelete = Database.Query <L>().Where(se => query.Any(e => backReference.Evaluate(se).Is(e))); if (defLazyDelete) { if (toDelete.Any()) { toDelete.UnsafeDelete(); } } else { toDelete.UnsafeDelete(); } return(null); }; return(fi); }
public Dictionary <Guid, IntegrityCheck>?FullIntegrityCheck() { var graph = GraphExplorer.FromRoot(this); return(GraphExplorer.FullIntegrityCheck(graph)); }
public void SetGraphErrors(IntegrityCheckException ex) { GraphExplorer.SetValidationErrors(GraphExplorer.FromRoot(this), ex); }
public bool HasChanges() { var graph = GraphExplorer.FromRoot(this); return(graph.Any(a => a.Modified == ModifiedState.SelfModified)); }
static void OperationExecute(IEntityOperationContext eoc) { if (eoc.CanExecute != null) { throw new ApplicationException("Operation {0} is disabled: {1}".FormatWith(eoc.OperationInfo.OperationSymbol, eoc.CanExecute)); } if (eoc.OperationSettings != null && eoc.OperationSettings.HasClick) { IEntity newIdent = eoc.OperationSettings.OnClick(eoc); if (newIdent != null) { eoc.EntityControl.RaiseEvent(new ChangeDataContextEventArgs(newIdent)); } } else { Entity ident = (Entity)(IEntity)eoc.Entity; if (eoc.OperationInfo.OperationType == OperationType.Execute) { if (eoc.OperationInfo.Lite.Value) { if (eoc.EntityControl.LooseChangesIfAny()) { if (eoc.ConfirmMessage()) { Lite <Entity> lite = ident.ToLite(); IEntity newIdent = Server.Return((IOperationServer s) => s.ExecuteOperationLite(lite, eoc.OperationInfo.OperationSymbol, null)); if (eoc.OperationInfo.Returns) { eoc.EntityControl.RaiseEvent(new ChangeDataContextEventArgs(newIdent)); } } } } else { if (eoc.ConfirmMessage()) { try { IEntity newIdent = Server.Return((IOperationServer s) => s.ExecuteOperation(ident, eoc.OperationInfo.OperationSymbol, null)); if (eoc.OperationInfo.Returns) { eoc.EntityControl.RaiseEvent(new ChangeDataContextEventArgs(newIdent)); } } catch (IntegrityCheckException e) { GraphExplorer.SetValidationErrors(GraphExplorer.FromRoot(ident), e); throw e; } } } } else if (eoc.OperationInfo.OperationType == OperationType.ConstructorFrom) { if (eoc.OperationInfo.Lite.Value && !eoc.EntityControl.LooseChangesIfAny()) { return; } if (!eoc.ConfirmMessage()) { return; } IEntity result = (Entity) new ConstructorContext(eoc.EntityControl, eoc.OperationInfo).SurroundConstructUntyped(eoc.OperationInfo.ReturnType, ctx => { Entity r; if (eoc.OperationInfo.Lite.Value) { r = Server.Return((IOperationServer s) => s.ConstructFromLite(ident.ToLite(), eoc.OperationInfo.OperationSymbol, null)); } else { try { r = Server.Return((IOperationServer s) => s.ConstructFrom(ident, eoc.OperationInfo.OperationSymbol, null)); } catch (IntegrityCheckException e) { GraphExplorer.SetValidationErrors(GraphExplorer.FromRoot(ident), e); throw e; } } if (r == null) { MessageBox.Show(Window.GetWindow(eoc.EntityControl), OperationMessage.TheOperation0DidNotReturnAnEntity.NiceToString().FormatWith(eoc.OperationInfo.OperationSymbol.NiceToString())); } return(r); }); if (result != null) { Navigator.Navigate(result); } } else if (eoc.OperationInfo.OperationType == OperationType.Delete) { if (eoc.ConfirmMessage()) { Lite <Entity> lite = ident.ToLite(); Server.Execute((IOperationServer s) => s.DeleteLite(lite, eoc.OperationInfo.OperationSymbol, null)); Window.GetWindow(eoc.EntityControl).Close(); } } } }