Split doc operator

This commit is contained in:
Mike Farah 2021-01-14 14:25:31 +11:00
parent 02ef99560d
commit 626e9cacaf
8 changed files with 89 additions and 3 deletions

View File

@ -0,0 +1,31 @@
# Split into Documents
This operator splits all matches into separate documents
## Split empty
Running
```bash
yq eval --null-input 'splitDoc'
```
will output
```yaml
```
## Split array
Given a sample.yml file of:
```yaml
- a: cat
- b: dog
```
then
```bash
yq eval '.[] | splitDoc' sample.yml
```
will output
```yaml
a: cat
---
b: dog
```

View File

@ -0,0 +1,3 @@
# Split into Documents
This operator splits all matches into separate documents

View File

@ -241,6 +241,7 @@ func initLexer() (*lex.Lexer, error) {
lexer.Add([]byte(`documentIndex`), opToken(getDocumentIndexOpType)) lexer.Add([]byte(`documentIndex`), opToken(getDocumentIndexOpType))
lexer.Add([]byte(`di`), opToken(getDocumentIndexOpType)) lexer.Add([]byte(`di`), opToken(getDocumentIndexOpType))
lexer.Add([]byte(`splitDoc`), opToken(splitDocumentOpType))
lexer.Add([]byte(`style`), opAssignableToken(getStyleOpType, assignStyleOpType)) lexer.Add([]byte(`style`), opAssignableToken(getStyleOpType, assignStyleOpType))

View File

@ -51,6 +51,7 @@ var shortPipeOpType = &operationType{Type: "SHORT_PIPE", NumArgs: 2, Precedence:
var lengthOpType = &operationType{Type: "LENGTH", NumArgs: 0, Precedence: 50, Handler: lengthOperator} var lengthOpType = &operationType{Type: "LENGTH", NumArgs: 0, Precedence: 50, Handler: lengthOperator}
var collectOpType = &operationType{Type: "COLLECT", NumArgs: 0, Precedence: 50, Handler: collectOperator} var collectOpType = &operationType{Type: "COLLECT", NumArgs: 0, Precedence: 50, Handler: collectOperator}
var splitDocumentOpType = &operationType{Type: "SPLIT_DOC", NumArgs: 0, Precedence: 50, Handler: splitDocumentOperator}
var getStyleOpType = &operationType{Type: "GET_STYLE", NumArgs: 0, Precedence: 50, Handler: getStyleOperator} var getStyleOpType = &operationType{Type: "GET_STYLE", NumArgs: 0, Precedence: 50, Handler: getStyleOperator}
var getTagOpType = &operationType{Type: "GET_TAG", NumArgs: 0, Precedence: 50, Handler: getTagOperator} var getTagOpType = &operationType{Type: "GET_TAG", NumArgs: 0, Precedence: 50, Handler: getTagOperator}
var getCommentOpType = &operationType{Type: "GET_COMMENT", NumArgs: 0, Precedence: 50, Handler: getCommentsOperator} var getCommentOpType = &operationType{Type: "GET_COMMENT", NumArgs: 0, Precedence: 50, Handler: getCommentsOperator}

View File

@ -0,0 +1,18 @@
package yqlib
import (
"container/list"
)
func splitDocumentOperator(d *dataTreeNavigator, matchMap *list.List, expressionNode *ExpressionNode) (*list.List, error) {
log.Debugf("-- splitDocumentOperator")
var index uint = 0
for el := matchMap.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
candidate.Document = index
index = index + 1
}
return matchMap, nil
}

View File

@ -0,0 +1,32 @@
package yqlib
import (
"testing"
)
var splitDocOperatorScenarios = []expressionScenario{
{
description: "Split empty",
document: ``,
expression: `splitDoc`,
expected: []string{
"D0, P[], (!!null)::\n",
},
},
{
description: "Split array",
document: `[{a: cat}, {b: dog}]`,
expression: `.[] | splitDoc`,
expected: []string{
"D0, P[0], (!!map)::{a: cat}\n",
"D1, P[1], (!!map)::{b: dog}\n",
},
},
}
func TestSplitDocOperatorScenarios(t *testing.T) {
for _, tt := range splitDocOperatorScenarios {
testScenario(t, &tt)
}
documentScenarios(t, "Split into Documents", splitDocOperatorScenarios)
}

View File

@ -55,7 +55,7 @@ func testScenario(t *testing.T, s *expressionScenario) {
candidateNode := &CandidateNode{ candidateNode := &CandidateNode{
Document: 0, Document: 0,
Filename: "", Filename: "",
Node: &yaml.Node{Tag: "!!null"}, Node: &yaml.Node{Tag: "!!null", Kind: yaml.ScalarNode},
FileIndex: 0, FileIndex: 0,
} }
inputs.PushBack(candidateNode) inputs.PushBack(candidateNode)
@ -245,7 +245,7 @@ func documentOutput(t *testing.T, w *bufio.Writer, s expressionScenario, formatt
candidateNode := &CandidateNode{ candidateNode := &CandidateNode{
Document: 0, Document: 0,
Filename: "", Filename: "",
Node: &yaml.Node{Tag: "!!null"}, Node: &yaml.Node{Tag: "!!null", Kind: yaml.ScalarNode},
FileIndex: 0, FileIndex: 0,
} }
inputs.PushBack(candidateNode) inputs.PushBack(candidateNode)

View File

@ -35,7 +35,7 @@ func (s *streamEvaluator) EvaluateNew(expression string, printer Printer) error
candidateNode := &CandidateNode{ candidateNode := &CandidateNode{
Document: 0, Document: 0,
Filename: "", Filename: "",
Node: &yaml.Node{Tag: "!!null"}, Node: &yaml.Node{Tag: "!!null", Kind: yaml.ScalarNode},
FileIndex: 0, FileIndex: 0,
} }
inputList := list.New() inputList := list.New()