data

package
v0.30.1-0...-025f12f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2020 License: Apache-2.0 Imports: 18 Imported by: 0

README

data

Testing

This package uses golden files to verify Arrow serialization.

Add the update flag to go test to update the golden files:

go test -update

Make sure you check in any updated golden files.

Documentation

Overview

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.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func FrameTestCompareOptions

func FrameTestCompareOptions() []cmp.Option

FrameTestCompareOptions returns go-cmp testing options to allow testing of Frame equivelnce. The intent is to only use this for testing.

func MarshalArrow

func MarshalArrow(f *Frame) ([]byte, error)

MarshalArrow converts the Frame to an arrow table and returns a byte representation of that table.

func Replace

func Replace(frame *Frame, fieldIdx int, replacer *StringFieldReplacer) error

Replace will replace a *string Vector of the specified Field's index using the StringFieldReplacer.

func ValidFieldType

func ValidFieldType(t interface{}) bool

ValidFieldType returns if a primitive slice is a valid supported Field type.

Types

type ConfFloat64

type ConfFloat64 float64

ConfFloat64 is a float64. It Marshals float64 values of NaN of Inf to null.

func (*ConfFloat64) MarshalJSON

func (sf *ConfFloat64) MarshalJSON() ([]byte, error)

func (*ConfFloat64) UnmarshalJSON

func (sf *ConfFloat64) UnmarshalJSON(data []byte) error
type DataLink struct {
	Title       string `json:"title,omitempty"`
	TargetBlank bool   `json:"targetBlank,omitempty"`
	URL         string `json:"url,omitempty"`
}

DataLink define what

type Field

type Field struct {
	Name   string
	Config *FieldConfig

	Labels Labels
	// contains filtered or unexported fields
}

Field represents a column of data with a specific type.

func NewField

func NewField(name string, labels Labels, values interface{}) *Field

NewField returns a new instance of Field.

func NewFieldFromFieldType

func NewFieldFromFieldType(p FieldType, n int) *Field

NewFieldFromFieldType creates a new Field of the given pType of length n.

func (*Field) Append

func (f *Field) Append(i interface{})

Append appends element i to the Field.

func (*Field) At

func (f *Field) At(idx int) interface{}

At returns the the element at index idx of the Field. It will panic if idx is out of range.

func (*Field) ConcreteAt

func (f *Field) ConcreteAt(idx int) (val interface{}, ok bool)

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 (*Field) CopyAt

func (f *Field) CopyAt(idx int) interface{}

CopyAt returns a copy of the value of the specified index idx. It will panic if idx is out of range.

func (*Field) Extend

func (f *Field) Extend(i int)

Extend extends the Field length by i.

func (*Field) Len

func (f *Field) Len() int

Len returns the number of elements in the Field.

func (*Field) Nullable

func (f *Field) Nullable() bool

Nullable returns if the the Field's elements are nullable.

func (*Field) PointerAt

func (f *Field) PointerAt(idx int) interface{}

PointerAt returns a pointer to the value at idx of the Field. It will panic if idx is out of range.

func (*Field) Set

func (f *Field) Set(idx int, val interface{})

Set sets the Field's value at index idx to val. It will panic if idx is out of range.

func (*Field) SetConfig

func (f *Field) SetConfig(conf *FieldConfig) *Field

SetConfig modifies the Field's Config property to be set to conf and returns the Field.

func (*Field) Type

func (f *Field) Type() FieldType

Type returns the underlying primitive type of the Field.

type FieldConfig

