X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=proto%2Fproto.go;h=a58725d6f81a6c7ad451390974e311b63a08b0f7;hb=e4d7b0fcc5352abe6d0254abcacab17e69673109;hp=7f53f3d82c0732e2b9643f1937e15eb01e113c6e;hpb=414ad0469c90b2c5487394646571e4e737d747be;p=sysdb%2Fgo.git diff --git a/proto/proto.go b/proto/proto.go index 7f53f3d..a58725d 100644 --- a/proto/proto.go +++ b/proto/proto.go @@ -30,7 +30,10 @@ package proto import ( "encoding/binary" + "encoding/json" + "fmt" "io" + "strings" ) // Network byte order. @@ -77,8 +80,25 @@ const ( // 'TIMESERIES' command in the server. ConnectionTimeseries = Status(7) - // ConnectionExpr is the internal state for expression parsing. - ConnectionExpr = Status(100) + // ConnectionMatcher is the internal state for parsing matchers. + ConnectionMatcher = Status(100) + // ConnectionExpr is the internal state for parsing expressions. + ConnectionExpr = Status(101) + + // ConnectionServerVersion is the state requesting the server version. + ConnectionServerVersion = Status(1000) +) + +// The DataType describes the type of data in a ConnectionData message. +type DataType int + +const ( + // A HostList can be unmarshaled to []sysdb.Host. + HostList DataType = iota + // A Host can be unmarshaled to sysdb.Host. + Host + // A Timeseries can be unmarshaled to sysdb.Timeseries. + Timeseries ) // A Message represents a raw message of the SysDB front-end protocol. @@ -130,4 +150,44 @@ func Write(w io.Writer, m *Message) error { return nil } +// DataType determines the type of data in a ConnectionData message. +func (m Message) DataType() (DataType, error) { + if m.Type != ConnectionData { + return 0, fmt.Errorf("message is not of type DATA") + } + + typ := nbo.Uint32(m.Raw[:4]) + switch Status(typ) { + case ConnectionList, ConnectionLookup: + return HostList, nil + case ConnectionFetch: + return Host, nil + case ConnectionTimeseries: + return Timeseries, nil + } + return 0, fmt.Errorf("unknown DATA type %d", typ) +} + +// Unmarshal parses the raw body of m and stores the result in the value +// pointed to by v which has to match the type of the message and its data. +func Unmarshal(m *Message, v interface{}) error { + if m.Type != ConnectionData { + return fmt.Errorf("unmarshaling message of type %d not supported", m.Type) + } + if len(m.Raw) == 0 { // empty command + return nil + } else if len(m.Raw) < 4 { + return fmt.Errorf("DATA message body too short") + } + return json.Unmarshal(m.Raw[4:], v) +} + +// EscapeString returns the quoted and escaped string s suitable for use +// in a query. +func EscapeString(s string) string { + // Currently, the server only handles double-quotes. + // Backslashes do not serve any special purpose. + return "'" + strings.Replace(s, "'", "''", -1) + "'" +} + // vim: set tw=78 sw=4 sw=4 noexpandtab :