handle list nodes equality in selector

This commit is contained in:
Fabio Bozzo
2024-09-16 13:00:13 +02:00
parent 700f130858
commit ad03154b6e
2 changed files with 69 additions and 18 deletions

View File

@@ -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
} }
} }

View File

@@ -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
} }
} }