diff --git a/CHANGELOG.md b/CHANGELOG.md index 25a37ac197..33862b50a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ ### Bugfixes +- [#8119](https://github.com/influxdata/influxdb/pull/8119): Add chunked/chunk size as setting/options in cli. - [#8091](https://github.com/influxdata/influxdb/issues/8091): Do not increment the continuous query statistic if no query is run. - [#8064](https://github.com/influxdata/influxdb/issues/8064): Forbid wildcards in binary expressions. - [#8148](https://github.com/influxdata/influxdb/issues/8148): Fix fill(linear) when multiple series exist and there are null values. diff --git a/cmd/influx/cli/cli.go b/cmd/influx/cli/cli.go index 67be0cdc9c..edaa0d9e87 100644 --- a/cmd/influx/cli/cli.go +++ b/cmd/influx/cli/cli.go @@ -47,6 +47,7 @@ type CommandLine struct { ShowVersion bool Import bool Chunked bool + ChunkSize int Quit chan struct{} IgnoreSignals bool // Ignore signals normally caught by this process (used primarily for testing) ForceTTY bool // Force the CLI to act as if it were connected to a TTY @@ -64,6 +65,7 @@ func New(version string) *CommandLine { ClientVersion: version, Quit: make(chan struct{}, 1), osSignals: make(chan os.Signal, 1), + Chunked: true, } } @@ -256,6 +258,15 @@ func (c *CommandLine) ParseCommand(cmd string) error { c.SetWriteConsistency(cmd) case "settings": c.Settings() + case "chunked": + c.Chunked = !c.Chunked + if c.Chunked { + fmt.Println("chunked responses enabled") + } else { + fmt.Println("chunked reponses disabled") + } + case "chunk": + c.SetChunkSize(cmd) case "pretty": c.Pretty = !c.Pretty if c.Pretty { @@ -490,6 +501,31 @@ func (c *CommandLine) retentionPolicyExists(db, rp string) bool { return true } +// SetChunkSize sets the chunk size +// 0 sets it back to the default +func (c *CommandLine) SetChunkSize(cmd string) { + // normalize cmd + cmd = strings.ToLower(cmd) + cmd = strings.Join(strings.Fields(cmd), " ") + + // Remove the "chunk size" keyword if it exists + cmd = strings.TrimPrefix(cmd, "chunk size ") + + // Remove the "chunk" keyword if it exists + // allows them to use `chunk 50` as a shortcut + cmd = strings.TrimPrefix(cmd, "chunk ") + + if n, err := strconv.ParseInt(cmd, 10, 64); err == nil { + c.ChunkSize = int(n) + if c.ChunkSize <= 0 { + c.ChunkSize = 0 + } + fmt.Printf("chunk size set to %d\n", c.ChunkSize) + } else { + fmt.Printf("unable to parse chunk size from %q\n", cmd) + } +} + // SetPrecision sets client precision. func (c *CommandLine) SetPrecision(cmd string) { // normalize cmd @@ -659,9 +695,10 @@ func (c *CommandLine) Insert(stmt string) error { // query creates a query struct to be used with the client. func (c *CommandLine) query(query string) client.Query { return client.Query{ - Command: query, - Database: c.Database, - Chunked: true, + Command: query, + Database: c.Database, + Chunked: c.Chunked, + ChunkSize: c.ChunkSize, } } @@ -877,6 +914,8 @@ func (c *CommandLine) Settings() { fmt.Fprintf(w, "Pretty\t%v\n", c.Pretty) fmt.Fprintf(w, "Format\t%s\n", c.Format) fmt.Fprintf(w, "Write Consistency\t%s\n", c.ClientConfig.WriteConsistency) + fmt.Fprintf(w, "Chunked\t%v\n", c.Chunked) + fmt.Fprintf(w, "Chunk Size\t%d\n", c.ChunkSize) fmt.Fprintln(w) w.Flush() } @@ -886,6 +925,8 @@ func (c *CommandLine) help() { connect connects to another node specified by host:port auth prompts for username and password pretty toggles pretty print for the json format + chunked turns on chunked responses from server + chunk size sets the size of the chunked responses. Set to 0 to reset to the default chunked size use sets current database format specifies the format of the server responses: json, csv, or column precision specifies the format of the timestamp: rfc3339, h, m, s, ms, u or ns diff --git a/cmd/influx/cli/cli_test.go b/cmd/influx/cli/cli_test.go index 9ec74c28b1..bc2c222037 100644 --- a/cmd/influx/cli/cli_test.go +++ b/cmd/influx/cli/cli_test.go @@ -132,6 +132,77 @@ func TestSetFormat(t *testing.T) { } } +func Test_SetChunked(t *testing.T) { + t.Parallel() + c := cli.New(CLIENT_VERSION) + config := client.NewConfig() + client, _ := client.NewClient(config) + c.Client = client + + // make sure chunked is on by default + if got, exp := c.Chunked, true; got != exp { + t.Fatalf("chunked should be on by default. got %v, exp %v", got, exp) + } + + // turn chunked off + if err := c.ParseCommand("Chunked"); err != nil { + t.Fatalf("setting chunked failed: err: %s", err) + } + + if got, exp := c.Chunked, false; got != exp { + t.Fatalf("setting chunked failed. got %v, exp %v", got, exp) + } + + // turn chunked back on + if err := c.ParseCommand("Chunked"); err != nil { + t.Fatalf("setting chunked failed: err: %s", err) + } + + if got, exp := c.Chunked, true; got != exp { + t.Fatalf("setting chunked failed. got %v, exp %v", got, exp) + } +} + +func Test_SetChunkSize(t *testing.T) { + t.Parallel() + c := cli.New(CLIENT_VERSION) + config := client.NewConfig() + client, _ := client.NewClient(config) + c.Client = client + + // check default chunk size + if got, exp := c.ChunkSize, 0; got != exp { + t.Fatalf("unexpected chunk size. got %d, exp %d", got, exp) + } + + tests := []struct { + command string + exp int + }{ + {"chunk size 20", 20}, + {" CHunk siZE 55 ", 55}, + {"chunk 10", 10}, + {" chuNK 15", 15}, + {"chunk size -60", 0}, + {"chunk size 10", 10}, + {"chunk size 0", 0}, + {"chunk size 10", 10}, + {"chunk size junk", 10}, + } + + for _, test := range tests { + if err := c.ParseCommand(test.command); err != nil { + t.Logf("command: %q", test.command) + t.Fatalf("setting chunked failed: err: %s", err) + } + + if got, exp := c.ChunkSize, test.exp; got != exp { + t.Logf("command: %q", test.command) + t.Fatalf("unexpected chunk size. got %d, exp %d", got, exp) + } + } +} + func TestSetWriteConsistency(t *testing.T) { t.Parallel() c := cli.New(CLIENT_VERSION)