type FieldConfig struct {
	Title      string `json:"title,omitempty"`
	Filterable *bool  `json:"filterable,omitempty"` // indicates if the Field's data can be filtered by additional calls.

	// Numeric Options
	Unit     string       `json:"unit,omitempty"`     // is the string to display to represent the Field's unit, such as "Requests/sec"
	Decimals *uint16      `json:"decimals,omitempty"` // is the number of decimal places to display
	Min      *ConfFloat64 `json:"min,omitempty"`      // is the maximum value of fields in the column. When present the frontend can skip the calculation.
	Max      *ConfFloat64 `json:"max,omitempty"`      // see Min

	// Convert input values into a display string
	Mappings []ValueMapping `json:"mappings,omitempty"`

	// Map numeric values to states
	Thresholds *ThresholdsConfig `json:"thresholds,omitempty"`

	// Map values to a display color
	// NOTE: this interface is under development in the frontend... so simple map for now
	Color map[string]interface{} `json:"color,omitempty"`

	// Used when reducing field values
	NullValueMode NullValueMode `json:"nullValueMode,omitempty"`

	// The behavior when clicking on a result
	Links []DataLink `json:"links,omitempty"`

	// Alternative to empty string
	NoValue string `json:"noValue,omitempty"`

	// Panel Specific Values
	Custom map[string]interface{} `json:"custom,omitempty"`
}

FieldConfig represents the display properties for a Field.

func (*FieldConfig) SetDecimals

func (fc *FieldConfig) SetDecimals(v uint16) *FieldConfig

SetDecimals modifies the FieldConfig's Decimals property to be set to v and returns the FieldConfig. It is a convenance function since the Decimals property is a pointer.

func (*FieldConfig) SetFilterable

func (fc *FieldConfig) SetFilterable(b bool) *FieldConfig

SetFilterable modifies the FieldConfig's Filterable property to be set to b and returns the FieldConfig. It is a convenance function since the Filterable property is a pointer.

func (*FieldConfig) SetMax

func (fc *FieldConfig) SetMax(v float64) *FieldConfig

SetMax modifies the FieldConfig's Max property to be set to v and returns the FieldConfig. It is a convenance function since the Min property is a pointer.

func (*FieldConfig) SetMin

func (fc *FieldConfig) SetMin(v float64) *FieldConfig

SetMin modifies the FieldConfig's Min property to be set to v and returns the FieldConfig. It is a convenance function since the Min property is a pointer.

type FieldType

type FieldType int

FieldType indicates the Go type underlying the Field.

const (
	// FieldTypeInt8 indicates the underlying primitive is a []int8.
	FieldTypeInt8 FieldType = iota
	// FieldTypeNullableInt8 indicates the underlying primitive is a []*int8.
	FieldTypeNullableInt8

	// FieldTypeInt16 indicates the underlying primitive is a []Int16.
	FieldTypeInt16
	// FieldTypeNullableInt16 indicates the underlying primitive is a []*Int16.
	FieldTypeNullableInt16

	// FieldTypeInt32 indicates the underlying primitive is a []int32.
	FieldTypeInt32
	// FieldTypeNullableInt32 indicates the underlying primitive is a []*int32.
	FieldTypeNullableInt32

	// FieldTypeInt64 indicates the underlying primitive is a []int64.
	FieldTypeInt64
	// FieldTypeNullableInt64 indicates the underlying primitive is a []*int64.
	FieldTypeNullableInt64

	// FieldTypeUint8 indicates the underlying primitive is a []int8.
	FieldTypeUint8
	// FieldTypeNullableUint8 indicates the underlying primitive is a []*int8.
	FieldTypeNullableUint8

	// FieldTypeUint16 indicates the underlying primitive is a []uint16.
	FieldTypeUint16
	// FieldTypeNullableUint16 indicates the underlying primitive is a []*uint16.
	FieldTypeNullableUint16

	// FieldTypeUint32 indicates the underlying primitive is a []uint32.
	FieldTypeUint32
	// FieldTypeNullableUint32 indicates the underlying primitive is a []*uint32.
	FieldTypeNullableUint32

	// FieldTypeUint64 indicates the underlying primitive is a []uint64.
	FieldTypeUint64
	// FieldTypeNullableUint64 indicates the underlying primitive is a []*uint64.
	FieldTypeNullableUint64

	// FieldTypeFloat32 indicates the underlying primitive is a []float32.
	FieldTypeFloat32
	// FieldTypeNullableFloat32 indicates the underlying primitive is a []*float32.
	FieldTypeNullableFloat32

	// FieldTypeFloat64 indicates the underlying primitive is a []float64.
	FieldTypeFloat64
	// FieldTypeNullableFloat64 indicates the underlying primitive is a []*float64.
	FieldTypeNullableFloat64

	// FieldTypeString indicates the underlying primitive is a []string.
	FieldTypeString
	// FieldTypeNullableString indicates the underlying primitive is a []*string.
	FieldTypeNullableString

	// FieldTypeBool indicates the underlying primitive is a []bool.
	FieldTypeBool
	// FieldTypeNullableBool indicates the underlying primitive is a []*bool.
	FieldTypeNullableBool

	// FieldTypeTime indicates the underlying primitive is a []time.Time.
	FieldTypeTime
	// FieldTypeNullableTime indicates the underlying primitive is a []*time.Time.
	FieldTypeNullableTime
)

