handle list nodes equality in selector
This commit is contained in:
@@ -26,11 +26,22 @@ func matchStatement(statement Statement, node ipld.Node) bool {
|
|||||||
switch statement.Kind() {
|
switch statement.Kind() {
|
||||||
case KindEqual:
|
case KindEqual:
|
||||||
if s, ok := statement.(equality); ok {
|
if s, ok := statement.(equality); ok {
|
||||||
one, _, err := selector.Select(s.selector, node)
|
one, many, err := selector.Select(s.selector, node)
|
||||||
if err != nil || one == nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return datamodel.DeepEqual(s.value, one)
|
if one != nil {
|
||||||
|
return datamodel.DeepEqual(s.value, one)
|
||||||
|
}
|
||||||
|
if many != nil {
|
||||||
|
for _, n := range many {
|
||||||
|
if eq := datamodel.DeepEqual(s.value, n); eq {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
case KindGreaterThan:
|
case KindGreaterThan:
|
||||||
if s, ok := statement.(equality); ok {
|
if s, ok := statement.(equality); ok {
|
||||||
@@ -119,17 +130,25 @@ func matchStatement(statement Statement, node ipld.Node) bool {
|
|||||||
}
|
}
|
||||||
case KindAny:
|
case KindAny:
|
||||||
if s, ok := statement.(quantifier); ok {
|
if s, ok := statement.(quantifier); ok {
|
||||||
// FIXME: line below return a single node, not many
|
one, many, err := selector.Select(s.selector, node)
|
||||||
_, many, err := selector.Select(s.selector, node)
|
if err != nil {
|
||||||
if err != nil || many == nil {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, n := range many {
|
if one != nil {
|
||||||
ok := matchStatement(s.statement, n)
|
ok := matchStatement(s.statement, one)
|
||||||
if ok {
|
if ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if many != nil {
|
||||||
|
for _, n := range many {
|
||||||
|
ok := matchStatement(s.statement, n)
|
||||||
|
if ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,26 +199,58 @@ func resolve(sel Selector, subject ipld.Node, at []string) (ipld.Node, []ipld.No
|
|||||||
|
|
||||||
case seg.Field() != "":
|
case seg.Field() != "":
|
||||||
at = append(at, seg.Field())
|
at = append(at, seg.Field())
|
||||||
if cur == nil || cur.Kind() != datamodel.Kind_Map {
|
if cur == nil {
|
||||||
if seg.Optional() {
|
if seg.Optional() {
|
||||||
cur = nil
|
cur = nil
|
||||||
} else {
|
} else {
|
||||||
return nil, nil, newResolutionError(fmt.Sprintf("can not access field: %s on kind: %s", seg.Field(), kindString(cur)), at)
|
return nil, nil, newResolutionError(fmt.Sprintf("can not access field: %s on kind: %s", seg.Field(), kindString(cur)), at)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
n, err := cur.LookupByString(seg.Field())
|
switch cur.Kind() {
|
||||||
if err != nil {
|
case datamodel.Kind_Map:
|
||||||
if isMissing(err) {
|
n, err := cur.LookupByString(seg.Field())
|
||||||
if seg.Optional() {
|
if err != nil {
|
||||||
cur = nil
|
if isMissing(err) {
|
||||||
|
if seg.Optional() {
|
||||||
|
cur = nil
|
||||||
|
} else {
|
||||||
|
return nil, nil, newResolutionError(fmt.Sprintf("object has no field named: %s", seg.Field()), at)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, nil, newResolutionError(fmt.Sprintf("object has no field named: %s", seg.Field()), at)
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, nil, err
|
cur = n
|
||||||
|
}
|
||||||
|
case datamodel.Kind_List:
|
||||||
|
var many []ipld.Node
|
||||||
|
it := cur.ListIterator()
|
||||||
|
for !it.Done() {
|
||||||
|
_, v, err := it.Next()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if v.Kind() == datamodel.Kind_Map {
|
||||||
|
n, err := v.LookupByString(seg.Field())
|
||||||
|
if err == nil {
|
||||||
|
many = append(many, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(many) > 0 {
|
||||||
|
cur = nil
|
||||||
|
return nil, many, nil
|
||||||
|
} else if seg.Optional() {
|
||||||
|
cur = nil
|
||||||
|
} else {
|
||||||
|
return nil, nil, newResolutionError(fmt.Sprintf("no elements in list have field named: %s", seg.Field()), at)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if seg.Optional() {
|
||||||
|
cur = nil
|
||||||
|
} else {
|
||||||
|
return nil, nil, newResolutionError(fmt.Sprintf("can not access field: %s on kind: %s", seg.Field(), kindString(cur)), at)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
cur = n
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user