func mutateRestoreNode(ctx context.Context, n *node.Node, p *node.Node, b *node.Node) error { n.Restore(ctx, b) if p == nil { return nil } switch p.Type.NativeJsonType(ctx) { case system.J_MAP: // don't have to call n.InitialiseMapItem because the node is already // initialized if err := n.AddToMap(ctx, p, n.Key, true); err != nil { return kerr.Wrap("TOPLOONYCL", err) } case system.J_ARRAY: // don't have to call n.InitialiseArrayItem because the node is already // initialized if err := n.AddToArray(ctx, p, n.Index, true); err != nil { return kerr.Wrap("WFXSQYOEAY", err) } case system.J_OBJECT: // don't have to call n.InitialiseObjectField because the node is // already initialized if err := n.AddToObject(ctx, p, n.Rule, n.Key, true); err != nil { return kerr.Wrap("QMBJQMLOCY", err) } } return nil }
func ValidateNode(ctx context.Context, n *node.Node) (errors []ValidationError, err error) { // First validate all the nodes for _, current := range n.Flatten(true) { // Validate the actual object if v, ok := current.Value.(system.Validator); ok { failed, messages, err := v.Validate(ctx) if err != nil { return nil, kerr.Wrap("JXKTDTIIYG", err) } if failed { for _, message := range messages { errors = append(errors, ValidationError{Struct: kerr.New("KULDIJUYFB", message), Source: current}) } } } } // Then build a list of all nodes that have rules cache := map[*node.Node][]system.RuleInterface{} if err := BuildRulesNode(ctx, n, cache); err != nil { return nil, kerr.Wrap("YPUHTXPGRA", err) } // Then enforce the rules for current, rules := range cache { for _, rule := range rules { e, ok := rule.(system.Enforcer) if !ok { continue } failed, messages, err := e.Enforce(ctx, current.Value) if err != nil { return nil, kerr.Wrap("EBEMISLGDX", err) } if failed { for _, message := range messages { errors = append(errors, ValidationError{Struct: kerr.New("HLKQWDCMRN", message), Source: current}) } } } } return errors, nil }
func CreateParser(ctx context.Context, node *node.Node) (*Parser, error) { parser := Parser{node: node, root: node, ctx: ctx} parser.flattened = node.Flatten(true) //fmt.Println("CreateParser") //for i, n := range parser.flattened { // fmt.Println(i, n.Type.Id.Value(), n.ValueString, n.Key) //} return &parser, nil }
func mutateDeleteNode(ctx context.Context, n *node.Node, p *node.Node, b *node.Node) error { *b = *n.Backup() if p == nil { return nil } switch p.Type.NativeJsonType(ctx) { case system.J_MAP: if err := p.DeleteMapChild(n.Key); err != nil { return kerr.Wrap("BUUOWYSJNG", err) } case system.J_ARRAY: if err := p.DeleteArrayChild(n.Index); err != nil { return kerr.Wrap("RWFQSINACH", err) } case system.J_OBJECT: if err := p.DeleteObjectChild(ctx, n.Key); err != nil { return kerr.Wrap("XGVEXEOBUP", err) } } return nil }
func TestAddMutationRedo(t *testing.T) { cb, n := data.Setup(t) test := func(t *testing.T, n *node.Node, m *data.Multi) { var a, p, b, a1, p1, b1 *node.Node a = node.NewNode() p = n.Map["am"] b = node.NewNode() ty, ok := system.GetTypeFromCache(cb.Ctx(), "kego.io/tests/data", "multi") require.True(t, ok) require.NoError(t, mutateAddNode(cb.Ctx(), a, p, "", 2, ty, "")) require.Equal(t, `[{"js":"amjs0","type":"multi"},{"js":"amjs1","type":"multi"},{"type":"multi"}]`, p.Print(cb.Ctx())) a1 = n.Map["am"].Array[2].Map["m"] p1 = n.Map["am"].Array[2] b1 = node.NewNode() require.NoError(t, mutateAddNode(cb.Ctx(), a1, p1, "m", -1, ty, "")) require.Equal(t, 3, len(n.Map["am"].Array)) require.Equal(t, 3, len(m.Am)) require.False(t, n.Map["am"].Array[2].Map["m"].Missing) require.Equal(t, `[{"js":"amjs0","type":"multi"},{"js":"amjs1","type":"multi"},{"m":{"type":"multi"},"type":"multi"}]`, p.Print(cb.Ctx())) require.NoError(t, mutateDeleteNode(cb.Ctx(), a, p, b)) require.NoError(t, mutateDeleteNode(cb.Ctx(), a1, p1, b1)) require.Equal(t, 2, len(n.Map["am"].Array)) require.Equal(t, 2, len(m.Am)) require.NoError(t, mutateRestoreNode(cb.Ctx(), a, p, b)) require.NoError(t, mutateRestoreNode(cb.Ctx(), a1, p1, b1)) require.Equal(t, 3, len(n.Map["am"].Array)) require.Equal(t, 3, len(m.Am)) require.NotNil(t, n.Map["am"].Array[2]) require.NotNil(t, m.Am[2]) } test(t, n.Map["m"], n.Value.(*data.Multi).M) }
func mutateAddNode(ctx context.Context, n *node.Node, p *node.Node, key string, index int, t *system.Type, name string) error { switch { case p == nil: n.InitialiseRoot() case p.Type.NativeJsonType(ctx) == system.J_ARRAY: if err := n.InitialiseArrayItem(ctx, p, index); err != nil { return kerr.Wrap("QLBGMSQENC", err) } if err := n.AddToArray(ctx, p, index, true); err != nil { return kerr.Wrap("PLEJOTCSGH", err) } case p.Type.NativeJsonType(ctx) == system.J_MAP: if err := n.InitialiseMapItem(ctx, p, key); err != nil { return kerr.Wrap("KRTGPFYWIH", err) } if err := n.AddToMap(ctx, p, key, true); err != nil { return kerr.Wrap("UEPLLMTLDB", err) } } if err := n.SetValueZero(ctx, false, t); err != nil { return kerr.Wrap("NLSRNQGLLW", err) } if p == nil { // for root nodes, id field must be set. if err := n.SetIdField(ctx, name); err != nil { return kerr.Wrap("VDPFOWLHIL", err) } } return nil }