// Converts the value to a duration in the given units func (*duration) Call(args ...interface{}) (v interface{}, err error) { if len(args) != 1 && len(args) != 2 { return time.Duration(0), errors.New("duration expects one or two arguments duration(value, unit) where unit is optional depending on the type of value.") } getUnit := func() (time.Duration, error) { if len(args) != 2 { return 0, errors.New("duration expects unit argument for int and float values") } unit, ok := args[1].(time.Duration) if !ok { return 0, fmt.Errorf("invalid duration unit type: %T", args[1]) } return unit, nil } var unit time.Duration switch a := args[0].(type) { case time.Duration: v = a case int64: unit, err = getUnit() v = time.Duration(a) * unit case float64: unit, err = getUnit() v = time.Duration(a * float64(unit)) case string: v, err = influxql.ParseDuration(a) if err != nil { err = fmt.Errorf("invalid duration string %q", a) } default: err = fmt.Errorf("cannot convert %T to duration", a) } return }
// create a new number from a text string func newDur(p int, text string) (*DurationNode, error) { n := &DurationNode{ pos: pos(p), } d, err := influxql.ParseDuration(text) if err != nil { return nil, err } n.Dur = d return n, nil }
// create a new number from a text string func newDur(p position, text string, c *CommentNode) (*DurationNode, error) { n := &DurationNode{ position: p, Comment: c, Literal: text, } d, err := influxql.ParseDuration(text) if err != nil { return nil, err } n.Dur = d return n, nil }
func (vs *Vars) UnmarshalJSON(b []byte) error { dec := json.NewDecoder(bytes.NewReader(b)) dec.UseNumber() data := make(map[string]Var) err := dec.Decode(&data) if err != nil { return err } *vs = make(Vars) for name, v := range data { if v.Value != nil { switch v.Type { case VarDuration: switch value := v.Value.(type) { case json.Number: i, err := value.Int64() if err != nil { return errors.Wrapf(err, "invalid var %v", v) } v.Value = time.Duration(i) case string: d, err := influxql.ParseDuration(value) if err != nil { return errors.Wrapf(err, "invalid duration string for var %s", v) } v.Value = d default: return fmt.Errorf("invalid var %v: expected int or string value", v) } case VarInt: n, ok := v.Value.(json.Number) if !ok { return fmt.Errorf("invalid var %v: expected int value", v) } v.Value, err = n.Int64() if err != nil { return errors.Wrapf(err, "invalid var %v", v) } case VarFloat: n, ok := v.Value.(json.Number) if !ok { return fmt.Errorf("invalid var %v: expected float value", v) } v.Value, err = n.Float64() if err != nil { return errors.Wrapf(err, "invalid var %v", v) } case VarList: values, ok := v.Value.([]interface{}) if !ok { return fmt.Errorf("invalid var %v: expected list of vars", v) } vars := make([]Var, len(values)) for i := range values { m, ok := values[i].(map[string]interface{}) if !ok { return fmt.Errorf("invalid var %v: expected list of vars", v) } if typeText, ok := m["type"]; ok { err := vars[i].Type.UnmarshalText([]byte(typeText.(string))) if err != nil { return err } } else { return fmt.Errorf("invalid var %v: expected list type key in object", v) } if value, ok := m["value"]; ok { vars[i].Value = value } else { return fmt.Errorf("invalid var %v: expected list value key in object", v) } } v.Value = vars } } (*vs)[name] = v } return nil }
func doReplayLive(args []string) error { var replay client.Replay var err error noWait := false switch args[0] { case "batch": replayLiveBatchFlags.Parse(args[1:]) if *rlbTask == "" { replayLiveBatchFlags.Usage() return errors.New("task is required") } if *rlbStart == "" && *rlbPast == "" { replayLiveBatchFlags.Usage() return errors.New("must set one of start or past flags.") } if *rlbStart != "" && *rlbPast != "" { replayLiveBatchFlags.Usage() return errors.New("cannot set both start and past flags.") } start, stop := time.Time{}, time.Now() if *rlbStart != "" { start, err = time.Parse(time.RFC3339Nano, *rlbStart) if err != nil { return err } } if *rlbStop != "" { stop, err = time.Parse(time.RFC3339Nano, *rlbStop) if err != nil { return err } } if *rlbPast != "" { past, err := influxql.ParseDuration(*rlbPast) if err != nil { return err } start = stop.Add(-1 * past) } noWait = *rlbNowait clk := client.Fast if *rlbReal { clk = client.Real } replay, err = cli.ReplayBatch(client.ReplayBatchOptions{ ID: *rlbId, Task: *rlbTask, Start: start, Stop: stop, RecordingTime: *rlbRec, Clock: clk, }) if err != nil { return err } case "query": replayLiveQueryFlags.Parse(args[1:]) if *rlqQuery == "" || *rlqTask == "" { replayLiveQueryFlags.Usage() return errors.New("both query and task are required") } noWait = *rlqNowait clk := client.Fast if *rlqReal { clk = client.Real } replay, err = cli.ReplayQuery(client.ReplayQueryOptions{ ID: *rlqId, Task: *rlqTask, Query: *rlqQuery, Cluster: *rlqCluster, RecordingTime: *rlqRec, Clock: clk, }) if err != nil { return err } default: return fmt.Errorf("Unknown replay-live type %q, expected 'batch' or 'query'", args[0]) } if noWait { fmt.Println(replay.ID) return nil } for replay.Status == client.Running { time.Sleep(500 * time.Millisecond) replay, err = cli.Replay(replay.Link) if err != nil { return err } } fmt.Println(replay.ID) if replay.Status == client.Failed { if replay.Error == "" { replay.Error = "replay failed: unknown reason" } return errors.New(replay.Error) } return nil }
func doRecord(args []string) error { var recording client.Recording var err error noWait := false switch args[0] { case "stream": recordStreamFlags.Parse(args[1:]) if *rsTask == "" || *rsDur == "" { recordStreamFlags.Usage() return errors.New("both task and duration are required") } var duration time.Duration duration, err = influxql.ParseDuration(*rsDur) if err != nil { return err } noWait = *rsNowait recording, err = cli.RecordStream(client.RecordStreamOptions{ ID: *rsId, Task: *rsTask, Stop: time.Now().Add(duration), }) if err != nil { return err } case "batch": recordBatchFlags.Parse(args[1:]) if *rbTask == "" { recordBatchFlags.Usage() return errors.New("task is required") } if *rbStart == "" && *rbPast == "" { recordBatchFlags.Usage() return errors.New("must set one of start or past flags.") } if *rbStart != "" && *rbPast != "" { recordBatchFlags.Usage() return errors.New("cannot set both start and past flags.") } start, stop := time.Time{}, time.Now() if *rbStart != "" { start, err = time.Parse(time.RFC3339Nano, *rbStart) if err != nil { return err } } if *rbStop != "" { stop, err = time.Parse(time.RFC3339Nano, *rbStop) if err != nil { return err } } if *rbPast != "" { past, err := influxql.ParseDuration(*rbPast) if err != nil { return err } start = stop.Add(-1 * past) } noWait = *rbNowait recording, err = cli.RecordBatch(client.RecordBatchOptions{ ID: *rbId, Task: *rbTask, Start: start, Stop: stop, }) if err != nil { return err } case "query": recordQueryFlags.Parse(args[1:]) if *rqQuery == "" || *rqType == "" { recordQueryFlags.Usage() return errors.New("both query and type are required") } var typ client.TaskType switch *rqType { case "stream": typ = client.StreamTask case "batch": typ = client.BatchTask } noWait = *rqNowait recording, err = cli.RecordQuery(client.RecordQueryOptions{ ID: *rqId, Query: *rqQuery, Type: typ, Cluster: *rqCluster, }) if err != nil { return err } default: return fmt.Errorf("Unknown record type %q, expected 'stream', 'batch' or 'query'", args[0]) } if noWait { fmt.Println(recording.ID) return nil } for recording.Status == client.Running { time.Sleep(500 * time.Millisecond) recording, err = cli.Recording(recording.Link) if err != nil { return err } } fmt.Println(recording.ID) if recording.Status == client.Failed { if recording.Error == "" { recording.Error = "recording failed: unknown reason" } return errors.New(recording.Error) } return nil }