public override Daton Clone(DatonDef datondef) { var c = base.Clone(datondef) as Viewon; c.IsCompleteLoad = IsCompleteLoad; return(c); }
/// <summary> /// Validate the criteria of a requested viewon and populate Errors in this instance with the problems found. /// </summary> public async Task ValidateCriteria(DatonDef datondef, ViewonKey viewonKey) { Errors = new List <string>(); //built-in validation if (viewonKey.Criteria != null) { foreach (var cri in viewonKey.Criteria) { var coldef = datondef.CriteriaDef.FindCol(cri.Name); if (coldef == null) { Errors.Add("Unknown parameter: " + cri.Name); } else { ValidateCol(coldef, cri.PackedValue); } } } //custom validation var tempViewon0 = Utils.Construct(datondef.Type); if (tempViewon0 is Viewon tempViewon) { await tempViewon.ValidateCriteria(User, viewonKey, message => Errors.Add(message)); } }
/// <summary> /// Return readable strings describing any disallowed writes for this user /// </summary> /// <param name="pristineDaton">null for new unsaved persistons, else the pristine version being edited</param> public IEnumerable <string> GetDisallowedWrites(Daton pristineDaton, DatonDef datondef, PersistonDiff diff) { var errors = new List <string>(); FindDisallowedWrites(errors, pristineDaton, datondef.MainTableDef, diff.MainTable); return(errors); }
/// <summary> /// Clone all fields and child tables declared in datondef /// </summary> public virtual Daton Clone(DatonDef datondef) { if (datondef.MultipleMainRows) { var target = Utils.Construct(datondef.Type) as Daton; target.Key = Key; target.Version = Version; var listField = datondef.Type.GetField(datondef.MainTableDef.Name); var sourceList = listField.GetValue(this) as IList; var targetList = listField.GetValue(target) as IList; if (sourceList != null) { if (targetList == null) { targetList = Utils.Construct(listField.FieldType) as IList; listField.SetValue(target, targetList); } foreach (var row in sourceList) { if (row is Row trow) { targetList.Add(trow.Clone(datondef.MainTableDef)); } } } return(target); } else //single main row { var target = Clone(datondef.MainTableDef) as Daton; target.Key = Key; target.Version = Version; return(target); } }
/// <summary> /// Apply the changes in this diff to the given target /// </summary> public ApplyAction ApplyTo(DatonDef datondef, Persiston target) { if (MainTable.Count == 0) { return(ApplyAction.NoChanges); } if (datondef.MultipleMainRows) { bool anyChanges = false; var field = target.GetType().GetField(datondef.MainTableDef.Name); var targetList = Utils.CreateOrGetFieldValue <IList>(target, field); if (targetList == null) { throw new Exception($"Row class {target.GetType().Name} must include field member {datondef.MainTableDef.Name}"); } foreach (var source in MainTable) { anyChanges |= ApplyDiffRowToList(datondef.MainTableDef, source, targetList); } return(anyChanges ? ApplyAction.Changes : ApplyAction.NoChanges); } else { //handle top level edge cases to ensure the key matches the new/modified/delete status of the top row if (MainTable.Count != 1) { throw new Exception("For single-main-table persistons the diff may only include the single main row"); } bool diffIsNewRow = MainTable[0].Kind == DiffKind.NewRow; if (diffIsNewRow != target.Key.IsNew) { throw new Exception("The key specifies a new row but the diff does not indicate a new row; or the key specifies modified/delete but the diff indicates a new row"); } var source = MainTable[0]; if (source.Kind == DiffKind.DeletedRow) { return(ApplyAction.PersistonDeleted); } //reached here, so its a plain update of the single row; primary key ignored bool anyChanges = false; foreach (string colName in source.Columns.Keys) { anyChanges |= SetValue(datondef.MainTableDef, source, colName, target); } //child tables anyChanges |= ApplyChildTables(source, target, target.GetType()); return(anyChanges ? ApplyAction.Changes : ApplyAction.NoChanges); } }
/// <summary> /// Calls Recompute on each row in the daton /// </summary> public void Recompute(DatonDef datondef) { var r = RecurPoint.FromDaton(datondef, this); if (r is RowRecurPoint rr) { Recompute(rr); } else if (r is TableRecurPoint rt) { Recompute(rt); } }
/// <summary> /// Change the value of certain defaults to be more user friendly (namely, non-nullable dates and times) /// </summary> /// <param name="d">a newly created persisto</param> public static void FixTopLevelDefaultsInNewPersiston(DatonDef datondef, Daton d) { if (datondef.MultipleMainRows) { return; } foreach (var coldef in datondef.MainTableDef.Cols) { if (coldef.CSType == typeof(DateTime)) { var field = datondef.Type.GetField(coldef.Name); field.SetValue(d, DateTime.UtcNow); } } }
/// <summary> /// Get a RecurPoint for the top level of a daton, which will be a RowRecurPoint for single-main-row type, else a TableRecurPoint /// </summary> public static RecurPoint FromDaton(DatonDef datondef, Daton daton) { if (datondef.MultipleMainRows) { return new TableRecurPoint { TableDef = datondef.MainTableDef, Table = GetMainTable(datondef, daton, createIfMissing: true) } } ; else { return new RowRecurPoint { TableDef = datondef.MainTableDef, Row = daton } }; }
/// <summary> /// Validate the persiston and populate Errors in this instance with the problems found. /// </summary> public async Task ValidatePersiston(DatonDef datondef, Persiston daton) { Errors = new List <string>(); //built-in validation var r = RecurPoint.FromDaton(datondef, daton); if (r is RowRecurPoint rr) { Validate(rr); } else if (r is TableRecurPoint rt) { Validate(rt); } //custom validation await daton.Validate(User, message => Errors.Add(message)); }
/// <summary> /// Construct a daton object using ConstructRow if it is a single main row style daton, else just construct the type /// </summary> public static Daton ConstructDaton(Type t, DatonDef datondef) { return(ConstructRow(t, datondef.MultipleMainRows ? null : datondef.MainTableDef) as Daton); }
public PersistonDiff(DatonDef datondef, DatonKey key, string version) { DatonDef = datondef; Key = key; BasedOnVersion = version; }
public static IList GetMainTable(DatonDef datondef, Daton daton, bool createIfMissing = false) { var f = daton.GetType().GetField(datondef.MainTableDef.Name); return(GetChildTable(daton, f, createIfMissing)); }