summaryrefslogtreecommitdiff
path: root/internal/tree/mutations.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/tree/mutations.go')
-rw-r--r--internal/tree/mutations.go48
1 files changed, 37 insertions, 11 deletions
diff --git a/internal/tree/mutations.go b/internal/tree/mutations.go
index ec80ebd..9aa9056 100644
--- a/internal/tree/mutations.go
+++ b/internal/tree/mutations.go
@@ -3,11 +3,13 @@ package tree
import (
"context"
"fmt"
+ "strings"
"go.neonxp.dev/djson/internal/model"
+ json "go.neonxp.dev/json/model"
)
-func (t *Engine) Mutation(ctx context.Context, mut *model.Mutation) error {
+func (t *stdCore) Mutation(ctx context.Context, mut *model.Mutation) error {
t.mu.Lock()
defer t.mu.Unlock()
if err := t.execute(mut); err != nil {
@@ -16,45 +18,69 @@ func (t *Engine) Mutation(ctx context.Context, mut *model.Mutation) error {
return t.storage.Commit(ctx, *mut)
}
-func (t *Engine) execute(mut *model.Mutation) error {
+func (t *stdCore) execute(mut *model.Mutation) error {
switch mut.Type {
case model.Create:
if len(mut.Path) == 0 {
// create root node
- t.Root = mut.Body
+ inObject, ok := mut.Body.(*json.ObjectNode)
+ if !ok {
+ return fmt.Errorf("root node must be object")
+ }
+ t.Root = *inObject
return nil
}
key := mut.Path[len(mut.Path)-1]
path := mut.Path[:len(mut.Path)-1]
- target, err := t.Root.Query(path)
+ target, err := json.Query(&t.Root, path)
if err != nil {
return err
}
- return target.Set(key, mut.Body)
+ targetObject, ok := target.(*json.ObjectNode)
+ if !ok {
+ return fmt.Errorf("node %s is not object", strings.Join(path, "/"))
+ }
+ return targetObject.Value.Set(key, mut.Body)
case model.Merge:
+ inObject, ok := mut.Body.(*json.ObjectNode)
+ if !ok {
+ return fmt.Errorf("patch allowed only for objects")
+ }
if len(mut.Path) == 0 {
// patch root node
- return t.Root.Merge(&mut.Body)
+ t.Root.Merge(inObject)
+ return nil
}
- target, err := t.Root.Query(mut.Path)
+ target, err := json.Query(&t.Root, mut.Path)
if err != nil {
return err
}
- return target.Merge(&mut.Body)
+ targetObject, ok := target.(*json.ObjectNode)
+ if !ok {
+ return fmt.Errorf("patch allowed only for objects")
+ }
+ targetObject.Merge(inObject)
+ return nil
case model.Remove:
if len(mut.Path) == 0 {
return fmt.Errorf("can't remove root node. Only replace or create avaliable")
}
key := mut.Path[len(mut.Path)-1]
if len(mut.Path) == 1 {
- return t.Root.Remove(key)
+ t.Root.Remove(key)
+ return nil
}
path := mut.Path[:len(mut.Path)-1]
- target, err := t.Root.Query(path)
+ target, err := json.Query(&t.Root, path)
if err != nil {
return err
}
- return target.Remove(key)
+ targetObject, ok := target.(*json.ObjectNode)
+ if !ok {
+ return fmt.Errorf("remove allowed only from objects")
+ }
+ targetObject.Remove(key)
+ return nil
}
return fmt.Errorf("invalid command type: %d", mut.Type)
}