func NumericFieldTypes

func NumericFieldTypes() []FieldType

NumericFieldTypes returns a slice of FieldTypes that are numeric.

func (FieldType) ItemTypeString

func (p FieldType) ItemTypeString() string

ItemTypeString returns the string representation of the type of element within in the vector

func (FieldType) Nullable

func (p FieldType) Nullable() bool

Nullable returns if Field type is a nullable type

func (FieldType) String

func (p FieldType) String() string

type Fields

type Fields []*Field

Fields is a slice of Field pointers.

type Frame

type Frame struct {
	// Name is used in some Grafana visualizations.
	Name string

	// Fields are the columns of a frame.
	// All Fields must be of the same the length when marshalling the Frame for transmission.
	Fields []*Field

	// RefID is a property that can be set to match a Frame to its orginating query.
	RefID    string
	Meta     *QueryResultMeta
	Warnings []Warning
}

Frame represents a columnar storage with optional labels.

func LongToWide

func LongToWide(longFrame *Frame) (*Frame, error)

LongToWide converts a Long formated time series Frame to a Wide format (see TimeSeriesType for descriptions). The first Field of type time.Time or *time.Time will be the time index for the series, and will be the first field of the outputted longFrame.

During conversion: String Fields in the longFrame become Labels on the Fields of wideFrame. The name of each string Field becomes a label key, and the values of that Field become label values. Each unique combination of value Fields and set of Label key/values become a Field of longFrame.

Additionally, if the time index is a *time.Time field, it will become time.Time Field. If a *string Field has nil values, they are equivalent to "" when converted into labels.

An error is returned if any of the following are true: The input frame is not a long formated time series frame. The input frame's Fields are of length 0. The time index is not sorted ascending by time. The time index has null values.

With a conversion of Long to Wide, and then back to Long via WideToLong(), the outputted Long Frame may not match the original inputted Long frame.

func NewFrame

func NewFrame(name string, fields ...*Field) *Frame

NewFrame returns a new instance of a Frame.

func NewFromSQLRows

func NewFromSQLRows(rows *sql.Rows, converters ...SQLStringConverter) (*Frame, map[int]SQLStringConverter, error)

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. 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).

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 SQLStringConverter's ConversionFunc will be applied to matching rows if it is not nil. Additionally, if the SQLStringConverter's Replacer is not nil, the replacement will be performed. A map of Field/Column index to the corresponding SQLStringConverter is returned so what conversions were done can be inspected.

Example
package main

import (
	"database/sql"

	"github.com/fbarcena/grafana-plugin-sdk-go/data"
)

func main() {
	aQuery := "SELECT * FROM GoodData"
	db, err := sql.Open("fancySql", "fancysql://user:pass@localhost:1433")
	if err != nil {
		// return err
	}

	defer db.Close()

	rows, err := db.Query(aQuery)
	if err != nil {
		// return err
	}
	defer rows.Close()

	frame, mappings, err := data.NewFromSQLRows(rows)
	if err != nil {
		// return err
	}
	_, _ = frame, mappings
}
Output:

