2015-01-23 22:49:23 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2015-03-13 22:37:23 +00:00
|
|
|
"bufio"
|
2015-02-03 21:43:18 +00:00
|
|
|
"encoding/csv"
|
2015-01-23 22:49:23 +00:00
|
|
|
"encoding/json"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
2015-02-03 21:43:18 +00:00
|
|
|
"io"
|
2015-01-23 22:49:23 +00:00
|
|
|
"net/url"
|
|
|
|
"os"
|
2015-01-29 00:15:16 +00:00
|
|
|
"os/user"
|
|
|
|
"path/filepath"
|
2015-03-11 15:23:01 +00:00
|
|
|
"sort"
|
2015-02-03 16:15:11 +00:00
|
|
|
"strconv"
|
2015-01-23 22:49:23 +00:00
|
|
|
"strings"
|
2015-02-03 21:43:18 +00:00
|
|
|
"text/tabwriter"
|
2015-01-23 22:49:23 +00:00
|
|
|
|
|
|
|
"github.com/influxdb/influxdb/client"
|
2015-01-29 00:15:16 +00:00
|
|
|
"github.com/peterh/liner"
|
2015-01-23 22:49:23 +00:00
|
|
|
)
|
|
|
|
|
2015-02-12 06:00:33 +00:00
|
|
|
// These variables are populated via the Go linker.
|
|
|
|
var (
|
|
|
|
version string = "0.9"
|
|
|
|
)
|
|
|
|
|
2015-02-03 16:15:11 +00:00
|
|
|
const (
|
2015-02-03 21:43:18 +00:00
|
|
|
default_host = "localhost"
|
|
|
|
default_port = 8086
|
|
|
|
default_format = "column"
|
2015-02-03 16:15:11 +00:00
|
|
|
)
|
|
|
|
|
2015-02-03 17:22:50 +00:00
|
|
|
type CommandLine struct {
|
|
|
|
Client *client.Client
|
2015-02-03 18:12:05 +00:00
|
|
|
Line *liner.State
|
2015-02-03 17:22:50 +00:00
|
|
|
Host string
|
|
|
|
Port int
|
|
|
|
Username string
|
|
|
|
Password string
|
|
|
|
Database string
|
|
|
|
Version string
|
2015-02-03 21:43:18 +00:00
|
|
|
Pretty bool // controls pretty print for json
|
|
|
|
Format string // controls the output format. Valid values are json, csv, or column
|
2015-03-13 22:37:23 +00:00
|
|
|
Dump bool
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2015-02-03 17:22:50 +00:00
|
|
|
c := CommandLine{}
|
2015-01-23 22:49:23 +00:00
|
|
|
|
|
|
|
fs := flag.NewFlagSet("default", flag.ExitOnError)
|
2015-02-03 17:22:50 +00:00
|
|
|
fs.StringVar(&c.Host, "host", default_host, "influxdb host to connect to")
|
|
|
|
fs.IntVar(&c.Port, "port", default_port, "influxdb port to connect to")
|
2015-02-03 22:01:07 +00:00
|
|
|
fs.StringVar(&c.Username, "username", c.Username, "username to connect to the server.")
|
|
|
|
fs.StringVar(&c.Password, "password", c.Password, `password to connect to the server. Leaving blank will prompt for password (--password="")`)
|
2015-02-03 17:22:50 +00:00
|
|
|
fs.StringVar(&c.Database, "database", c.Database, "database to connect to the server.")
|
2015-02-03 21:43:18 +00:00
|
|
|
fs.StringVar(&c.Format, "output", default_format, "format specifies the format of the server responses: json, csv, or column")
|
2015-03-13 22:37:23 +00:00
|
|
|
fs.BoolVar(&c.Dump, "dump", false, "dump the contents of the given database to stdout")
|
2015-01-23 22:49:23 +00:00
|
|
|
fs.Parse(os.Args[1:])
|
|
|
|
|
2015-02-03 22:01:07 +00:00
|
|
|
var promptForPassword bool
|
|
|
|
// determine if they set the password flag but provided no value
|
|
|
|
for _, v := range os.Args {
|
|
|
|
v = strings.ToLower(v)
|
2015-02-03 22:19:52 +00:00
|
|
|
if (strings.HasPrefix(v, "-password") || strings.HasPrefix(v, "--password")) && c.Password == "" {
|
2015-02-03 22:01:07 +00:00
|
|
|
promptForPassword = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 23:34:05 +00:00
|
|
|
// TODO Determine if we are an ineractive shell or running commands
|
2015-02-12 06:00:33 +00:00
|
|
|
fmt.Println("InfluxDB shell " + version)
|
2015-01-29 00:15:16 +00:00
|
|
|
|
2015-02-03 18:12:05 +00:00
|
|
|
c.Line = liner.NewLiner()
|
|
|
|
defer c.Line.Close()
|
|
|
|
|
|
|
|
if promptForPassword {
|
|
|
|
p, e := c.Line.PasswordPrompt("password: ")
|
|
|
|
if e != nil {
|
|
|
|
fmt.Println("Unable to parse password.")
|
|
|
|
} else {
|
|
|
|
c.Password = p
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
c.connect("")
|
2015-01-29 00:15:16 +00:00
|
|
|
|
2015-03-16 22:31:41 +00:00
|
|
|
if c.Dump {
|
|
|
|
c.dump()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-01-29 00:15:16 +00:00
|
|
|
var historyFile string
|
|
|
|
usr, err := user.Current()
|
|
|
|
// Only load history if we can get the user
|
|
|
|
if err == nil {
|
2015-01-29 00:22:28 +00:00
|
|
|
historyFile = filepath.Join(usr.HomeDir, ".influx_history")
|
2015-01-29 00:15:16 +00:00
|
|
|
|
|
|
|
if f, err := os.Open(historyFile); err == nil {
|
2015-02-03 18:12:05 +00:00
|
|
|
c.Line.ReadHistory(f)
|
2015-01-29 00:15:16 +00:00
|
|
|
f.Close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
2015-02-03 18:12:05 +00:00
|
|
|
l, e := c.Line.Prompt("> ")
|
2015-01-29 00:15:16 +00:00
|
|
|
if e != nil {
|
|
|
|
break
|
|
|
|
}
|
2015-03-03 22:12:19 +00:00
|
|
|
if c.ParseCommand(l) {
|
2015-01-29 00:15:16 +00:00
|
|
|
// write out the history
|
2015-03-03 22:12:19 +00:00
|
|
|
if len(historyFile) > 0 {
|
|
|
|
c.Line.AppendHistory(l)
|
|
|
|
if f, err := os.Create(historyFile); err == nil {
|
|
|
|
c.Line.WriteHistory(f)
|
|
|
|
f.Close()
|
|
|
|
}
|
2015-01-29 00:15:16 +00:00
|
|
|
}
|
2015-03-03 22:12:19 +00:00
|
|
|
} else {
|
|
|
|
break // exit main loop
|
2015-01-29 00:15:16 +00:00
|
|
|
}
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
2015-01-29 00:15:16 +00:00
|
|
|
}
|
|
|
|
|
2015-02-03 17:22:50 +00:00
|
|
|
func (c *CommandLine) ParseCommand(cmd string) bool {
|
2015-02-03 16:15:11 +00:00
|
|
|
lcmd := strings.TrimSpace(strings.ToLower(cmd))
|
2015-01-29 00:15:16 +00:00
|
|
|
switch {
|
|
|
|
case strings.HasPrefix(lcmd, "exit"):
|
|
|
|
// signal the program to exit
|
|
|
|
return false
|
|
|
|
case strings.HasPrefix(lcmd, "gopher"):
|
|
|
|
gopher()
|
|
|
|
case strings.HasPrefix(lcmd, "connect"):
|
|
|
|
c.connect(cmd)
|
2015-02-03 18:12:05 +00:00
|
|
|
case strings.HasPrefix(lcmd, "auth"):
|
|
|
|
c.SetAuth()
|
2015-01-29 00:15:16 +00:00
|
|
|
case strings.HasPrefix(lcmd, "help"):
|
|
|
|
help()
|
2015-02-03 21:43:18 +00:00
|
|
|
case strings.HasPrefix(lcmd, "format"):
|
|
|
|
c.SetFormat(cmd)
|
|
|
|
case strings.HasPrefix(lcmd, "settings"):
|
|
|
|
c.Settings()
|
2015-01-29 00:15:16 +00:00
|
|
|
case strings.HasPrefix(lcmd, "pretty"):
|
2015-02-03 17:22:50 +00:00
|
|
|
c.Pretty = !c.Pretty
|
|
|
|
if c.Pretty {
|
2015-01-29 00:15:16 +00:00
|
|
|
fmt.Println("Pretty print enabled")
|
|
|
|
} else {
|
|
|
|
fmt.Println("Pretty print disabled")
|
|
|
|
}
|
|
|
|
case strings.HasPrefix(lcmd, "use"):
|
2015-01-30 21:31:53 +00:00
|
|
|
c.use(cmd)
|
2015-02-03 16:15:11 +00:00
|
|
|
case lcmd == "":
|
|
|
|
break
|
2015-01-29 00:15:16 +00:00
|
|
|
default:
|
|
|
|
c.executeQuery(cmd)
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
2015-01-29 00:15:16 +00:00
|
|
|
return true
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
|
|
|
|
2015-02-03 17:22:50 +00:00
|
|
|
func (c *CommandLine) connect(cmd string) {
|
2015-01-23 22:49:23 +00:00
|
|
|
var cl *client.Client
|
2015-01-29 00:15:16 +00:00
|
|
|
|
2015-01-23 22:49:23 +00:00
|
|
|
if cmd != "" {
|
2015-02-03 16:15:11 +00:00
|
|
|
// Remove the "connect" keyword if it exists
|
|
|
|
cmd = strings.TrimSpace(strings.Replace(cmd, "connect", "", -1))
|
|
|
|
if cmd == "" {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if strings.Contains(cmd, ":") {
|
|
|
|
h := strings.Split(cmd, ":")
|
|
|
|
if i, e := strconv.Atoi(h[1]); e != nil {
|
|
|
|
fmt.Printf("Connect error: Invalid port number %q: %s\n", cmd, e)
|
|
|
|
return
|
|
|
|
} else {
|
2015-02-03 17:22:50 +00:00
|
|
|
c.Port = i
|
2015-02-03 16:15:11 +00:00
|
|
|
}
|
2015-02-03 16:34:13 +00:00
|
|
|
if h[0] == "" {
|
2015-02-03 17:22:50 +00:00
|
|
|
c.Host = default_host
|
2015-02-03 16:34:13 +00:00
|
|
|
} else {
|
2015-02-03 17:22:50 +00:00
|
|
|
c.Host = h[0]
|
2015-02-03 16:34:13 +00:00
|
|
|
}
|
2015-02-03 16:15:11 +00:00
|
|
|
} else {
|
2015-02-03 17:22:50 +00:00
|
|
|
c.Host = cmd
|
2015-02-03 16:15:11 +00:00
|
|
|
// If they didn't specify a port, always use the default port
|
2015-02-03 17:22:50 +00:00
|
|
|
c.Port = default_port
|
2015-02-03 16:15:11 +00:00
|
|
|
}
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
2015-02-03 16:15:11 +00:00
|
|
|
|
2015-01-23 22:49:23 +00:00
|
|
|
u := url.URL{
|
|
|
|
Scheme: "http",
|
|
|
|
}
|
2015-02-03 17:22:50 +00:00
|
|
|
if c.Port > 0 {
|
|
|
|
u.Host = fmt.Sprintf("%s:%d", c.Host, c.Port)
|
2015-01-23 22:49:23 +00:00
|
|
|
} else {
|
2015-02-03 17:22:50 +00:00
|
|
|
u.Host = c.Host
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
2015-02-03 17:22:50 +00:00
|
|
|
if c.Username != "" {
|
|
|
|
u.User = url.UserPassword(c.Username, c.Password)
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
|
|
|
cl, err := client.NewClient(
|
|
|
|
client.Config{
|
2015-02-11 20:31:15 +00:00
|
|
|
URL: u,
|
|
|
|
Username: c.Username,
|
|
|
|
Password: c.Password,
|
2015-02-12 06:00:33 +00:00
|
|
|
UserAgent: "InfluxDBShell/" + version,
|
2015-01-23 22:49:23 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("Could not create client %s", err)
|
2015-01-26 21:12:58 +00:00
|
|
|
return
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
2015-02-03 17:22:50 +00:00
|
|
|
c.Client = cl
|
|
|
|
if _, v, e := c.Client.Ping(); e != nil {
|
|
|
|
fmt.Printf("Failed to connect to %s\n", c.Client.Addr())
|
2015-01-26 21:12:58 +00:00
|
|
|
} else {
|
2015-02-03 17:22:50 +00:00
|
|
|
c.Version = v
|
2015-03-17 20:57:47 +00:00
|
|
|
fmt.Printf("Connected to %s version %s\n", c.Client.Addr(), c.Version)
|
2015-01-26 21:12:58 +00:00
|
|
|
}
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
|
|
|
|
2015-02-03 18:12:05 +00:00
|
|
|
func (c *CommandLine) SetAuth() {
|
|
|
|
u, e := c.Line.Prompt("username: ")
|
|
|
|
if e != nil {
|
|
|
|
fmt.Printf("Unable to process input: %s", e)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
c.Username = strings.TrimSpace(u)
|
|
|
|
p, e := c.Line.PasswordPrompt("password: ")
|
|
|
|
if e != nil {
|
|
|
|
fmt.Printf("Unable to process input: %s", e)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
c.Password = p
|
|
|
|
}
|
|
|
|
|
2015-02-03 17:22:50 +00:00
|
|
|
func (c *CommandLine) use(cmd string) {
|
2015-02-28 15:25:46 +00:00
|
|
|
args := strings.Split(strings.TrimSpace(cmd), " ")
|
2015-01-30 21:31:53 +00:00
|
|
|
if len(args) != 2 {
|
|
|
|
fmt.Printf("Could not parse database name from %q.\n", cmd)
|
|
|
|
return
|
|
|
|
}
|
2015-02-28 15:25:46 +00:00
|
|
|
d := args[1]
|
2015-02-03 17:22:50 +00:00
|
|
|
c.Database = d
|
2015-01-30 21:31:53 +00:00
|
|
|
fmt.Printf("Using database %s\n", d)
|
|
|
|
}
|
|
|
|
|
2015-02-03 21:43:18 +00:00
|
|
|
func (c *CommandLine) SetFormat(cmd string) {
|
|
|
|
// Remove the "format" keyword if it exists
|
|
|
|
cmd = strings.TrimSpace(strings.Replace(cmd, "format", "", -1))
|
|
|
|
// normalize cmd
|
|
|
|
cmd = strings.ToLower(cmd)
|
|
|
|
|
|
|
|
switch cmd {
|
|
|
|
case "json", "csv", "column":
|
|
|
|
c.Format = cmd
|
|
|
|
default:
|
|
|
|
fmt.Printf("Unknown format %q. Please use json, csv, or column.\n", cmd)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-10 23:30:43 +00:00
|
|
|
func (c *CommandLine) dump() {
|
2015-03-13 22:37:23 +00:00
|
|
|
response, err := c.Client.Dump(c.Database)
|
2015-03-16 22:31:41 +00:00
|
|
|
defer response.Close()
|
2015-03-10 23:30:43 +00:00
|
|
|
if err != nil {
|
2015-03-16 22:31:41 +00:00
|
|
|
fmt.Printf("Dump failed. %s\n", err)
|
2015-03-13 22:37:23 +00:00
|
|
|
} else {
|
2015-03-16 22:31:41 +00:00
|
|
|
scanner := bufio.NewScanner(response)
|
2015-03-13 22:37:23 +00:00
|
|
|
for scanner.Scan() {
|
|
|
|
fmt.Println(scanner.Text())
|
2015-03-10 23:30:43 +00:00
|
|
|
}
|
2015-03-13 22:37:23 +00:00
|
|
|
if err := scanner.Err(); err != nil {
|
2015-03-16 22:31:41 +00:00
|
|
|
fmt.Printf("Dump failed. %s\n", err)
|
2015-03-10 23:30:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-03 17:22:50 +00:00
|
|
|
func (c *CommandLine) executeQuery(query string) {
|
|
|
|
results, err := c.Client.Query(client.Query{Command: query, Database: c.Database})
|
2015-01-23 22:49:23 +00:00
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("ERR: %s\n", err)
|
2015-01-29 00:15:16 +00:00
|
|
|
return
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
2015-02-10 16:12:18 +00:00
|
|
|
c.FormatResults(results, os.Stdout)
|
2015-02-10 15:54:19 +00:00
|
|
|
if results.Error() != nil {
|
|
|
|
fmt.Printf("ERR: %s\n", results.Error())
|
2015-02-10 16:12:18 +00:00
|
|
|
if c.Database == "" {
|
|
|
|
fmt.Println("Warning: It is possible this error is due to not setting a database.")
|
|
|
|
fmt.Println(`Please set a database with the command "use <database>".`)
|
|
|
|
}
|
2015-02-03 21:43:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CommandLine) FormatResults(results *client.Results, w io.Writer) {
|
|
|
|
switch c.Format {
|
|
|
|
case "json":
|
2015-03-11 15:12:40 +00:00
|
|
|
c.writeJSON(results, w)
|
2015-02-03 21:43:18 +00:00
|
|
|
case "csv":
|
2015-03-11 15:07:00 +00:00
|
|
|
c.writeCSV(results, w)
|
2015-02-03 21:43:18 +00:00
|
|
|
case "column":
|
2015-03-11 15:07:00 +00:00
|
|
|
c.writeColumns(results, w)
|
2015-02-03 21:43:18 +00:00
|
|
|
default:
|
|
|
|
fmt.Fprintf(w, "Unknown output format %q.\n", c.Format)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-11 15:12:40 +00:00
|
|
|
func (c *CommandLine) writeJSON(results *client.Results, w io.Writer) {
|
2015-01-29 00:15:16 +00:00
|
|
|
var data []byte
|
2015-02-03 21:43:18 +00:00
|
|
|
var err error
|
2015-03-11 15:12:40 +00:00
|
|
|
if c.Pretty {
|
2015-01-29 00:15:16 +00:00
|
|
|
data, err = json.MarshalIndent(results, "", " ")
|
|
|
|
} else {
|
|
|
|
data, err = json.Marshal(results)
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
2015-01-29 00:15:16 +00:00
|
|
|
if err != nil {
|
2015-02-03 21:43:18 +00:00
|
|
|
fmt.Fprintf(w, "Unable to parse json: %s\n", err)
|
2015-01-29 00:15:16 +00:00
|
|
|
return
|
|
|
|
}
|
2015-02-03 21:43:18 +00:00
|
|
|
fmt.Fprintln(w, string(data))
|
|
|
|
}
|
|
|
|
|
2015-03-11 15:07:00 +00:00
|
|
|
func (c *CommandLine) writeCSV(results *client.Results, w io.Writer) {
|
2015-02-03 21:43:18 +00:00
|
|
|
csvw := csv.NewWriter(w)
|
|
|
|
for _, result := range results.Results {
|
2015-02-03 22:10:32 +00:00
|
|
|
// Create a tabbed writer for each result as they won't always line up
|
2015-03-11 15:07:00 +00:00
|
|
|
rows := c.formatResults(result, "\t")
|
2015-02-03 21:43:18 +00:00
|
|
|
for _, r := range rows {
|
|
|
|
csvw.Write(strings.Split(r, "\t"))
|
|
|
|
}
|
|
|
|
csvw.Flush()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-11 15:07:00 +00:00
|
|
|
func (c *CommandLine) writeColumns(results *client.Results, w io.Writer) {
|
2015-02-03 21:43:18 +00:00
|
|
|
for _, result := range results.Results {
|
|
|
|
// Create a tabbed writer for each result a they won't always line up
|
|
|
|
w := new(tabwriter.Writer)
|
|
|
|
w.Init(os.Stdout, 0, 8, 1, '\t', 0)
|
2015-03-11 15:07:00 +00:00
|
|
|
csv := c.formatResults(result, "\t")
|
2015-02-03 21:43:18 +00:00
|
|
|
for _, r := range csv {
|
|
|
|
fmt.Fprintln(w, r)
|
|
|
|
}
|
|
|
|
w.Flush()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-11 15:07:00 +00:00
|
|
|
// formatResults will behave differently if you are formatting for columns or csv
|
|
|
|
func (c *CommandLine) formatResults(result client.Result, separator string) []string {
|
2015-02-03 21:43:18 +00:00
|
|
|
rows := []string{}
|
|
|
|
// Create a tabbed writer for each result a they won't always line up
|
2015-02-23 05:21:49 +00:00
|
|
|
for i, row := range result.Series {
|
2015-03-10 22:44:50 +00:00
|
|
|
// gather tags
|
|
|
|
tags := []string{}
|
|
|
|
for k, v := range row.Tags {
|
|
|
|
tags = append(tags, fmt.Sprintf("%s=%s", k, v))
|
2015-03-11 15:23:01 +00:00
|
|
|
sort.Strings(tags)
|
2015-03-10 22:44:50 +00:00
|
|
|
}
|
|
|
|
|
2015-03-10 23:23:26 +00:00
|
|
|
columnNames := []string{}
|
2015-03-10 22:44:50 +00:00
|
|
|
|
2015-03-11 15:07:00 +00:00
|
|
|
// Only put name/tags in a column if format is csv
|
|
|
|
if c.Format == "csv" {
|
|
|
|
if len(tags) > 0 {
|
|
|
|
columnNames = append([]string{"tags"}, columnNames...)
|
2015-02-03 21:43:18 +00:00
|
|
|
}
|
2015-03-11 15:07:00 +00:00
|
|
|
|
|
|
|
if row.Name != "" {
|
|
|
|
columnNames = append([]string{"name"}, columnNames...)
|
|
|
|
}
|
2015-03-10 23:23:26 +00:00
|
|
|
}
|
2015-03-11 15:07:00 +00:00
|
|
|
|
2015-03-10 23:23:26 +00:00
|
|
|
for _, column := range row.Columns {
|
|
|
|
columnNames = append(columnNames, column)
|
2015-02-03 21:43:18 +00:00
|
|
|
}
|
2015-03-11 15:07:00 +00:00
|
|
|
|
|
|
|
// Output a line separator if we have more than one set or results and format is column
|
|
|
|
if i > 0 && c.Format == "column" {
|
2015-03-10 23:30:05 +00:00
|
|
|
rows = append(rows, "")
|
|
|
|
}
|
2015-03-10 22:44:50 +00:00
|
|
|
|
2015-03-11 15:14:41 +00:00
|
|
|
// If we are column format, we break out the name/tag to seperate lines
|
2015-03-11 15:07:00 +00:00
|
|
|
if c.Format == "column" {
|
|
|
|
if row.Name != "" {
|
2015-03-11 20:03:28 +00:00
|
|
|
n := fmt.Sprintf("name: %s", row.Name)
|
|
|
|
rows = append(rows, n)
|
2015-03-11 15:07:00 +00:00
|
|
|
if len(tags) == 0 {
|
2015-03-11 20:03:28 +00:00
|
|
|
l := strings.Repeat("-", len(n))
|
2015-03-11 15:07:00 +00:00
|
|
|
rows = append(rows, l)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(tags) > 0 {
|
|
|
|
t := fmt.Sprintf("tags: %s", (strings.Join(tags, ", ")))
|
|
|
|
rows = append(rows, t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rows = append(rows, strings.Join(columnNames, separator))
|
|
|
|
|
|
|
|
// if format is column, break tags to their own line/format
|
|
|
|
if c.Format == "column" && len(tags) > 0 {
|
2015-02-03 21:43:18 +00:00
|
|
|
lines := []string{}
|
|
|
|
for _, columnName := range columnNames {
|
|
|
|
lines = append(lines, strings.Repeat("-", len(columnName)))
|
|
|
|
}
|
2015-03-11 15:07:00 +00:00
|
|
|
rows = append(rows, strings.Join(lines, separator))
|
2015-02-03 21:43:18 +00:00
|
|
|
}
|
2015-03-10 22:44:50 +00:00
|
|
|
|
2015-02-03 21:43:18 +00:00
|
|
|
for _, v := range row.Values {
|
2015-03-10 22:44:50 +00:00
|
|
|
var values []string
|
2015-03-11 15:07:00 +00:00
|
|
|
if c.Format == "csv" {
|
|
|
|
if row.Name != "" {
|
|
|
|
values = append(values, row.Name)
|
|
|
|
}
|
|
|
|
if len(tags) > 0 {
|
|
|
|
values = append(values, strings.Join(tags, ","))
|
|
|
|
}
|
2015-03-10 22:44:50 +00:00
|
|
|
}
|
2015-02-03 21:43:18 +00:00
|
|
|
|
|
|
|
for _, vv := range v {
|
|
|
|
values = append(values, interfaceToString(vv))
|
|
|
|
}
|
2015-03-11 15:07:00 +00:00
|
|
|
rows = append(rows, strings.Join(values, separator))
|
2015-03-11 17:05:23 +00:00
|
|
|
}
|
|
|
|
// Outout a line separator if in column format
|
|
|
|
if c.Format == "column" {
|
|
|
|
rows = append(rows, "")
|
2015-02-03 21:43:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return rows
|
|
|
|
}
|
|
|
|
|
|
|
|
func interfaceToString(v interface{}) string {
|
|
|
|
switch t := v.(type) {
|
|
|
|
case nil:
|
|
|
|
return ""
|
|
|
|
case bool:
|
|
|
|
return fmt.Sprintf("%v", v)
|
|
|
|
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr:
|
|
|
|
return fmt.Sprintf("%d", t)
|
|
|
|
case float32, float64:
|
|
|
|
return fmt.Sprintf("%v", t)
|
|
|
|
default:
|
|
|
|
return fmt.Sprintf("%v", t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CommandLine) Settings() {
|
|
|
|
w := new(tabwriter.Writer)
|
|
|
|
w.Init(os.Stdout, 0, 8, 1, '\t', 0)
|
|
|
|
if c.Port > 0 {
|
|
|
|
fmt.Fprintf(w, "Host\t%s:%d\n", c.Host, c.Port)
|
|
|
|
} else {
|
|
|
|
fmt.Fprintf(w, "Host\t%s\n", c.Host)
|
2015-01-30 21:38:27 +00:00
|
|
|
}
|
2015-02-03 21:43:18 +00:00
|
|
|
fmt.Fprintf(w, "Username\t%s\n", c.Username)
|
|
|
|
fmt.Fprintf(w, "Database\t%s\n", c.Database)
|
|
|
|
fmt.Fprintf(w, "Pretty\t%v\n", c.Pretty)
|
|
|
|
fmt.Fprintf(w, "Format\t%s\n", c.Format)
|
|
|
|
fmt.Fprintln(w)
|
|
|
|
w.Flush()
|
2015-01-29 00:15:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func help() {
|
|
|
|
fmt.Println(`Usage:
|
|
|
|
connect <host:port> connect to another node
|
2015-02-03 18:12:05 +00:00
|
|
|
auth prompt for username and password
|
2015-01-29 00:15:16 +00:00
|
|
|
pretty toggle pretty print
|
|
|
|
use <db_name> set current databases
|
2015-02-03 21:43:18 +00:00
|
|
|
format <format> set the output format: json, csv, or column
|
|
|
|
settings output the current settings for the shell
|
2015-01-29 00:15:16 +00:00
|
|
|
exit quit the influx shell
|
|
|
|
|
|
|
|
show databases show database names
|
|
|
|
show series show series information
|
|
|
|
show measurements show measurement information
|
|
|
|
show tag keys show tag key information
|
|
|
|
show tag values show tag value information
|
|
|
|
|
|
|
|
a full list of influxql commands can be found at:
|
|
|
|
http://influxdb.com/docs
|
|
|
|
`)
|
2015-01-23 22:49:23 +00:00
|
|
|
}
|
2015-01-23 23:34:05 +00:00
|
|
|
|
2015-01-26 16:24:17 +00:00
|
|
|
func gopher() {
|
2015-01-23 23:34:05 +00:00
|
|
|
fmt.Println(`
|
2015-01-26 16:24:17 +00:00
|
|
|
.-::-::://:-::- .:/++/'
|
|
|
|
'://:-''/oo+//++o+/.://o- ./+:
|
|
|
|
.:-. '++- .o/ '+yydhy' o-
|
|
|
|
.:/. .h: :osoys .smMN- :/
|
|
|
|
-/:.' s- /MMMymh. '/y/ s'
|
|
|
|
-+s:'''' d -mMMms// '-/o:
|
|
|
|
-/++/++/////:. o: '... s- :s.
|
|
|
|
:+-+s-' ':/' 's- /+ 'o:
|
|
|
|
'+-'o: /ydhsh. '//. '-o- o-
|
|
|
|
.y. o: .MMMdm+y ':+++:::/+:.' s:
|
|
|
|
.-h/ y- 'sdmds'h -+ydds:::-.' 'h.
|
|
|
|
.//-.d' o: '.' 'dsNMMMNh:.:++' :y
|
|
|
|
+y. 'd 's. .s:mddds: ++ o/
|
|
|
|
'N- odd 'o/. './o-s-' .---+++' o-
|
|
|
|
'N' yNd .://:/:::::. -s -+/s/./s' 'o/'
|
|
|
|
so' .h '''' ////s: '+. .s +y'
|
|
|
|
os/-.y' 's' 'y::+ +d'
|
|
|
|
'.:o/ -+:-:.' so.---.'
|
|
|
|
o' 'd-.''/s'
|
|
|
|
.s' :y.''.y
|
|
|
|
-s mo:::'
|
|
|
|
:: yh
|
|
|
|
// '''' /M'
|
|
|
|
o+ .s///:/. 'N:
|
|
|
|
:+ /: -s' ho
|
|
|
|
's- -/s/:+/.+h' +h
|
|
|
|
ys' ':' '-. -d
|
|
|
|
oh .h
|
|
|
|
/o .s
|
|
|
|
s. .h
|
|
|
|
-y .d
|
|
|
|
m/ -h
|
|
|
|
+d /o
|
|
|
|
'N- y:
|
|
|
|
h: m.
|
|
|
|
s- -d
|
|
|
|
o- s+
|
|
|
|
+- 'm'
|
|
|
|
s/ oo--.
|
|
|
|
y- /s ':+'
|
|
|
|
s' 'od--' .d:
|
|
|
|
-+ ':o: ':+-/+
|
|
|
|
y- .:+- '
|
|
|
|
//o- '.:+/.
|
|
|
|
.-:+/' ''-/+/.
|
|
|
|
./:' ''.:o+/-'
|
|
|
|
.+o:/:/+-' ''.-+ooo/-'
|
|
|
|
o: -h///++////-.
|
|
|
|
/: .o/
|
|
|
|
//+ 'y
|
|
|
|
./sooy.
|
|
|
|
|
2015-01-23 23:34:05 +00:00
|
|
|
`)
|
|
|
|
}
|