diff --git a/server/query.go b/server/query.go
index 6f9722c64a6c37130311bf3e15b9586039964764..6d8fddf252d8159e7c3facbf5b7e24b43d5120f5 100644 (file)
--- a/server/query.go
+++ b/server/query.go
import (
"errors"
"fmt"
- "log"
"strings"
"time"
"unicode"
+ "github.com/sysdb/go/client"
"github.com/sysdb/go/proto"
- "github.com/sysdb/go/sysdb"
)
func listAll(req request, s *Server) (*page, error) {
return nil, fmt.Errorf("%s not found", strings.Title(req.cmd))
}
- res, err := s.query("LIST %s", identifier(req.cmd))
+ q, err := client.QueryString("LIST %s", client.Identifier(req.cmd))
+ if err != nil {
+ return nil, err
+ }
+ res, err := s.c.Query(q)
if err != nil {
return nil, err
}
}
if fields := strings.SplitN(tok, ":", 2); len(fields) == 2 {
+ // Query: [<type>:] [<sibling-type>.]<attribute>:<value> ...
if i == 0 && fields[1] == "" {
typ = fields[0]
+ } else if elems := strings.Split(fields[0], "."); len(elems) > 1 {
+ objs := elems[:len(elems)-1]
+ for _, o := range objs {
+ if o != "host" && o != "service" && o != "metric" {
+ return nil, fmt.Errorf("Invalid object type %q", o)
+ }
+ }
+ args += fmt.Sprintf(" %s.attribute[%s] = %s",
+ strings.Join(objs, "."), proto.EscapeString(elems[len(elems)-1]),
+ proto.EscapeString(fields[1]))
} else {
args += fmt.Sprintf(" attribute[%s] = %s",
proto.EscapeString(fields[0]), proto.EscapeString(fields[1]))
}
}
- res, err := s.query("LOOKUP %s MATCHING"+args, identifier(typ))
+ q, err := client.QueryString("LOOKUP %s MATCHING"+args, client.Identifier(typ))
+ if err != nil {
+ return nil, err
+ }
+ res, err := s.c.Query(q)
if err != nil {
return nil, err
}
return nil, fmt.Errorf("%s not found", strings.Title(req.cmd))
}
- var res interface{}
+ var q string
var err error
switch req.cmd {
case "host":
if len(req.args) != 1 {
return nil, fmt.Errorf("%s not found", strings.Title(req.cmd))
}
- res, err = s.query("FETCH host %s", req.args[0])
+ q, err = client.QueryString("FETCH host %s", req.args[0])
case "service", "metric":
if len(req.args) != 2 {
return nil, fmt.Errorf("%s not found", strings.Title(req.cmd))
}
- res, err = s.query("FETCH %s %s.%s", identifier(req.cmd), req.args[0], req.args[1])
- if err == nil && req.cmd == "metric" {
- return metric(req, res, s)
- }
+ q, err = client.QueryString("FETCH %s %s.%s", client.Identifier(req.cmd), req.args[0], req.args[1])
default:
panic("Unknown request: fetch(" + req.cmd + ")")
}
if err != nil {
return nil, err
}
+
+ res, err := s.c.Query(q)
+ if err != nil {
+ return nil, err
+ }
+ if req.cmd == "metric" {
+ return metric(req, res, s)
+ }
return tmpl(s.results[req.cmd], res)
}
return !unicode.IsSpace(r)
}
-type identifier string
-
-func (s *Server) query(cmd string, args ...interface{}) (interface{}, error) {
- c := <-s.conns
- defer func() { s.conns <- c }()
-
- for i, arg := range args {
- switch v := arg.(type) {
- case identifier:
- // Nothing to do.
- case string:
- args[i] = proto.EscapeString(v)
- case time.Time:
- args[i] = v.Format(datetime)
- default:
- panic(fmt.Sprintf("query: invalid type %T", arg))
- }
- }
-
- cmd = fmt.Sprintf(cmd, args...)
- m := &proto.Message{
- Type: proto.ConnectionQuery,
- Raw: []byte(cmd),
- }
- if err := c.Send(m); err != nil {
- return nil, fmt.Errorf("Query %q: %v", cmd, err)
- }
-
- for {
- m, err := c.Receive()
- if err != nil {
- return nil, fmt.Errorf("Failed to receive server response: %v", err)
- }
- if m.Type == proto.ConnectionLog {
- log.Println(string(m.Raw[4:]))
- continue
- } else if m.Type == proto.ConnectionError {
- return nil, errors.New(string(m.Raw))
- }
-
- t, err := m.DataType()
- if err != nil {
- return nil, fmt.Errorf("Failed to unmarshal response: %v", err)
- }
-
- var res interface{}
- switch t {
- case proto.HostList:
- var hosts []sysdb.Host
- err = proto.Unmarshal(m, &hosts)
- res = hosts
- case proto.Host:
- var host sysdb.Host
- err = proto.Unmarshal(m, &host)
- res = host
- case proto.Timeseries:
- var ts sysdb.Timeseries
- err = proto.Unmarshal(m, &ts)
- res = ts
- default:
- return nil, fmt.Errorf("Unsupported data type %d", t)
- }
- if err != nil {
- return nil, fmt.Errorf("Failed to unmarshal response: %v", err)
- }
- return res, nil
- }
-}
-
// vim: set tw=78 sw=4 sw=4 noexpandtab :