Documentation
¶
Overview ¶
Package sqlutil provides helpers for scanning database/sql responses into a data.Frame.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FrameFromRows ¶
func FrameFromRows(rows *sql.Rows, converters ...StringConverter) (*data.Frame, map[int]StringConverter, error)
FrameFromRows 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 StringConverter will be created and the resulting Field Vector type will be of type []*string.
The StringConverter's ConversionFunc will be applied to matching rows if it is not nil. Additionally, if the StringConverter's Replacer is not nil, the replacement will be performed. A map of Field/Column index to the corresponding StringConverter is returned so what conversions were done can be inspected.
Example ¶
package main
import (
"database/sql"
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
)
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 := sqlutil.FrameFromRows(rows)
if err != nil {
// return err
}
_, _ = frame, mappings
}
func Replace ¶
func Replace(frame *data.Frame, fieldIdx int, replacer *StringFieldReplacer) error
Replace will replace a *string Vector of the specified Field's index using the StringFieldReplacer.
Example ¶
package main
import (
"fmt"
"strconv"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
)
func main() {
i := 0
getString := func() *string {
i++
s := strconv.Itoa(i)
return &s
}
frame := data.NewFrame("Before",
data.NewField("string", nil, []*string{getString(), getString()}))
fmt.Println(frame.String()) // Before
intReplacer := &sqlutil.StringFieldReplacer{
OutputFieldType: data.FieldTypeNullableInt64,
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
},
}
err := sqlutil.Replace(frame, 0, intReplacer)
if err != nil {
// return err
}
frame.Name = "After"
fmt.Println(frame.String()) // After
}
Output: Name: Before Dimensions: 1 Fields by 2 Rows +-----------------+ | Name: string | | Labels: | | Type: []*string | +-----------------+ | 1 | | 2 | +-----------------+ Name: After Dimensions: 1 Fields by 2 Rows +----------------+ | Name: string | | Labels: | | Type: []*int64 | +----------------+ | 1 | | 2 | +----------------+
Types ¶
type StringConverter ¶
type StringConverter 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
}
StringConverter 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/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
)
func main() {
_ = sqlutil.StringConverter{
Name: "BIGINT to *int64",
InputScanKind: reflect.Struct,
InputTypeName: "BIGINT",
Replacer: &sqlutil.StringFieldReplacer{
OutputFieldType: data.FieldTypeNullableInt64,
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
},
},
}
}
type StringFieldReplacer ¶
type StringFieldReplacer struct {
OutputFieldType data.FieldType
ReplaceFunc func(in *string) (interface{}, error)
}
StringFieldReplacer is used to replace a *string Field in a Frame. The type returned by the ReplaceFunc must match the type of elements of VectorType. Both properties must be non-nil.