X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=proto%2Fproto.go;h=a58725d6f81a6c7ad451390974e311b63a08b0f7;hb=e4d7b0fcc5352abe6d0254abcacab17e69673109;hp=5aadf9aee1885e45f8cc9157545683f6292d57f4;hpb=d0b4eb4d690dff7768b5ae588450fc202d286a6a;p=sysdb%2Fgo.git diff --git a/proto/proto.go b/proto/proto.go index 5aadf9a..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. @@ -87,13 +107,14 @@ type Message struct { Raw []byte } -// Decodes reads a raw message encoded in the SysDB wire format from r. The -// raw body of the message will still be encoded in the wire format. +// Read reads a raw message encoded in the SysDB wire format from r. The +// function parses the header but the raw body of the message will still be +// encoded in the wire format. // // The reader has to be in blocking mode. Otherwise, the client and server // will be out of sync after reading a partial message and cannot recover from // that. -func Decode(r io.Reader) (*Message, error) { +func Read(r io.Reader) (*Message, error) { var header [8]byte if _, err := io.ReadFull(r, header[:]); err != nil { return nil, err @@ -109,13 +130,13 @@ func Decode(r io.Reader) (*Message, error) { return &Message{Status(typ), msg}, nil } -// Encode writes a raw message to w. The raw body of m has to be encoded in -// the SysDB wire format. +// Write writes a raw message to w. The raw body of m has to be encoded in the +// SysDB wire format. The function adds the right header to the message. // // The writer has to be in blocking mode. Otherwise, the client and server // will be out of sync after writing a partial message and cannot recover from // that. -func Encode(w io.Writer, m *Message) error { +func Write(w io.Writer, m *Message) error { var header [8]byte nbo.PutUint32(header[:4], uint32(m.Type)) nbo.PutUint32(header[4:], uint32(len(m.Raw))) @@ -129,4 +150,44 @@ func Encode(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 :