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 }
Output:
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 }, }, } }
Output:
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.