Skip to content

Commit c68c6dd

Browse files
committed
Implement nested map creation
1 parent 9511861 commit c68c6dd

27 files changed

+374
-131
lines changed

context.go

Lines changed: 69 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,6 @@ import (
55
"reflect"
66
)
77

8-
// Step is a single step in the query.
9-
// Each function call has its own step.
10-
// Each value in the output is simply a pointer to the actual data point in the context data.
11-
type Step struct {
12-
selector Selector
13-
index int
14-
output Values
15-
}
16-
17-
func (s *Step) Selector() Selector {
18-
return s.selector
19-
}
20-
21-
func (s *Step) Index() int {
22-
return s.index
23-
}
24-
25-
func (s *Step) Output() Values {
26-
return s.output
27-
}
28-
298
// Context has scope over the entire query.
309
// Each individual function has its own step within the context.
3110
// The context holds the entire data structure we're accessing/modifying.
@@ -36,6 +15,7 @@ type Context struct {
3615
data Value
3716
functions *FunctionCollection
3817
createWhenMissing bool
18+
filters []valueFilterFn
3919
}
4020

4121
func newContextWithFunctions(value interface{}, selector string, functions *FunctionCollection) *Context {
@@ -53,6 +33,7 @@ func newContextWithFunctions(value interface{}, selector string, functions *Func
5333
v = Value{
5434
Value: reflectVal,
5535
setFn: func(value Value) {
36+
fmt.Println("root set")
5637
reflectVal.Set(value.Value)
5738
},
5839
metadata: map[string]interface{}{},
@@ -91,6 +72,59 @@ func NewContext(value interface{}, selector string) *Context {
9172
return newContextWithFunctions(value, selector, standardFunctions())
9273
}
9374

75+
func newSelectContext(value interface{}, selector string) *Context {
76+
return newContextWithFunctions(value, selector, standardFunctions())
77+
}
78+
79+
func newPutContext(value interface{}, selector string) *Context {
80+
return newContextWithFunctions(value, selector, standardFunctions()).
81+
WithCreateWhenMissing(true)
82+
}
83+
84+
func newDeleteContext(value interface{}, selector string) *Context {
85+
c := newContextWithFunctions(value, selector, standardFunctions())
86+
c.filters = append(c.filters, withoutDeletePlaceholders)
87+
return c
88+
}
89+
90+
func Select(root interface{}, selector string) (Values, error) {
91+
c := newSelectContext(root, selector)
92+
return c.Run()
93+
}
94+
95+
func Put(root interface{}, selector string, value interface{}) (Value, error) {
96+
toSet := ValueOf(value)
97+
c := newPutContext(root, selector)
98+
values, err := c.Run()
99+
if err != nil {
100+
return Value{}, err
101+
}
102+
for _, v := range values {
103+
v.Set(toSet)
104+
}
105+
return c.Data(), nil
106+
}
107+
108+
func Delete(root interface{}, selector string) (Value, error) {
109+
c := newDeleteContext(root, selector)
110+
values, err := c.Run()
111+
if err != nil {
112+
return Value{}, err
113+
}
114+
for _, v := range values {
115+
v.Delete()
116+
}
117+
return c.Data(), nil
118+
}
119+
120+
func (c *Context) subSelectContext(value interface{}, selector string) *Context {
121+
return newContextWithFunctions(value, selector, c.functions)
122+
}
123+
124+
func (c *Context) subSelect(value interface{}, selector string) (Values, error) {
125+
return c.subSelectContext(value, selector).Run()
126+
}
127+
94128
func (c *Context) WithSelector(s string) *Context {
95129
c.selector = s
96130
c.selectorResolver = NewSelectorResolver(s, c.functions)
@@ -102,11 +136,15 @@ func (c *Context) WithCreateWhenMissing(create bool) *Context {
102136
return c
103137
}
104138

105-
func (c *Context) Data(filters ...ValueFilterFn) Value {
106-
if len(filters) == 0 {
139+
func (c *Context) CreateWhenMissing() bool {
140+
return c.createWhenMissing
141+
}
142+
143+
func (c *Context) Data() Value {
144+
if len(c.filters) == 0 {
107145
return c.data
108146
}
109-
changed, _ := rebuildWithFilter(c.data, filters...)
147+
changed, _ := rebuildWithFilter(c.data, c.filters...)
110148
return changed
111149
}
112150

@@ -139,14 +177,15 @@ func (c *Context) Next() (*Step, error) {
139177
}
140178

141179
nextStep := &Step{
180+
context: c,
142181
selector: *nextSelector,
143182
index: len(c.steps),
144183
output: nil,
145184
}
146185

147186
c.steps = append(c.steps, nextStep)
148187

149-
if err := c.processStep(nextStep); err != nil {
188+
if err := nextStep.execute(); err != nil {
150189
return nextStep, err
151190
}
152191

@@ -161,42 +200,17 @@ func (c *Context) Step(i int) *Step {
161200
return c.steps[i]
162201
}
163202

164-
func (c *Context) processStep(step *Step) error {
165-
f, err := c.functions.Get(step.selector.funcName)
166-
if err != nil {
167-
return err
168-
}
169-
output, err := f(c, step, step.selector.funcArgs)
170-
step.output = output
171-
return err
172-
}
173-
174-
func (c *Context) inputValue(s *Step) Values {
175-
prevStep := c.Step(s.index - 1)
176-
if prevStep == nil {
177-
return Values{}
178-
}
179-
return prevStep.output
180-
}
181-
182-
func (c *Context) subContext(value interface{}, selector string) *Context {
183-
return newContextWithFunctions(value, selector, c.functions)
184-
}
185-
186-
func performSubQuery(c *Context, value Value, selector string) (Values, error) {
187-
return c.subContext(value, selector).Run()
188-
}
189-
190-
// ValueFilterFn represents a filter that can be used to remove values
203+
// valueFilterFn represents a filter that can be used to remove values
191204
// from the output data.
192205
// If the filter returns true, the value is removed.
193-
type ValueFilterFn func(value Value) bool
206+
type valueFilterFn func(value Value) bool
194207

195-
func WithoutDeletePlaceholders(value Value) bool {
208+
// withoutDeletePlaceholders implements valueFilterFn.
209+
func withoutDeletePlaceholders(value Value) bool {
196210
return value.IsDeletePlaceholder()
197211
}
198212

199-
func rebuildWithFilter(value Value, filters ...ValueFilterFn) (Value, bool) {
213+
func rebuildWithFilter(value Value, filters ...valueFilterFn) (Value, bool) {
200214
changes := 0
201215

202216
remove := func(v Value) bool {

func_all.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var AllFunc = BasicFunction{
1212
return nil, err
1313
}
1414

15-
input := c.inputValue(s)
15+
input := s.inputs()
1616

1717
res := make(Values, 0)
1818

func_and.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ var AndFunc = BasicFunction{
1212
return nil, err
1313
}
1414

15-
input := c.inputValue(s)
15+
input := s.inputs()
1616

1717
runComparison := func(value Value, selector string) (bool, error) {
18-
gotValues, err := performSubQuery(c, value, selector)
18+
gotValues, err := c.subSelect(value, selector)
1919
if err != nil {
2020
return false, err
2121
}

func_equal.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var EqualFunc = BasicFunction{
1515
return nil, err
1616
}
1717

18-
input := c.inputValue(s)
18+
input := s.inputs()
1919

2020
type comparison struct {
2121
selector string
@@ -38,7 +38,7 @@ var EqualFunc = BasicFunction{
3838
}
3939

4040
runComparison := func(value Value, cmp comparison) (bool, error) {
41-
gotValues, err := performSubQuery(c, value, cmp.selector)
41+
gotValues, err := c.subSelect(value, cmp.selector)
4242
if err != nil {
4343
return false, err
4444
}

func_filter.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ var FilterFunc = BasicFunction{
1111
return nil, err
1212
}
1313

14-
input := c.inputValue(s)
14+
input := s.inputs()
1515

1616
runComparison := func(value Value, selector string) (bool, error) {
17-
gotValues, err := performSubQuery(c, value, selector)
17+
gotValues, err := c.subSelect(value, selector)
1818
if err != nil {
1919
return false, err
2020
}

func_filter_or.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ var FilterOrFunc = BasicFunction{
1111
return nil, err
1212
}
1313

14-
input := c.inputValue(s)
14+
input := s.inputs()
1515

1616
runComparison := func(value Value, selector string) (bool, error) {
17-
gotValues, err := performSubQuery(c, value, selector)
17+
gotValues, err := c.subSelect(value, selector)
1818
if err != nil {
1919
return false, err
2020
}

func_first.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var FirstFunc = BasicFunction{
1212
return nil, err
1313
}
1414

15-
input := c.inputValue(s)
15+
input := s.inputs()
1616

1717
res := make(Values, 0)
1818

func_index.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ var IndexFunc = BasicFunction{
2727
return nil, err
2828
}
2929

30-
input := c.inputValue(s)
30+
input := s.inputs()
3131

3232
res := make(Values, 0)
3333

func_key.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ var KeyFunc = BasicFunction{
77
return nil, err
88
}
99

10-
input := c.inputValue(s)
10+
input := s.inputs()
1111

1212
res := make(Values, 0)
1313

func_last.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var LastFunc = BasicFunction{
1212
return nil, err
1313
}
1414

15-
input := c.inputValue(s)
15+
input := s.inputs()
1616

1717
res := make(Values, 0)
1818

func_len.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ var LenFunc = BasicFunction{
77
return nil, err
88
}
99

10-
input := c.inputValue(s)
10+
input := s.inputs()
1111

1212
res := make(Values, 0)
1313

func_less_than.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ var LessThanFunc = BasicFunction{
1313
return nil, err
1414
}
1515

16-
input := c.inputValue(s)
16+
input := s.inputs()
1717

1818
type comparison struct {
1919
selector string
@@ -36,7 +36,7 @@ var LessThanFunc = BasicFunction{
3636
}
3737

3838
runComparison := func(value Value, cmp comparison) (bool, error) {
39-
gotValues, err := performSubQuery(c, value, cmp.selector)
39+
gotValues, err := c.subSelect(value, cmp.selector)
4040
if err != nil {
4141
return false, err
4242
}

func_metadata.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ var MetadataFunc = BasicFunction{
77
return nil, err
88
}
99

10-
input := c.inputValue(s)
10+
input := s.inputs()
1111

1212
res := make(Values, 0)
1313

func_more_than.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ var MoreThanFunc = BasicFunction{
1313
return nil, err
1414
}
1515

16-
input := c.inputValue(s)
16+
input := s.inputs()
1717

1818
type comparison struct {
1919
selector string
@@ -36,7 +36,7 @@ var MoreThanFunc = BasicFunction{
3636
}
3737

3838
runComparison := func(value Value, cmp comparison) (bool, error) {
39-
gotValues, err := performSubQuery(c, value, cmp.selector)
39+
gotValues, err := c.subSelect(value, cmp.selector)
4040
if err != nil {
4141
return false, err
4242
}

func_not.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ var NotFunc = BasicFunction{
1212
return nil, err
1313
}
1414

15-
input := c.inputValue(s)
15+
input := s.inputs()
1616

1717
runComparison := func(value Value, selector string) (bool, error) {
18-
gotValues, err := performSubQuery(c, value, selector)
18+
gotValues, err := c.subSelect(value, selector)
1919
if err != nil {
2020
return false, err
2121
}

func_or.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ var OrFunc = BasicFunction{
1212
return nil, err
1313
}
1414

15-
input := c.inputValue(s)
15+
input := s.inputs()
1616

1717
runComparison := func(value Value, selector string) (bool, error) {
18-
gotValues, err := performSubQuery(c, value, selector)
18+
gotValues, err := c.subSelect(value, selector)
1919
if err != nil {
2020
return false, err
2121
}

func_parent.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ var ParentFunc = BasicFunction{
77
return nil, err
88
}
99

10-
input := c.inputValue(s)
10+
input := s.inputs()
1111

1212
res := make(Values, 0)
1313

0 commit comments

Comments
 (0)