func UnmarshalArrow

func UnmarshalArrow(b []byte) (*Frame, error)

UnmarshalArrow converts a byte representation of an arrow table to a Frame

func WideToLong

func WideToLong(wideFrame *Frame) (*Frame, error)

WideToLong converts a Wide formated time series Frame to a Long formated time series Frame (see TimeSeriesType for descriptions). The first Field of type time.Time or *time.Time in wideFrame will be the time index for the series, and will be the first field of the outputted wideFrame.

During conversion: All the unique keys in all of the Labels across the Fields of wideFrame become string Fields with the corresponding name in longFrame. The corresponding Labels values become values in those Fields of longFrame. For each unique non-timeIndex Field across the Fields of wideFrame (value fields), a Field of the same type is created in longFrame. For each unique set of Labels across the Fields of wideFrame, a row is added to longFrame, and then for each unique value Field, the corresponding value Field of longFrame is set.

An error is returned if any of the following are true: The input frame is not a wide formated time series frame. The input row has no rows. The time index not sorted ascending by time. The time index has null values. Two numeric Fields have the same name but different types.

With a conversion of Wide to Long, and then back to Wide via LongToWide(), the outputted Wide Frame may not match the original inputted Wide frame.

func (*Frame) AppendRow

func (f *Frame) AppendRow(vals ...interface{})

AppendRow adds a new row to the Frame by appending to each element of vals to the corresponding Field in the data. 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 to the Field type or AppendRow will panic.

func (*Frame) AppendRowSafe

func (f *Frame) AppendRowSafe(vals ...interface{}) error

AppendRowSafe adds a new row to the Frame by appending to each each element of vals to the corresponding Field in the data. It has the some constraints as AppendRow but will return an error under those conditions instead of panicing.

func (*Frame) AppendWarning

func (f *Frame) AppendWarning(message string, details string)

AppendWarning adds warnings to the data frame.

func (*Frame) At

func (f *Frame) At(fieldIdx int, rowIdx int) interface{}

At returns the value of the specified fieldIdx and rowIdx. It will panic if either the fieldIdx or rowIdx are out of range.

func (*Frame) ConcreteAt

func (f *Frame) ConcreteAt(fieldIdx int, rowIdx int) (val interface{}, ok bool)

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 (*Frame) CopyAt

func (f *Frame) CopyAt(fieldIdx int, rowIdx int) interface{}

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 (*Frame) EmptyCopy

func (f *Frame) EmptyCopy() *Frame

EmptyCopy returns a copy of Frame f but with Fields of zero length, and no copy of the FieldConfigs, Metadata, or Warnings.

func (*Frame) Extend

func (f *Frame) Extend(i int)

Extend extends all the Fields by length by i.

func (*Frame) FilterRowsByField

func (f *Frame) FilterRowsByField(fieldIdx int, filter func(i interface{}) (bool, error)) (*Frame, error)

FilterRowsByField returns a copy of frame f (as per EmptyCopy()) that includes rows where the filter returns true and no error. If filter returns an error, then an error is returned.

func (*Frame) RowCopy

func (f *Frame) RowCopy(rowIdx int) []interface{}

RowCopy returns an interface slice that contains the values of each Field for the given rowIdx.

func (*Frame) RowLen

func (f *Frame) RowLen() (int, error)

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 (*Frame) Rows

func (f *Frame) Rows() int

Rows returns the number of rows in the frame.

func (*Frame) Set

func (f *Frame) Set(fieldIdx int, rowIdx int, val interface{})

Set set the val to the specified fieldIdx and rowIdx. It will panic if either the fieldIdx or rowIdx are out of range.

func (*Frame) TimeSeriesSchema

