influxdb/storage/reads/resultset_lineprotocol.go

130 lines
2.8 KiB
Go

package reads
import (
"errors"
"io"
"strconv"
"github.com/influxdata/influxdb/models"
"github.com/influxdata/influxdb/tsdb/cursors"
)
// ResultSetToLineProtocol transforms rs to line protocol and writes the
// output to wr.
func ResultSetToLineProtocol(wr io.Writer, rs ResultSet) (err error) {
defer rs.Close()
line := make([]byte, 0, 4096)
for rs.Next() {
tags := rs.Tags()
name := tags.Get(models.MeasurementTagKeyBytes)
field := tags.Get(models.FieldKeyTagKeyBytes)
if len(name) == 0 || len(field) == 0 {
return errors.New("missing measurement / field")
}
line = append(line[:0], name...)
if tags.Len() > 2 {
tags = tags[1 : len(tags)-1] // take first and last elements which are measurement and field keys
line = tags.AppendHashKey(line)
}
line = append(line, ' ')
line = append(line, field...)
line = append(line, '=')
err = cursorToLineProtocol(wr, line, rs.Cursor())
if err != nil {
return err
}
}
return rs.Err()
}
func cursorToLineProtocol(wr io.Writer, line []byte, cur cursors.Cursor) error {
var newLine = []byte{'\n'}
switch ccur := cur.(type) {
case cursors.IntegerArrayCursor:
for {
a := ccur.Next()
if a.Len() > 0 {
for i := range a.Timestamps {
buf := strconv.AppendInt(line, a.Values[i], 10)
buf = append(buf, 'i', ' ')
buf = strconv.AppendInt(buf, a.Timestamps[i], 10)
wr.Write(buf)
wr.Write(newLine)
}
} else {
break
}
}
case cursors.FloatArrayCursor:
for {
a := ccur.Next()
if a.Len() > 0 {
for i := range a.Timestamps {
buf := strconv.AppendFloat(line, a.Values[i], 'f', -1, 64)
buf = append(buf, ' ')
buf = strconv.AppendInt(buf, a.Timestamps[i], 10)
wr.Write(buf)
wr.Write(newLine)
}
} else {
break
}
}
case cursors.UnsignedArrayCursor:
for {
a := ccur.Next()
if a.Len() > 0 {
for i := range a.Timestamps {
buf := strconv.AppendUint(line, a.Values[i], 10)
buf = append(buf, 'u', ' ')
buf = strconv.AppendInt(buf, a.Timestamps[i], 10)
wr.Write(buf)
wr.Write(newLine)
}
} else {
break
}
}
case cursors.BooleanArrayCursor:
for {
a := ccur.Next()
if a.Len() > 0 {
for i := range a.Timestamps {
buf := strconv.AppendBool(line, a.Values[i])
buf = append(buf, ' ')
buf = strconv.AppendInt(buf, a.Timestamps[i], 10)
wr.Write(buf)
wr.Write(newLine)
}
} else {
break
}
}
case cursors.StringArrayCursor:
for {
a := ccur.Next()
if a.Len() > 0 {
for i := range a.Timestamps {
buf := strconv.AppendQuote(line, a.Values[i])
buf = append(buf, 'i', ' ')
buf = strconv.AppendInt(buf, a.Timestamps[i], 10)
wr.Write(buf)
wr.Write(newLine)
}
} else {
break
}
}
default:
panic("unreachable")
}
cur.Close()
return cur.Err()
}