-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmutation.go
154 lines (137 loc) · 3.28 KB
/
mutation.go
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package humus
import (
"github.com/pkg/errors"
)
//SingleMutation represents just that, one object mutated.
//interface{} is used over DNode as the structure of a mutation might
//change so a map[string]interface{} is needed for certain mutations.
type SingleMutation struct {
Object DNode
MutationType MutationType
//Used for upsert.
Condition string
}
func (s SingleMutation) WithCond(cond string) SingleMutation {
s.Condition = cond
return s
}
func (s SingleMutation) Type() MutationType {
return s.MutationType
}
func (s SingleMutation) Cond() string {
return s.Condition
}
func (s SingleMutation) mutate() ([]byte, error) {
//panic("do not Process a single mutation")
if s.Object == nil {
return nil, errors.New("nil value supplied to Process")
}
s.Object.Recurse(0)
var b []byte
switch s.MutationType {
case MutateSet:
if val, ok := s.Object.(Saver); ok {
if val == nil {
return nil, errors.New("nil value supplied to Process")
}
node, err := val.Save()
if err != nil {
return nil, err
}
b, _ = json.Marshal(node)
} else {
b, _ = json.Marshal(s.Object)
}
case MutateDelete:
if val, ok := s.Object.(Deleter); ok {
if val == nil {
return nil, errors.New("nil value supplied to Process")
}
node, err := val.Delete()
if err != nil {
return nil, err
}
b, _ = json.Marshal(node)
} else {
b, _ = json.Marshal(s.Object)
}
}
return b, nil
}
type MutationQuery struct {
Values []DNode
Condition string
MutationType MutationType
}
//CreateMutations creates a list of mutations from a variadic list of Dnodes.
func CreateMutations(typ MutationType, muts ...DNode) *MutationQuery {
return &MutationQuery{
Values: muts,
MutationType: typ,
}
}
func (m *MutationQuery) SetCondition(c string) *MutationQuery {
m.Condition = c
return m
}
func (m *MutationQuery) Cond() string {
return m.Condition
}
func (m *MutationQuery) mutate() ([]byte, error) {
var counter int
var err error
for k, v := range m.Values {
counter = v.Recurse(counter)
switch m.MutationType {
case MutateSet:
if val, ok := v.(Saver); ok {
if val == nil {
return nil, errors.New("nil DNode supplied to Process in mutationQuery")
}
m.Values[k], err = val.Save()
if err != nil {
return nil, err
}
}
case MutateDelete:
if val, ok := v.(Deleter); ok {
if val == nil {
return nil, errors.New("nil DNode supplied to Process in mutationQuery")
}
m.Values[k], err = val.Delete()
if err != nil {
return nil, err
}
}
}
}
byt, err := json.Marshal(m.Values)
return byt, err
}
func (m *MutationQuery) Type() MutationType {
return m.MutationType
}
type customMutation struct {
Value interface{}
QueryType MutationType
Condition string
}
func (c customMutation) Cond() string {
return c.Condition
}
func (c customMutation) mutate() ([]byte, error) {
b, _ := json.Marshal(c.Value)
return b, nil
}
func (c customMutation) Type() MutationType {
return c.QueryType
}
//CreateCustomMutation allows you to create a mutation from an interface
//and not a DNode. This is useful alongside custom queries to set values, especially
//working with facets.
func CreateCustomMutation(obj interface{}, typ MutationType) Mutate {
return customMutation{
Value: obj,
QueryType: typ,
}
}