func (f *Frame) TimeSeriesSchema() (tsSchema TimeSeriesSchema)

TimeSeriesSchema returns the TimeSeriesSchema of the frame. The TimeSeriesSchema's Type value will be TimeSeriesNot if it is not a time series.

func (*Frame) TypeIndices

func (f *Frame) TypeIndices(pTypes ...FieldType) []int

TypeIndices returns a slice of Field index positions for the given pTypes.

type Frames

type Frames []*Frame

Frames is a slice of Frame pointers. It is the main data container within a backend.DataResponse.

type Labels

type Labels map[string]string

Labels are used to add metadata to an object.

func LabelsFromString

func LabelsFromString(s string) (Labels, error)

LabelsFromString parses the output of Labels.String() into a Labels object. It probably has some flaws.

func (Labels) Contains

func (l Labels) Contains(arg Labels) bool

Contains returns true if all k=v pairs of the argument are in the receiver.

func (Labels) Copy

func (l Labels) Copy() Labels

Copy returns a copy of the labels.

func (Labels) Equals

func (l Labels) Equals(arg Labels) bool

Equals returns true if the argument has the same k=v pairs as the receiver.

func (Labels) String

func (l Labels) String() string

type MappingType

type MappingType int8

MappingType value or range

const (
	// ValueToText map a value to text
	ValueToText MappingType = iota + 1

	// RangeToText map a range to text
	RangeToText
)

type NullValueMode

type NullValueMode string

NullValueMode say how the UI should show null values

const (
	// NullValueModeNull displays null values
	NullValueModeNull NullValueMode = "null"
	// NullValueModeIgnore sets the display to ignore null values
	NullValueModeIgnore NullValueMode = "connected"
	// NullValueModeAsZero set the display show null values as zero
	NullValueModeAsZero NullValueMode = "null as zero"
)

type QueryResultMeta

type QueryResultMeta struct {
	// Used in Explore for highlighting
	SearchWords []string `json:"searchWords,omitempty"`

	// Used in Explore to show limit applied to search result
	Limit int64 `json:"limit,omitempty"`

	// Datasource specific values
	Custom map[string]interface{} `json:"custom,omitempty"`
}

QueryResultMeta matches: https://github.com/grafana/grafana/blob/master/packages/grafana-data/src/types/data.ts#L11 NOTE -- in javascript this can accept any `[key: string]: any;` however this interface only exposes the values we want to be exposed

func QueryResultMetaFromJSON

func QueryResultMetaFromJSON(jsonStr string) (*QueryResultMeta, error)

QueryResultMetaFromJSON creates a QueryResultMeta from a json string

type SQLStringConverter

type SQLStringConverter struct {
	// Name is an optional property that can be used to identify a converter
	Name          string
	InputScanKind reflect.Kind // reflect.Type might better or worse option?
	InputTypeName string

	// Conversion func may be nil to do no additional operations on the string conversion.
	ConversionFunc func(in *string) (*string, error)

	// If the Replacer is not nil, the replacement will be performed.
	Replacer *StringFieldReplacer
}

SQLStringConverter can be used to store types not supported by 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 conversion func will be run on the row.

Example
package main

import (
	"reflect"
	"strconv"

	"github.com/fbarcena/grafana-plugin-sdk-go/data"
)

func main() {
	_ = data.SQLStringConverter{
		Name:          "BIGINT to *int64",
		InputScanKind: reflect.Struct,
		InputTypeName: "BIGINT",
		Replacer: &data.StringFieldReplacer{
			VectorType: []*int64{},
			ReplaceFunc: func(in *string) (interface{}, error) {
				if in == nil {
					return nil, nil
				}
				v, err := strconv.ParseInt(*in, 10, 64)
				if err != nil {
					return nil, err
				}
				return &v, nil
			},
		},
	}
}
Output:

type StringFieldReplacer

type StringFieldReplacer struct {
	VectorType  interface{}
	ReplaceFunc func(in *string) (interface{}, error)
}

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. Both properties must be non-nil.

