Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
@@ -54,7 +54,7 @@ template holding one from a quoted heredoc or a file. The rest of stdin's rules
|
|||||||
| `-d`, `--data-path D` | a directory to layer over the shipped data; repeatable, the last wins a name clash |
|
| `-d`, `--data-path D` | a directory to layer over the shipped data; repeatable, the last wins a name clash |
|
||||||
| `--no-shipped-data` | load only the `--data-path` directories |
|
| `--no-shipped-data` | load only the `--data-path` directories |
|
||||||
| `-s`, `--seed N` | same seed, version and data: identical output |
|
| `-s`, `--seed N` | same seed, version and data: identical output |
|
||||||
| `-n`, `--repeat N` | render the template N times (up to 1048576), each an independent draw, streamed |
|
| `-n`, `--repeat N` | render the template N times (0 to 1048576), each an independent draw, streamed; `0` prints nothing, or `[]` under `--format json` |
|
||||||
| `--separator S` | between repeated renders (default empty); a record `--format` ignores it |
|
| `--separator S` | between repeated renders (default empty); a record `--format` ignores it |
|
||||||
| `--format F` | `text` (default), `json`, `ndjson`, `csv` or `sql` — a record's columns, one record per row (json frames them as an array) |
|
| `--format F` | `text` (default), `json`, `ndjson`, `csv` or `sql` — a record's columns, one record per row (json frames them as an array) |
|
||||||
| `--table T` | the INSERT target for `--format sql`, ignored under any other (default: a lone reference's last segment, such as `users` for `{/users}`, else `records`) |
|
| `--table T` | the INSERT target for `--format sql`, ignored under any other (default: a lone reference's last segment, such as `users` for `{/users}`, else `records`) |
|
||||||
|
|||||||
+19
-3
@@ -61,7 +61,7 @@ one INSERT.
|
|||||||
--list list the paths the data offers, each written after {/ in a template, then exit;
|
--list list the paths the data offers, each written after {/ in a template, then exit;
|
||||||
--repeat, --separator, --format and --table do nothing here
|
--repeat, --separator, --format and --table do nothing here
|
||||||
--no-shipped-data load only the --data-path directories
|
--no-shipped-data load only the --data-path directories
|
||||||
-n, --repeat N render the template N times, 1..1048576 (default 1)
|
-n, --repeat N render the template N times, 0..1048576 (default 1)
|
||||||
-s, --seed N same seed, version and data: identical output
|
-s, --seed N same seed, version and data: identical output
|
||||||
--separator S string between repeated renders (default empty); a record --format ignores it
|
--separator S string between repeated renders (default empty); a record --format ignores it
|
||||||
--table T the INSERT target for --format sql, ignored under any other
|
--table T the INSERT target for --format sql, ignored under any other
|
||||||
@@ -103,8 +103,8 @@ var flagDefs = []flagDef{
|
|||||||
{"no-shipped-data", "", false, func(in *invocation, _ string) error { in.noShipped = true; return nil }},
|
{"no-shipped-data", "", false, func(in *invocation, _ string) error { in.noShipped = true; return nil }},
|
||||||
{"repeat", "n", true, func(in *invocation, v string) error {
|
{"repeat", "n", true, func(in *invocation, v string) error {
|
||||||
n, err := strconv.Atoi(v)
|
n, err := strconv.Atoi(v)
|
||||||
if err != nil || n < 1 || n > fejkdata.MaxRepeat {
|
if err != nil || n < 0 || n > fejkdata.MaxRepeat {
|
||||||
return fmt.Errorf("--repeat needs an integer in 1..%d, got %q", fejkdata.MaxRepeat, v)
|
return fmt.Errorf("--repeat needs an integer in 0..%d, got %q", fejkdata.MaxRepeat, v)
|
||||||
}
|
}
|
||||||
in.repeat = n
|
in.repeat = n
|
||||||
return nil
|
return nil
|
||||||
@@ -370,6 +370,9 @@ func (in invocation) writeRecords(f *fejkdata.Generator, src input, w io.Writer)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
format := recordFormats[in.format]
|
format := recordFormats[in.format]
|
||||||
|
if in.repeat == 0 {
|
||||||
|
return writeNoRecord(record, format, w)
|
||||||
|
}
|
||||||
out := bufio.NewWriter(w)
|
out := bufio.NewWriter(w)
|
||||||
if format.open != "" {
|
if format.open != "" {
|
||||||
out.WriteString(format.open)
|
out.WriteString(format.open)
|
||||||
@@ -397,6 +400,19 @@ func (in invocation) writeRecords(f *fejkdata.Generator, src input, w io.Writer)
|
|||||||
return out.Flush()
|
return out.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeNoRecord writes zero records: an empty document where the format frames one, else nothing. It
|
||||||
|
// draws one record and drops it, so a lone reference to nothing fails as it would with records.
|
||||||
|
func writeNoRecord(record func() (*fejkdata.Record, error), format recordFormat, w io.Writer) error {
|
||||||
|
if _, err := record(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if format.open == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
_, err := io.WriteString(w, format.open+format.close+"\n")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// defaultTable names the INSERT target when --table is absent: the path's last
|
// defaultTable names the INSERT target when --table is absent: the path's last
|
||||||
// segment, or "records" when stdin is not a lone reference.
|
// segment, or "records" when stdin is not a lone reference.
|
||||||
func defaultTable(path string) string {
|
func defaultTable(path string) string {
|
||||||
|
|||||||
Reference in New Issue
Block a user