Commit 73c4bef7 by Kyle Brandt Committed by GitHub

Dependency: sdk's dataframe package renamed to data (#22700)

* use sdk 0.24.0
parent 2c6993f1
...@@ -32,7 +32,7 @@ require ( ...@@ -32,7 +32,7 @@ require (
github.com/gorilla/websocket v1.4.1 github.com/gorilla/websocket v1.4.1
github.com/gosimple/slug v1.4.2 github.com/gosimple/slug v1.4.2
github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4
github.com/grafana/grafana-plugin-sdk-go v0.21.0 github.com/grafana/grafana-plugin-sdk-go v0.24.0
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd
github.com/hashicorp/go-plugin v1.0.1 github.com/hashicorp/go-plugin v1.0.1
github.com/hashicorp/go-version v1.1.0 github.com/hashicorp/go-version v1.1.0
......
...@@ -135,6 +135,10 @@ github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 h1:SP ...@@ -135,6 +135,10 @@ github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 h1:SP
github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4/go.mod h1:nc0XxBzjeGcrMltCDw269LoWF9S8ibhgxolCdA1R8To= github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4/go.mod h1:nc0XxBzjeGcrMltCDw269LoWF9S8ibhgxolCdA1R8To=
github.com/grafana/grafana-plugin-sdk-go v0.21.0 h1:5en5MdVFgeD9tuHDuJgwHYdIVjPs0PN0a7ZQ2bZNxNk= github.com/grafana/grafana-plugin-sdk-go v0.21.0 h1:5en5MdVFgeD9tuHDuJgwHYdIVjPs0PN0a7ZQ2bZNxNk=
github.com/grafana/grafana-plugin-sdk-go v0.21.0/go.mod h1:G6Ov9M+FDOZXNw8eKXINO6XzqdUvTs7huwyQp5jLTBQ= github.com/grafana/grafana-plugin-sdk-go v0.21.0/go.mod h1:G6Ov9M+FDOZXNw8eKXINO6XzqdUvTs7huwyQp5jLTBQ=
github.com/grafana/grafana-plugin-sdk-go v0.22.1-0.20200310164332-6b4c0d952d70 h1:VQFBaWHlxwjb4VB5HuXtuucMzXJ7xZGGASzbqA3VtVo=
github.com/grafana/grafana-plugin-sdk-go v0.22.1-0.20200310164332-6b4c0d952d70/go.mod h1:G6Ov9M+FDOZXNw8eKXINO6XzqdUvTs7huwyQp5jLTBQ=
github.com/grafana/grafana-plugin-sdk-go v0.24.0 h1:sgd9rAQMmB0rAIMd4JVMFM0Gc+CTHoDwN5oxkPjVrGw=
github.com/grafana/grafana-plugin-sdk-go v0.24.0/go.mod h1:G6Ov9M+FDOZXNw8eKXINO6XzqdUvTs7huwyQp5jLTBQ=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd h1:rNuUHR+CvK1IS89MMtcF0EpcVMZtjKfPRp4MEmt/aTs= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd h1:rNuUHR+CvK1IS89MMtcF0EpcVMZtjKfPRp4MEmt/aTs=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE= github.com/hashicorp/go-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE=
......
...@@ -7,7 +7,7 @@ import ( ...@@ -7,7 +7,7 @@ import (
"path" "path"
"strconv" "strconv"
"github.com/grafana/grafana-plugin-sdk-go/dataframe" "github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2" "github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
...@@ -189,7 +189,7 @@ func (s *transformCallback) QueryData(ctx context.Context, req *pluginv2.QueryDa ...@@ -189,7 +189,7 @@ func (s *transformCallback) QueryData(ctx context.Context, req *pluginv2.QueryDa
if err != nil { if err != nil {
return nil, err return nil, err
} }
encFrame, err := dataframe.MarshalArrow(frame) encFrame, err := data.MarshalArrow(frame)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -3,19 +3,19 @@ package tsdb ...@@ -3,19 +3,19 @@ package tsdb
import ( import (
"time" "time"
"github.com/grafana/grafana-plugin-sdk-go/dataframe" "github.com/grafana/grafana-plugin-sdk-go/data"
) )
// SeriesToFrame converts a TimeSeries to a sdk Frame // SeriesToFrame converts a TimeSeries to a sdk Frame
func SeriesToFrame(series *TimeSeries) (*dataframe.Frame, error) { func SeriesToFrame(series *TimeSeries) (*data.Frame, error) {
timeVec := make([]*time.Time, len(series.Points)) timeVec := make([]*time.Time, len(series.Points))
floatVec := make([]*float64, len(series.Points)) floatVec := make([]*float64, len(series.Points))
for idx, point := range series.Points { for idx, point := range series.Points {
timeVec[idx], floatVec[idx] = convertTSDBTimePoint(point) timeVec[idx], floatVec[idx] = convertTSDBTimePoint(point)
} }
frame := dataframe.New(series.Name, frame := data.NewFrame(series.Name,
dataframe.NewField("time", nil, timeVec), data.NewField("time", nil, timeVec),
dataframe.NewField("value", dataframe.Labels(series.Tags), floatVec), data.NewField("value", data.Labels(series.Tags), floatVec),
) )
return frame, nil return frame, nil
......
package plugin
import (
"fmt"
"net/http"
"net/http/pprof"
"os"
hclog "github.com/hashicorp/go-hclog"
)
// SetupPluginEnvironment will read the environment variables and apply the
// standard environment behavior. As the SDK evolves, this will likely change!
func SetupPluginEnvironment(pluginID string) hclog.Logger {
pluginLogger := hclog.New(&hclog.LoggerOptions{
Name: pluginID,
// TODO: How to make level configurable?
Level: hclog.LevelFromString("DEBUG"),
JSONFormat: true,
// Color: hclog.ColorOff, (when we use 0.12)
})
// Enable profiler
profilerEnabled := false
if value, ok := os.LookupEnv("GF_PLUGINS_PROFILER"); ok {
// compare value to plugin name
if value == pluginID {
profilerEnabled = true
}
}
pluginLogger.Info("Profiler", "enabled", profilerEnabled)
if profilerEnabled {
profilerPort := "6060"
if value, ok := os.LookupEnv("GF_PLUGINS_PROFILER_PORT"); ok {
profilerPort = value
}
pluginLogger.Info("Profiler", "port", profilerPort)
portConfig := fmt.Sprintf(":%s", profilerPort)
r := http.NewServeMux()
r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)
go func() {
if err := http.ListenAndServe(portConfig, r); err != nil {
pluginLogger.Error("Error Running profiler: %s", err.Error())
}
}()
}
return pluginLogger
}
package dataframe package data
import ( import (
"github.com/apache/arrow/go/arrow" "github.com/apache/arrow/go/arrow"
......
package dataframe package data
import "encoding/json" import "encoding/json"
// Warning contains information about problems in a dataframe. // Warning contains information about problems in a data.
type Warning struct { type Warning struct {
// Short message (typically shown in the header) // Short message (typically shown in the header)
Message string `json:"message,omitempty"` Message string `json:"message,omitempty"`
......
package dataframe // Package data provides data structures that Grafana recognizes. The Frame
// object represents a Grafana Dataframe which can represent data such as tables
// and time series.
package data
import ( import (
"fmt" "fmt"
"math"
"sort" "sort"
"strings" "strings"
"time" "time"
"github.com/google/go-cmp/cmp"
) )
// Frame represents a columnar storage with optional labels. // Frame represents a columnar storage with optional labels.
...@@ -21,7 +27,7 @@ type Frame struct { ...@@ -21,7 +27,7 @@ type Frame struct {
type Field struct { type Field struct {
Name string Name string
Config *FieldConfig Config *FieldConfig
Vector Vector // TODO? in the frontend, the variable is called "Values" vector vector // TODO? in the frontend, the variable is called "Values"
Labels Labels Labels Labels
} }
...@@ -29,13 +35,13 @@ type Field struct { ...@@ -29,13 +35,13 @@ type Field struct {
type Fields []*Field type Fields []*Field
// AppendRow adds a new row to the Frame by appending to each element of vals to // AppendRow adds a new row to the Frame by appending to each element of vals to
// the corresponding Field in the dataframe. // the corresponding Field in the data.
// The dataframe's Fields and the Fields' Vectors must be initalized or AppendRow will panic. // The Frame's Fields must be initalized or AppendRow will panic.
// The number of arguments must match the number of Fields in the Frame and each type must coorespond // The number of arguments must match the number of Fields in the Frame and each type must coorespond
// to the Field type or AppendRow will panic. // to the Field type or AppendRow will panic.
func (f *Frame) AppendRow(vals ...interface{}) { func (f *Frame) AppendRow(vals ...interface{}) {
for i, v := range vals { for i, v := range vals {
f.Fields[i].Vector.Append(v) f.Fields[i].vector.Append(v)
} }
} }
...@@ -45,7 +51,7 @@ func (f *Frame) AppendWarning(message string, details string) { ...@@ -45,7 +51,7 @@ func (f *Frame) AppendWarning(message string, details string) {
} }
// AppendRowSafe adds a new row to the Frame by appending to each each element of vals to // AppendRowSafe adds a new row to the Frame by appending to each each element of vals to
// the corresponding Field in the dataframe. It has the some constraints as AppendRow but will // the corresponding Field in the data. It has the some constraints as AppendRow but will
// return an error under those conditions instead of panicing. // return an error under those conditions instead of panicing.
func (f *Frame) AppendRowSafe(vals ...interface{}) error { func (f *Frame) AppendRowSafe(vals ...interface{}) error {
if len(vals) != len(f.Fields) { if len(vals) != len(f.Fields) {
...@@ -53,29 +59,44 @@ func (f *Frame) AppendRowSafe(vals ...interface{}) error { ...@@ -53,29 +59,44 @@ func (f *Frame) AppendRowSafe(vals ...interface{}) error {
} }
// check validity before any modification // check validity before any modification
for i, v := range vals { for i, v := range vals {
if f.Fields[i] == nil { if f.Fields[i] == nil || f.Fields[i].vector == nil {
return fmt.Errorf("can not append to uninitalized Field at field index %v", i) return fmt.Errorf("can not append to uninitalized Field at field index %v", i)
} }
if f.Fields[i].Vector == nil { dfPType := f.Fields[i].Type()
return fmt.Errorf("can not append to uninitalized Field Vector at field index %v", i)
}
dfPType := f.Fields[i].Vector.PrimitiveType()
if v == nil { if v == nil {
if !dfPType.Nullable() { if !dfPType.Nullable() {
return fmt.Errorf("can not append nil to non-nullable vector with underlying type %s at field index %v", dfPType, i) return fmt.Errorf("can not append nil to non-nullable vector with underlying type %s at field index %v", dfPType, i)
} }
} }
if v != nil && pTypeFromVal(v) != dfPType { if v != nil && fieldTypeFromVal(v) != dfPType {
return fmt.Errorf("invalid type appending row at index %v, got %T want %v", i, v, dfPType.ItemTypeString()) return fmt.Errorf("invalid type appending row at index %v, got %T want %v", i, v, dfPType.ItemTypeString())
} }
f.Fields[i].Vector.Append(v) f.Fields[i].vector.Append(v)
} }
return nil return nil
} }
// TypeIndices returns a slice of Field index positions for the given pTypes.
func (f *Frame) TypeIndices(pTypes ...FieldType) []int {
indices := []int{}
if f.Fields == nil {
return indices
}
for fieldIdx, f := range f.Fields {
vecType := f.Type()
for _, pType := range pTypes {
if pType == vecType {
indices = append(indices, fieldIdx)
break
}
}
}
return indices
}
// NewField returns a new instance of Field. // NewField returns a new instance of Field.
func NewField(name string, labels Labels, values interface{}) *Field { func NewField(name string, labels Labels, values interface{}) *Field {
var vec Vector var vec vector
switch v := values.(type) { switch v := values.(type) {
case []int8: case []int8:
vec = newVector(v, len(v)) vec = newVector(v, len(v))
...@@ -213,14 +234,66 @@ func NewField(name string, labels Labels, values interface{}) *Field { ...@@ -213,14 +234,66 @@ func NewField(name string, labels Labels, values interface{}) *Field {
return &Field{ return &Field{
Name: name, Name: name,
Vector: vec, vector: vec,
Labels: labels, Labels: labels,
} }
} }
// Len returns the number of elements in the field. // Set sets the Field's value at index idx to val.
// It will panic if idx is out of range.
func (f *Field) Set(idx int, val interface{}) {
f.vector.Set(idx, val)
}
// Append appends element i to the Field.
func (f *Field) Append(i interface{}) {
f.vector.Append(i)
}
// Extend extends the Field length by i.
func (f *Field) Extend(i int) {
f.vector.Extend(i)
}
// At returns the the element at index idx of the Field.
// It will panic if idx is out of range.
func (f *Field) At(idx int) interface{} {
return f.vector.At(idx)
}
// Len returns the number of elements in the Field.
func (f *Field) Len() int { func (f *Field) Len() int {
return f.Vector.Len() return f.vector.Len()
}
// Type returns the underlying primitive type of the Field.
func (f *Field) Type() FieldType {
return f.vector.Type()
}
// PointerAt returns a pointer to the value at idx of the Field.
// It will panic if idx is out of range.
func (f *Field) PointerAt(idx int) interface{} {
return f.vector.PointerAt(idx)
}
// CopyAt returns a copy of the value of the specified index idx.
// It will panic if idx is out of range.
func (f *Field) CopyAt(idx int) interface{} {
return f.vector.CopyAt(idx)
}
// ConcreteAt returns the concrete value at the specified index idx.
// A non-pointer type is returned regardless if the underlying vector is a pointer
// type or not. If the value is a pointer type, and is nil, then the zero value
// is returned and ok will be false.
func (f *Field) ConcreteAt(idx int) (val interface{}, ok bool) {
return f.vector.ConcreteAt(idx)
}
// Nullable returns if the the Field's elements are nullable.
func (f *Field) Nullable() bool {
return f.Type().Nullable()
} }
// SetConfig modifies the Field's Config property to // SetConfig modifies the Field's Config property to
...@@ -303,8 +376,8 @@ func LabelsFromString(s string) (Labels, error) { ...@@ -303,8 +376,8 @@ func LabelsFromString(s string) (Labels, error) {
return labels, nil return labels, nil
} }
// New returns a new instance of a Frame. // NewFrame returns a new instance of a Frame.
func New(name string, fields ...*Field) *Frame { func NewFrame(name string, fields ...*Field) *Frame {
return &Frame{ return &Frame{
Name: name, Name: name,
Fields: fields, Fields: fields,
...@@ -318,3 +391,97 @@ func (f *Frame) Rows() int { ...@@ -318,3 +391,97 @@ func (f *Frame) Rows() int {
} }
return 0 return 0
} }
// At returns the value of the specified fieldIdx and rowIdx.
// It will panic if either the fieldIdx or rowIdx are out of range.
func (f *Frame) At(fieldIdx int, rowIdx int) interface{} {
return f.Fields[fieldIdx].vector.At(rowIdx)
}
// CopyAt returns a copy of the value of the specified fieldIdx and rowIdx.
// It will panic if either the fieldIdx or rowIdx are out of range.
func (f *Frame) CopyAt(fieldIdx int, rowIdx int) interface{} {
return f.Fields[fieldIdx].vector.CopyAt(rowIdx)
}
// Set set the val to the specified fieldIdx and rowIdx.
// It will panic if either the fieldIdx or rowIdx are out of range.
func (f *Frame) Set(fieldIdx int, rowIdx int, val interface{}) {
f.Fields[fieldIdx].vector.Set(rowIdx, val)
}
// Extend extends all the Fields by length by i.
func (f *Frame) Extend(i int) {
for _, f := range f.Fields {
f.vector.Extend(i)
}
}
// ConcreteAt returns the concrete value at the specified fieldIdx and rowIdx.
// A non-pointer type is returned regardless if the underlying type is a pointer
// type or not. If the value is a pointer type, and is nil, then the zero value
// is returned and ok will be false.
func (f *Frame) ConcreteAt(fieldIdx int, rowIdx int) (val interface{}, ok bool) {
return f.Fields[fieldIdx].vector.ConcreteAt(rowIdx)
}
// RowLen returns the the length of the Frame Fields.
// If the Length of all the Fields is not the same then error is returned.
// If the Frame's Fields are nil an error is returned.
func (f *Frame) RowLen() (int, error) {
if f.Fields == nil || len(f.Fields) == 0 {
return 0, fmt.Errorf("frame's fields are nil or of zero length")
}
var l int
for i := 0; i < len(f.Fields); i++ {
if f.Fields[i].vector == nil {
return 0, fmt.Errorf("frame's field at index %v is nil", i)
}
if i == 0 {
l = f.Fields[i].Len()
continue
}
if l != f.Fields[i].Len() {
return 0, fmt.Errorf("frame has different field lengths, field 0 is len %v but field %v is len %v", l, i, f.Fields[i].vector.Len())
}
}
return l, nil
}
// FrameTestCompareOptions returns go-cmp testing options to allow testing of Frame equivelnce.
// The intent is to only use this for testing.
func FrameTestCompareOptions() []cmp.Option {
confFloats := cmp.Comparer(func(x, y *ConfFloat64) bool {
if x == nil && y == nil {
return true
}
if y == nil {
if math.IsNaN(float64(*x)) {
return true
}
if math.IsInf(float64(*x), 1) {
return true
}
if math.IsInf(float64(*x), -1) {
return true
}
}
if x == nil {
if math.IsNaN(float64(*y)) {
return true
}
if math.IsInf(float64(*y), 1) {
return true
}
if math.IsInf(float64(*y), -1) {
return true
}
}
return *x == *y
})
unexportedField := cmp.AllowUnexported(Field{})
return []cmp.Option{confFloats, unexportedField}
}
package dataframe package data
//go:generate genny -in=$GOFILE -out=nullable_vector.gen.go gen "gen=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time" //go:generate genny -in=$GOFILE -out=nullable_vector.gen.go gen "gen=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
...@@ -25,6 +25,26 @@ func (v *nullablegenVector) At(i int) interface{} { ...@@ -25,6 +25,26 @@ func (v *nullablegenVector) At(i int) interface{} {
return (*v)[i] return (*v)[i]
} }
func (v *nullablegenVector) CopyAt(i int) interface{} {
if (*v)[i] == nil {
var g *gen
return g
}
var g gen
g = *(*v)[i]
return &g
}
func (v *nullablegenVector) ConcreteAt(i int) (interface{}, bool) {
var g gen
val := (*v)[i]
if val == nil {
return g, false
}
g = *val
return g, true
}
func (v *nullablegenVector) PointerAt(i int) interface{} { func (v *nullablegenVector) PointerAt(i int) interface{} {
return &(*v)[i] return &(*v)[i]
} }
...@@ -33,8 +53,8 @@ func (v *nullablegenVector) Len() int { ...@@ -33,8 +53,8 @@ func (v *nullablegenVector) Len() int {
return len((*v)) return len((*v))
} }
func (v *nullablegenVector) PrimitiveType() VectorPType { func (v *nullablegenVector) Type() FieldType {
return vectorPType(v) return vectorFieldType(v)
} }
func (v *nullablegenVector) Extend(i int) { func (v *nullablegenVector) Extend(i int) {
......
package dataframe package data
import ( import (
"github.com/cheekybits/genny/generic" "github.com/cheekybits/genny/generic"
...@@ -35,8 +35,18 @@ func (v *genVector) Len() int { ...@@ -35,8 +35,18 @@ func (v *genVector) Len() int {
return len((*v)) return len((*v))
} }
func (v *genVector) PrimitiveType() VectorPType { func (v *genVector) CopyAt(i int) interface{} {
return vectorPType(v) var g gen
g = (*v)[i]
return g
}
func (v *genVector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *genVector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *genVector) Extend(i int) { func (v *genVector) Extend(i int) {
......
package dataframe package data
import ( import (
"database/sql" "database/sql"
...@@ -6,13 +6,13 @@ import ( ...@@ -6,13 +6,13 @@ import (
"reflect" "reflect"
) )
// NewFromSQLRows returns a new dataframe populated with the data from rows. The Field Vector types // NewFromSQLRows returns a new Frame populated with the data from rows. The Field Vector types
// will be Vectors of pointer types, []*T, if the SQL column is nullable or if the nullable property is unknown. // will be Vectors of pointer types, []*T, if the SQL column is nullable or if the nullable property is unknown.
// Otherwise, they will be []T types. // Otherwise, they will be []T types.
// //
// Fields will be named to match name of the SQL columns and the SQL column names must be unique (https://github.com/grafana/grafana-plugin-sdk-go/issues/59). // Fields will be named to match name of the SQL columns and the SQL column names must be unique (https://github.com/grafana/grafana-plugin-sdk-go/issues/59).
// //
// All the types must be supported by the dataframe or a SQLStringConverter will be created and // All the types must be supported by the Frame or a SQLStringConverter will be created and
// the resulting Field Vector type will be of type []*string. // the resulting Field Vector type will be of type []*string.
// //
// The SQLStringConverter's ConversionFunc will be applied to matching rows if it is not nil. // The SQLStringConverter's ConversionFunc will be applied to matching rows if it is not nil.
...@@ -39,11 +39,11 @@ func NewFromSQLRows(rows *sql.Rows, converters ...SQLStringConverter) (*Frame, m ...@@ -39,11 +39,11 @@ func NewFromSQLRows(rows *sql.Rows, converters ...SQLStringConverter) (*Frame, m
} }
vec := frame.Fields[fieldIdx] vec := frame.Fields[fieldIdx]
for i := 0; i < vec.Len(); i++ { for i := 0; i < vec.Len(); i++ {
v, err := mapper.ConversionFunc(vec.Vector.At(i).(*string)) v, err := mapper.ConversionFunc(vec.vector.At(i).(*string))
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
vec.Vector.Set(i, v) vec.vector.Set(i, v)
} }
if mapper.Replacer == nil { if mapper.Replacer == nil {
continue continue
...@@ -100,7 +100,7 @@ func newForSQLRows(rows *sql.Rows, converters ...SQLStringConverter) (*Frame, ma ...@@ -100,7 +100,7 @@ func newForSQLRows(rows *sql.Rows, converters ...SQLStringConverter) (*Frame, ma
// Nullabe types get passed to scan as a pointer to a pointer // Nullabe types get passed to scan as a pointer to a pointer
vec = reflect.MakeSlice(reflect.SliceOf(ptrType), 0, 0).Interface() vec = reflect.MakeSlice(reflect.SliceOf(ptrType), 0, 0).Interface()
} }
if !ValidVectorType(vec) { if !ValidFieldType(vec) {
// Automatically create string mapper if we end up with an unsupported type // Automatically create string mapper if we end up with an unsupported type
mapping[i] = SQLStringConverter{ mapping[i] = SQLStringConverter{
Name: fmt.Sprintf("Autogenerated for column %v", i), Name: fmt.Sprintf("Autogenerated for column %v", i),
...@@ -115,13 +115,13 @@ func newForSQLRows(rows *sql.Rows, converters ...SQLStringConverter) (*Frame, ma ...@@ -115,13 +115,13 @@ func newForSQLRows(rows *sql.Rows, converters ...SQLStringConverter) (*Frame, ma
return frame, mapping, nil return frame, mapping, nil
} }
// newScannableRow adds a row to the dataframe by extending each Field's Vector. It returns // newScannableRow adds a row to the Frame by extending each Field's Vector. It returns
// a slice of references that can be passed to the database/sql rows.Scan() to scan directly into // a slice of references that can be passed to the database/sql rows.Scan() to scan directly into
// the extended Vectors of the dataframe. // the extended Vectors of the data.
func (f *Frame) newScannableRow() []interface{} { func (f *Frame) newScannableRow() []interface{} {
row := make([]interface{}, len(f.Fields)) row := make([]interface{}, len(f.Fields))
for i, field := range f.Fields { for i, field := range f.Fields {
vec := field.Vector vec := field.vector
vec.Extend(1) vec.Extend(1)
// non-nullable fields will be *T, and nullable fields will be **T // non-nullable fields will be *T, and nullable fields will be **T
vecItemPointer := vec.PointerAt(vec.Len() - 1) vecItemPointer := vec.PointerAt(vec.Len() - 1)
...@@ -131,7 +131,7 @@ func (f *Frame) newScannableRow() []interface{} { ...@@ -131,7 +131,7 @@ func (f *Frame) newScannableRow() []interface{} {
} }
// SQLStringConverter can be used to store types not supported by // SQLStringConverter can be used to store types not supported by
// a dataframe into a *string. When scanning, if a SQL's row's InputScanType's Kind // a Frame into a *string. When scanning, if a SQL's row's InputScanType's Kind
// and InputScanKind match that returned by the sql response, then the // and InputScanKind match that returned by the sql response, then the
// conversion func will be run on the row. // conversion func will be run on the row.
type SQLStringConverter struct { type SQLStringConverter struct {
...@@ -150,7 +150,7 @@ type SQLStringConverter struct { ...@@ -150,7 +150,7 @@ type SQLStringConverter struct {
// Note: SQLStringConverter is perhaps better understood as []byte. However, currently // Note: SQLStringConverter is perhaps better understood as []byte. However, currently
// the Vector type ([][]byte) is not supported. https://github.com/grafana/grafana-plugin-sdk-go/issues/57 // the Vector type ([][]byte) is not supported. https://github.com/grafana/grafana-plugin-sdk-go/issues/57
// StringFieldReplacer is used to replace a *string Field in a dataframe. The type // StringFieldReplacer is used to replace a *string Field in a data. The type
// returned by the ReplaceFunc must match the type of elements of VectorType. // returned by the ReplaceFunc must match the type of elements of VectorType.
// Both properties must be non-nil. // Both properties must be non-nil.
type StringFieldReplacer struct { type StringFieldReplacer struct {
...@@ -165,22 +165,22 @@ func Replace(frame *Frame, fieldIdx int, replacer *StringFieldReplacer) error { ...@@ -165,22 +165,22 @@ func Replace(frame *Frame, fieldIdx int, replacer *StringFieldReplacer) error {
return fmt.Errorf("fieldIdx is out of bounds, field len: %v", len(frame.Fields)) return fmt.Errorf("fieldIdx is out of bounds, field len: %v", len(frame.Fields))
} }
field := frame.Fields[fieldIdx] field := frame.Fields[fieldIdx]
if field.Vector.PrimitiveType() != VectorPTypeNullableString { if field.Type() != FieldTypeNullableString {
return fmt.Errorf("can only replace []*string vectors, vector is of type %s", field.Vector.PrimitiveType()) return fmt.Errorf("can only replace []*string vectors, vector is of type %s", field.Type())
} }
if !ValidVectorType(replacer.VectorType) { if !ValidFieldType(replacer.VectorType) {
return fmt.Errorf("can not replace column with unsupported type %T", replacer.VectorType) return fmt.Errorf("can not replace column with unsupported type %T", replacer.VectorType)
} }
newVector := newVector(replacer.VectorType, field.Vector.Len()) newVector := newVector(replacer.VectorType, field.vector.Len())
for i := 0; i < newVector.Len(); i++ { for i := 0; i < newVector.Len(); i++ {
oldVal := field.Vector.At(i).(*string) // Vector type is checked earlier above oldVal := field.vector.At(i).(*string) // Vector type is checked earlier above
newVal, err := replacer.ReplaceFunc(oldVal) newVal, err := replacer.ReplaceFunc(oldVal)
if err != nil { if err != nil {
return err return err
} }
newVector.Set(i, newVal) newVector.Set(i, newVal)
} }
field.Vector = newVector field.vector = newVector
return nil return nil
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Any changes will be lost if this file is regenerated. // Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny // see https://github.com/cheekybits/genny
package dataframe package data
import "time" import "time"
...@@ -35,8 +35,18 @@ func (v *uint8Vector) Len() int { ...@@ -35,8 +35,18 @@ func (v *uint8Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *uint8Vector) PrimitiveType() VectorPType { func (v *uint8Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g uint8
g = (*v)[i]
return g
}
func (v *uint8Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *uint8Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *uint8Vector) Extend(i int) { func (v *uint8Vector) Extend(i int) {
...@@ -72,8 +82,18 @@ func (v *uint16Vector) Len() int { ...@@ -72,8 +82,18 @@ func (v *uint16Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *uint16Vector) PrimitiveType() VectorPType { func (v *uint16Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g uint16
g = (*v)[i]
return g
}
func (v *uint16Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *uint16Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *uint16Vector) Extend(i int) { func (v *uint16Vector) Extend(i int) {
...@@ -109,8 +129,18 @@ func (v *uint32Vector) Len() int { ...@@ -109,8 +129,18 @@ func (v *uint32Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *uint32Vector) PrimitiveType() VectorPType { func (v *uint32Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g uint32
g = (*v)[i]
return g
}
func (v *uint32Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *uint32Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *uint32Vector) Extend(i int) { func (v *uint32Vector) Extend(i int) {
...@@ -146,8 +176,18 @@ func (v *uint64Vector) Len() int { ...@@ -146,8 +176,18 @@ func (v *uint64Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *uint64Vector) PrimitiveType() VectorPType { func (v *uint64Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g uint64
g = (*v)[i]
return g
}
func (v *uint64Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *uint64Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *uint64Vector) Extend(i int) { func (v *uint64Vector) Extend(i int) {
...@@ -183,8 +223,18 @@ func (v *int8Vector) Len() int { ...@@ -183,8 +223,18 @@ func (v *int8Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *int8Vector) PrimitiveType() VectorPType { func (v *int8Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g int8
g = (*v)[i]
return g
}
func (v *int8Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *int8Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *int8Vector) Extend(i int) { func (v *int8Vector) Extend(i int) {
...@@ -220,8 +270,18 @@ func (v *int16Vector) Len() int { ...@@ -220,8 +270,18 @@ func (v *int16Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *int16Vector) PrimitiveType() VectorPType { func (v *int16Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g int16
g = (*v)[i]
return g
}
func (v *int16Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *int16Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *int16Vector) Extend(i int) { func (v *int16Vector) Extend(i int) {
...@@ -257,8 +317,18 @@ func (v *int32Vector) Len() int { ...@@ -257,8 +317,18 @@ func (v *int32Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *int32Vector) PrimitiveType() VectorPType { func (v *int32Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g int32
g = (*v)[i]
return g
}
func (v *int32Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *int32Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *int32Vector) Extend(i int) { func (v *int32Vector) Extend(i int) {
...@@ -294,8 +364,18 @@ func (v *int64Vector) Len() int { ...@@ -294,8 +364,18 @@ func (v *int64Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *int64Vector) PrimitiveType() VectorPType { func (v *int64Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g int64
g = (*v)[i]
return g
}
func (v *int64Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *int64Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *int64Vector) Extend(i int) { func (v *int64Vector) Extend(i int) {
...@@ -331,8 +411,18 @@ func (v *float32Vector) Len() int { ...@@ -331,8 +411,18 @@ func (v *float32Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *float32Vector) PrimitiveType() VectorPType { func (v *float32Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g float32
g = (*v)[i]
return g
}
func (v *float32Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *float32Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *float32Vector) Extend(i int) { func (v *float32Vector) Extend(i int) {
...@@ -368,8 +458,18 @@ func (v *float64Vector) Len() int { ...@@ -368,8 +458,18 @@ func (v *float64Vector) Len() int {
return len((*v)) return len((*v))
} }
func (v *float64Vector) PrimitiveType() VectorPType { func (v *float64Vector) CopyAt(i int) interface{} {
return vectorPType(v) var g float64
g = (*v)[i]
return g
}
func (v *float64Vector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *float64Vector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *float64Vector) Extend(i int) { func (v *float64Vector) Extend(i int) {
...@@ -405,8 +505,18 @@ func (v *stringVector) Len() int { ...@@ -405,8 +505,18 @@ func (v *stringVector) Len() int {
return len((*v)) return len((*v))
} }
func (v *stringVector) PrimitiveType() VectorPType { func (v *stringVector) CopyAt(i int) interface{} {
return vectorPType(v) var g string
g = (*v)[i]
return g
}
func (v *stringVector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *stringVector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *stringVector) Extend(i int) { func (v *stringVector) Extend(i int) {
...@@ -442,8 +552,18 @@ func (v *boolVector) Len() int { ...@@ -442,8 +552,18 @@ func (v *boolVector) Len() int {
return len((*v)) return len((*v))
} }
func (v *boolVector) PrimitiveType() VectorPType { func (v *boolVector) CopyAt(i int) interface{} {
return vectorPType(v) var g bool
g = (*v)[i]
return g
}
func (v *boolVector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *boolVector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *boolVector) Extend(i int) { func (v *boolVector) Extend(i int) {
...@@ -479,8 +599,18 @@ func (v *timeTimeVector) Len() int { ...@@ -479,8 +599,18 @@ func (v *timeTimeVector) Len() int {
return len((*v)) return len((*v))
} }
func (v *timeTimeVector) PrimitiveType() VectorPType { func (v *timeTimeVector) CopyAt(i int) interface{} {
return vectorPType(v) var g time.Time
g = (*v)[i]
return g
}
func (v *timeTimeVector) ConcreteAt(i int) (interface{}, bool) {
return v.At(i), true
}
func (v *timeTimeVector) Type() FieldType {
return vectorFieldType(v)
} }
func (v *timeTimeVector) Extend(i int) { func (v *timeTimeVector) Extend(i int) {
......
...@@ -147,9 +147,9 @@ github.com/gosimple/slug ...@@ -147,9 +147,9 @@ github.com/gosimple/slug
# github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 # github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4
github.com/grafana/grafana-plugin-model/go/datasource github.com/grafana/grafana-plugin-model/go/datasource
github.com/grafana/grafana-plugin-model/go/renderer github.com/grafana/grafana-plugin-model/go/renderer
# github.com/grafana/grafana-plugin-sdk-go v0.21.0 # github.com/grafana/grafana-plugin-sdk-go v0.24.0
github.com/grafana/grafana-plugin-sdk-go/backend/plugin github.com/grafana/grafana-plugin-sdk-go/backend/plugin
github.com/grafana/grafana-plugin-sdk-go/dataframe github.com/grafana/grafana-plugin-sdk-go/data
github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2 github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2
# github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd # github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd
github.com/hashicorp/go-hclog github.com/hashicorp/go-hclog
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment