Skip to content

Commit bed2682

Browse files
Allow schema.Reference to work on array of ids. Closes rs#222. Closes rs#223
1 parent d3461c4 commit bed2682

File tree

3 files changed

+76
-11
lines changed

3 files changed

+76
-11
lines changed

rest/resource.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ func (r restResource) MultiGet(ctx context.Context, ids []interface{}) ([]map[st
3434
}
3535
payloads := make([]map[string]interface{}, 0, len(items))
3636
for _, i := range items {
37-
payloads = append(payloads, i.Payload)
37+
var p map[string]interface{}
38+
if i != nil {
39+
p = i.Payload
40+
}
41+
payloads = append(payloads, p)
3842
}
3943
return payloads, nil
4044
}

schema/query/projection_evaluator.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,37 @@ func evalProjection(ctx context.Context, p Projection, payload map[string]interf
7979
}
8080
} else if ref, ok := def.Validator.(*schema.Reference); ok {
8181
// Execute sub-request in batch
82+
var e Expression
83+
v, isArray := val.([]interface{})
84+
if isArray {
85+
e = &In{Field: "id", Values: v}
86+
} else {
87+
e = &Equal{Field: "id", Value: val}
88+
}
8289
q := &Query{
8390
Projection: pf.Children,
84-
Predicate: Predicate{&Equal{Field: "id", Value: val}},
91+
Predicate: Predicate{e},
8592
}
8693
rbr.request(ref.Path, q, func(payloads []map[string]interface{}, validator schema.Validator) error {
8794
var v interface{}
88-
if len(payloads) == 1 {
89-
payload, err := evalProjection(ctx, pf.Children, payloads[0], validator, rbr)
90-
if err != nil {
91-
return fmt.Errorf("%s: error applying Projection on sub-field: %v", name, err)
95+
if len(payloads) == 1 && isArray == false {
96+
if payloads[0] != nil {
97+
payload, err := evalProjection(ctx, pf.Children, payloads[0], validator, rbr)
98+
if err != nil {
99+
return fmt.Errorf("%s: error applying Projection on sub-field: %v", name, err)
100+
}
101+
if v, err = resolveFieldHandler(ctx, pf, def, payload); err != nil {
102+
return fmt.Errorf("%s: error resolving field handler on sub-field: %v", name, err)
103+
}
104+
}
105+
} else {
106+
var err error
107+
for i := range payloads {
108+
if payloads[i], err = evalProjection(ctx, pf.Children, payloads[i], validator, rbr); err != nil {
109+
return fmt.Errorf("%s: error applying projection on sub-field item #%d: %v", pf.Name, i, err)
110+
}
92111
}
93-
if v, err = resolveFieldHandler(ctx, pf, def, payload); err != nil {
112+
if v, err = resolveFieldHandler(ctx, pf, def, payloads); err != nil {
94113
return fmt.Errorf("%s: error resolving field handler on sub-field: %v", name, err)
95114
}
96115
}

schema/query/projection_evaluator_test.go

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ func TestProjectionEval(t *testing.T) {
101101
"ref": {},
102102
}},
103103
payloads: map[string]map[string]interface{}{
104-
"1": map[string]interface{}{"name": "first"},
105-
"2": map[string]interface{}{"name": "second", "ref": "a"},
106-
"3": map[string]interface{}{"name": "third", "ref": "b"},
107-
"4": map[string]interface{}{"name": "forth", "ref": "a"},
104+
"1": map[string]interface{}{"id": "1", "name": "first"},
105+
"2": map[string]interface{}{"id": "2", "name": "second", "ref": "a"},
106+
"3": map[string]interface{}{"id": "3", "name": "third", "ref": "b"},
107+
"4": map[string]interface{}{"id": "4", "name": "forth", "ref": "a"},
108108
},
109109
},
110110
},
@@ -186,6 +186,48 @@ func TestProjectionEval(t *testing.T) {
186186
nil,
187187
`{"reference":{"name":"second"}}`,
188188
},
189+
{
190+
"Reference-no-expansion",
191+
`reference`,
192+
`{"reference":"100"}`,
193+
nil,
194+
`{"reference":"100"}`,
195+
},
196+
{
197+
"Reference-non-existant",
198+
`reference{name}`,
199+
`{"reference":"100"}`,
200+
nil,
201+
`{"reference":null}`,
202+
},
203+
{
204+
"ReferenceArray-non-existant",
205+
`reference{name}`,
206+
`{"reference":["100"]}`,
207+
nil,
208+
`{"reference":[]}`,
209+
},
210+
{
211+
"ReferenceArray-empty",
212+
`reference{name}`,
213+
`{"reference":[]}`,
214+
nil,
215+
`{"reference":[]}`,
216+
},
217+
{
218+
"ReferenceArray-one",
219+
`reference{name}`,
220+
`{"reference":["2"]}`,
221+
nil,
222+
`{"reference":[{"name":"second"}]}`,
223+
},
224+
{
225+
"ReferenceArray-many",
226+
`reference{name}`,
227+
`{"reference":["2","3"]}`,
228+
nil,
229+
`{"reference":[{"name":"second"},{"name":"third"}]}`,
230+
},
189231
{
190232
"Connection#1",
191233
`connection{name}`,

0 commit comments

Comments
 (0)