-
-
Notifications
You must be signed in to change notification settings - Fork 166
Expand file tree
/
Copy pathnode_delete.go
More file actions
93 lines (78 loc) · 2.15 KB
/
node_delete.go
File metadata and controls
93 lines (78 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package dasel
import "reflect"
// Delete uses the given selector to find and delete the final node from the current node.
func (n *Node) Delete(selector string) error {
if isFinalSelector(selector) {
n.setReflectValue(initialiseEmptyOfType(n.Value))
return nil
}
n.Selector.Remaining = selector
rootNode := n
if err := buildFindChain(rootNode); err != nil {
return err
}
finalNode := lastNode(rootNode)
if err := deleteFromParent(finalNode); err != nil {
return err
}
if finalNode.Previous != nil {
if newSlice, changed := cleanupSliceDeletions(finalNode.Previous.Value); changed {
finalNode.Previous.setReflectValue(newSlice)
}
if finalNode.Previous.Selector.Type != "ROOT" {
if err := propagate(finalNode.Previous); err != nil {
return err
}
}
}
return nil
}
// DeleteMultiple uses the given selector to query the current node for every match
// possible and deletes them from the current node.
func (n *Node) DeleteMultiple(selector string) error {
if selector == "." {
n.setReflectValue(initialiseEmptyOfType(n.Value))
return nil
}
n.Selector.Remaining = selector
if err := buildFindMultipleChain(n); err != nil {
return err
}
lastNodes := lastNodes(n)
for _, lastNode := range lastNodes {
// delete properties and mark indexes for deletion
if err := deleteFromParent(lastNode); err != nil {
return err
}
}
for _, lastNode := range lastNodes {
// Cleanup indexes marked for deletion
if lastNode.Previous != nil {
if newSlice, changed := cleanupSliceDeletions(lastNode.Previous.Value); changed {
lastNode.Previous.setReflectValue(newSlice)
}
}
}
for _, lastNode := range lastNodes {
// Propagate values
if lastNode.Previous != nil {
if lastNode.Previous.Selector.Type != "ROOT" {
if err := propagate(lastNode.Previous); err != nil {
return err
}
}
}
}
return nil
}
func initialiseEmptyOfType(value reflect.Value) reflect.Value {
value = unwrapValue(value)
switch value.Kind() {
case reflect.Slice:
return reflect.MakeSlice(value.Type(), 0, 0)
case reflect.Map:
return reflect.MakeMap(value.Type())
default:
return reflect.ValueOf(map[string]interface{}{})
}
}