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, rowLimit int64, converters ...StringConverter) (*data.Frame, map[int]StringConverter, error)
FrameFromRows returns a new Frame populated with the data from rows. The field types will be nullable ([]*T) if the SQL column is nullable or if the nullable property is unknown. Otherwise, the field types will be non-nullable ([]T) types.
The number of rows scanned is limited to rowLimit. If maxRows is reached, then a data.Notice with a warning severity will be attached to the frame. If rowLimit is less than 0, there is no limit.
Fields will be named to match name of the SQL columns.
All the types must be supported by the Frame or a StringConverter will be created and the resulting FieldType type will be FieldTypeNullableString ([]*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, 1000) 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()})) st, _ := frame.StringTable(-1, -1) fmt.Println(st) 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" st, _ = frame.StringTable(-1, -1) fmt.Println(st) // 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.