2020-11-03 23:48:43 +00:00
|
|
|
package yqlib
|
2020-10-21 01:54:58 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"container/list"
|
|
|
|
)
|
|
|
|
|
2021-02-02 07:17:59 +00:00
|
|
|
func createMapOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
2024-02-15 22:41:33 +00:00
|
|
|
log.Debugf("createMapOperation")
|
2020-11-13 02:19:54 +00:00
|
|
|
|
|
|
|
//each matchingNodes entry should turn into a sequence of keys to create.
|
|
|
|
//then collect object should do a cross function of the same index sequence for all matches.
|
|
|
|
|
|
|
|
sequences := list.New()
|
|
|
|
|
2021-02-02 07:17:59 +00:00
|
|
|
if context.MatchingNodes.Len() > 0 {
|
2020-11-13 02:19:54 +00:00
|
|
|
|
2021-02-02 07:17:59 +00:00
|
|
|
for matchingNodeEl := context.MatchingNodes.Front(); matchingNodeEl != nil; matchingNodeEl = matchingNodeEl.Next() {
|
2020-11-13 02:19:54 +00:00
|
|
|
matchingNode := matchingNodeEl.Value.(*CandidateNode)
|
2021-02-02 07:17:59 +00:00
|
|
|
sequenceNode, err := sequenceFor(d, context, matchingNode, expressionNode)
|
2020-11-13 02:19:54 +00:00
|
|
|
if err != nil {
|
2021-02-02 07:17:59 +00:00
|
|
|
return Context{}, err
|
2020-11-13 02:19:54 +00:00
|
|
|
}
|
|
|
|
sequences.PushBack(sequenceNode)
|
|
|
|
}
|
|
|
|
} else {
|
2021-02-02 07:17:59 +00:00
|
|
|
sequenceNode, err := sequenceFor(d, context, nil, expressionNode)
|
2020-11-13 02:19:54 +00:00
|
|
|
if err != nil {
|
2021-02-02 07:17:59 +00:00
|
|
|
return Context{}, err
|
2020-11-13 02:19:54 +00:00
|
|
|
}
|
|
|
|
sequences.PushBack(sequenceNode)
|
|
|
|
}
|
|
|
|
|
2023-10-18 01:11:53 +00:00
|
|
|
node := listToNodeSeq(sequences)
|
|
|
|
|
|
|
|
return context.SingleChildContext(node), nil
|
2020-11-13 02:19:54 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-02-02 07:17:59 +00:00
|
|
|
func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *CandidateNode, expressionNode *ExpressionNode) (*CandidateNode, error) {
|
2021-12-20 22:30:08 +00:00
|
|
|
var document uint
|
2023-10-18 01:11:53 +00:00
|
|
|
var filename string
|
|
|
|
var fileIndex int
|
|
|
|
|
2020-11-13 02:19:54 +00:00
|
|
|
var matches = list.New()
|
|
|
|
|
|
|
|
if matchingNode != nil {
|
2023-10-18 01:11:53 +00:00
|
|
|
document = matchingNode.GetDocument()
|
|
|
|
filename = matchingNode.GetFilename()
|
|
|
|
fileIndex = matchingNode.GetFileIndex()
|
2021-02-02 07:17:59 +00:00
|
|
|
matches.PushBack(matchingNode)
|
2020-10-21 01:54:58 +00:00
|
|
|
}
|
|
|
|
|
2023-10-18 01:11:53 +00:00
|
|
|
log.Debugf("**********sequenceFor %v", NodeToString(matchingNode))
|
|
|
|
|
2021-02-02 07:17:59 +00:00
|
|
|
mapPairs, err := crossFunction(d, context.ChildContext(matches), expressionNode,
|
|
|
|
func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
2023-10-18 01:11:53 +00:00
|
|
|
node := &CandidateNode{Kind: MappingNode, Tag: "!!map"}
|
|
|
|
|
|
|
|
log.Debugf("**********adding key %v and value %v", NodeToString(lhs), NodeToString(rhs))
|
|
|
|
|
|
|
|
node.AddKeyValueChild(lhs, rhs)
|
|
|
|
|
|
|
|
node.document = document
|
|
|
|
node.fileIndex = fileIndex
|
|
|
|
node.filename = filename
|
2020-10-21 01:54:58 +00:00
|
|
|
|
2023-10-18 01:11:53 +00:00
|
|
|
return node, nil
|
2021-04-13 00:42:20 +00:00
|
|
|
}, false)
|
2020-10-21 01:54:58 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-02-02 07:17:59 +00:00
|
|
|
innerList := listToNodeSeq(mapPairs.MatchingNodes)
|
2023-10-18 01:11:53 +00:00
|
|
|
innerList.Style = FlowStyle
|
|
|
|
innerList.document = document
|
|
|
|
innerList.fileIndex = fileIndex
|
|
|
|
innerList.filename = filename
|
|
|
|
return innerList, nil
|
2020-11-13 02:19:54 +00:00
|
|
|
}
|
|
|
|
|
2022-08-29 04:13:15 +00:00
|
|
|
// NOTE: here the document index gets dropped so we
|
2020-11-13 02:19:54 +00:00
|
|
|
// no longer know where the node originates from.
|
2023-10-18 01:11:53 +00:00
|
|
|
func listToNodeSeq(list *list.List) *CandidateNode {
|
|
|
|
node := CandidateNode{Kind: SequenceNode, Tag: "!!seq"}
|
2020-11-13 02:19:54 +00:00
|
|
|
for entry := list.Front(); entry != nil; entry = entry.Next() {
|
|
|
|
entryCandidate := entry.Value.(*CandidateNode)
|
|
|
|
log.Debugf("Collecting %v into sequence", NodeToString(entryCandidate))
|
2023-10-18 01:11:53 +00:00
|
|
|
node.AddChild(entryCandidate)
|
2020-10-21 01:54:58 +00:00
|
|
|
}
|
2020-11-13 02:19:54 +00:00
|
|
|
return &node
|
2020-10-21 01:54:58 +00:00
|
|
|
}
|