Example
package main

import (
	"strconv"

	"github.com/fbarcena/grafana-plugin-sdk-go/data"
)

func main() {
	_ = &data.StringFieldReplacer{
		VectorType: []*int64{},
		ReplaceFunc: func(in *string) (interface{}, error) {
			if in == nil {
				return nil, nil
			}
			v, err := strconv.ParseInt(*in, 10, 64)
			if err != nil {
				return nil, err
			}
			return &v, nil
		},
	}
}
Output:

type Threshold

type Threshold struct {
	Value ConfFloat64 `json:"value,omitempty"` // First value is always -Infinity serialize to null
	Color string      `json:"color,omitempty"`
	State string      `json:"state,omitempty"`
}

Threshold a single step on the threshold list

func NewThreshold

func NewThreshold(value float64, color, state string) Threshold

NewThreshold Creates a new Threshold object

type ThresholdsConfig

type ThresholdsConfig struct {
	Mode ThresholdsMode `json:"mode"`

	// Must be sorted by 'value', first value is always -Infinity
	Steps []Threshold `json:"steps"`
}

ThresholdsConfig setup thresholds

type ThresholdsMode

type ThresholdsMode string

ThresholdsMode absolute or percentage

const (
	// ThresholdsModeAbsolute pick thresholds based on absolute value
	ThresholdsModeAbsolute ThresholdsMode = "absolute"

	// ThresholdsModePercentage the threshold is relative to min/max
	ThresholdsModePercentage ThresholdsMode = "percentage"
)

type TimeSeriesSchema

type TimeSeriesSchema struct {
	Type           TimeSeriesType // the type of series, as determinted by frame.TimeSeriesSchema()
	TimeIndex      int            // Field index of the time series index
	TimeIsNullable bool           // true if the time index is nullable (of *time.Time)
	ValueIndices   []int          // Field indices of value columns (All fields excluding string fields and the time index)
	FactorIndices  []int          // Field indices of string or *string Fields
}

TimeSeriesSchema is information about a Frame's schema. It is populated from the Frame's TimeSeriesSchema() method.

type TimeSeriesType

type TimeSeriesType int

TimeSeriesType represents the type of time series the schema can be treated as (if any).

const (
	// TimeSeriesTypeNot means this Frame is not a valid time series. This means it lacks at least
	// one of a time Field and another (value) Field.
	TimeSeriesTypeNot TimeSeriesType = iota

	// TimeSeriesTypeLong means this Frame can be treated as a "Long" time series.
	//
	// A Long series has one or more string Fields, disregards Labels on Fields, and generally
	// repeated time values in the time index.
	TimeSeriesTypeLong

	// TimeSeriesTypeWide means this Frame can be treated as a "Wide" time series.
	//
	// A Wide series has no string fields, should not have repeated time values, and generally
	// uses labels.
	TimeSeriesTypeWide
)

TODO: Create and link to Grafana documentation on Long vs Wide

func (TimeSeriesType) String

func (t TimeSeriesType) String() string

type ValueMapping

type ValueMapping struct {
	ID       int16       `json:"id"`
	Operator string      `json:"operator"`
	Text     string      `json:"title"`
	Type     MappingType `json:"type"`

	// Only valid for MappingType == ValueMap
	Value string `json:"value,omitempty"`

	// Only valid for MappingType == RangeMap
	From string `json:"from,omitempty"`
	To   string `json:"to,omitempty"`
}

ValueMapping convert input value to something else

type Warning

type Warning struct {
	// Short message (typically shown in the header)
	Message string `json:"message,omitempty"`

	// longer error message, shown in the body
	Details string `json:"details,omitempty"`
}

Warning contains information about problems in a data.

func WarningsFromJSON

func WarningsFromJSON(jsonStr string) ([]Warning, error)

WarningsFromJSON creates a *Warning from a json string.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL