File: flatten_unflatten.go

package info (click to toggle)
miller 6.16.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 87,928 kB
  • sloc: ruby: 162; sh: 119; makefile: 87
file content (98 lines) | stat: -rw-r--r-- 2,953 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package cli

// ================================================================
// Decide whether to insert a flatten or unflatten verb at the end of the
// chain.  See also repl/verbs.go which handles the same issue in the REPL.
//
// ----------------------------------------------------------------
// PROBLEM TO BE SOLVED:
//
// JSON has nested structures and CSV et al. do not. For example:
// {
//   "req" : {
//     "method": "GET",
//     "path":   "api/check",
//   }
// }
//
// For CSV we flatten this down to
//
// {
//   "req.method": "GET",
//   "req.path":   "api/check"
// }
//
// ----------------------------------------------------------------
// APPROACH:
//
// Use the Principle of Least Surprise (POLS).
//
// * If input is JSON and output is JSON:
//   o Records can be nested from record-read
//   o They remain that way through the Miller record-processing stream
//   o They are nested on record-write
//   o No action needs to be taken
//
// * If input is JSON and output is non-JSON:
//   o Records can be nested from record-read
//   o They remain that way through the Miller record-processing stream
//   o On record-write, nested structures will be converted to string (carriage
//     returns and all) using json_stringify. People *might* want this but
//     (using POLS) we will (by default) AUTO-FLATTEN for them. There is a
//     --no-auto-unflatten CLI flag for those who want it.
//
// * If input is non-JSON and output is non-JSON:
//   o If there is a "req.method" field, people should be able to do
//     'mlr sort -f req.method' with no surprises. (Again, POLS.) Therefore
//     no auto-unflatten on input.  People can insert an unflatten verb
//     into their verb chain if they really want unflatten for non-JSON
//     files.
//   o The DSL can make nested data, so AUTO-FLATTEN at output.
//
// * If input is non-JSON and output is JSON:
//   o Default is to auto-unflatten at output.
//   o There is a --no-auto-unflatten for those who want it.
//
// * Overriding these: if the last verb the user has explicitly provided is
//   flatten, don't undo that by putting an unflatten right after.
//
// ================================================================

func DecideFinalFlatten(writerOptions *TWriterOptions) bool {
	ofmt := writerOptions.OutputFileFormat
	if writerOptions.AutoFlatten {
		if ofmt != "json" {
			return true
		}
	}
	return false
}

func DecideFinalUnflatten(
	options *TOptions,
	verbSequences [][]string,
) bool {

	numVerbs := len(verbSequences)
	if numVerbs > 0 {
		lastVerbSequence := verbSequences[numVerbs-1]
		if len(lastVerbSequence) > 0 {
			lastVerbName := lastVerbSequence[0]
			if lastVerbName == "flatten" {
				return false
			}
		}
	}

	ifmt := options.ReaderOptions.InputFileFormat
	ofmt := options.WriterOptions.OutputFileFormat

	if options.WriterOptions.AutoUnflatten {
		if ifmt != "json" {
			if ofmt == "json" {
				return true
			}
		}
	}
	return false
}