Documentation ¶
Index ¶
- Variables
- func Append(frame *data.Frame, row []interface{}, converters ...Converter) error
- func DefaultConverterFunc(t reflect.Type) func(in interface{}) (interface{}, error)
- func FrameFromRows(rows *sql.Rows, rowLimit int64, converters ...Converter) (*data.Frame, error)
- func MakeScanRow(colTypes []*sql.ColumnType, colNames []string, converters ...Converter) (*ScanRow, []Converter, error)
- func NewFrame(columns []string, converters ...Converter) *data.Frame
- type Converter
- type FrameConverter
- type ScanRow
- type StringConverter
- type StringFieldReplacer
Constants ¶
This section is empty.
Variables ¶
var ( // NullStringConverter creates a *string using the scan type of `sql.NullString` NullStringConverter = Converter{ Name: "nullable string converter", InputScanType: reflect.TypeOf(sql.NullString{}), InputTypeName: "STRING", FrameConverter: FrameConverter{ FieldType: data.FieldTypeNullableString, ConverterFunc: func(n interface{}) (interface{}, error) { v := n.(*sql.NullString) if !v.Valid { return (*string)(nil), nil } f := v.String return &f, nil }, }, } // NullDecimalConverter creates a *float64 using the scan type of `sql.NullFloat64` NullDecimalConverter = Converter{ Name: "NULLABLE decimal converter", InputScanType: reflect.TypeOf(sql.NullFloat64{}), InputTypeName: "DOUBLE", FrameConverter: FrameConverter{ FieldType: data.FieldTypeNullableFloat64, ConverterFunc: func(n interface{}) (interface{}, error) { v := n.(*sql.NullFloat64) if !v.Valid { return (*float64)(nil), nil } f := v.Float64 return &f, nil }, }, } // NullInt64Converter creates a *int64 using the scan type of `sql.NullInt64` NullInt64Converter = Converter{ Name: "NULLABLE int64 converter", InputScanType: reflect.TypeOf(sql.NullInt64{}), InputTypeName: "INTEGER", FrameConverter: FrameConverter{ FieldType: data.FieldTypeNullableInt64, ConverterFunc: func(n interface{}) (interface{}, error) { v := n.(*sql.NullInt64) if !v.Valid { return (*int64)(nil), nil } f := v.Int64 return &f, nil }, }, } // NullInt32Converter creates a *int32 using the scan type of `sql.NullInt32` NullInt32Converter = Converter{ Name: "NULLABLE int32 converter", InputScanType: reflect.TypeOf(sql.NullInt32{}), InputTypeName: "INTEGER", FrameConverter: FrameConverter{ FieldType: data.FieldTypeNullableInt32, ConverterFunc: func(n interface{}) (interface{}, error) { v := n.(*sql.NullInt32) if !v.Valid { return (*int32)(nil), nil } f := v.Int32 return &f, nil }, }, } // NullTimeConverter creates a *time.time using the scan type of `sql.NullTime` NullTimeConverter = Converter{ Name: "NULLABLE time.Time converter", InputScanType: reflect.TypeOf(sql.NullTime{}), InputTypeName: "TIMESTAMP", FrameConverter: FrameConverter{ FieldType: data.FieldTypeNullableTime, ConverterFunc: func(n interface{}) (interface{}, error) { v := n.(*sql.NullTime) if !v.Valid { return (*time.Time)(nil), nil } f := v.Time return &f, nil }, }, } // NullBoolConverter creates a *bool using the scan type of `sql.NullBool` NullBoolConverter = Converter{ Name: "nullable bool converter", InputScanType: reflect.TypeOf(sql.NullBool{}), InputTypeName: "BOOLEAN", FrameConverter: FrameConverter{ FieldType: data.FieldTypeNullableBool, ConverterFunc: func(n interface{}) (interface{}, error) { v := n.(*sql.NullBool) if !v.Valid { return (*bool)(nil), nil } return &v.Bool, nil }, }, } )
var NullConverters = map[reflect.Type]Converter{ reflect.TypeOf(float64(0)): NullDecimalConverter, reflect.TypeOf(int64(0)): NullInt64Converter, reflect.TypeOf(int32(0)): NullInt32Converter, reflect.TypeOf(""): NullStringConverter, reflect.TypeOf(time.Time{}): NullTimeConverter, reflect.TypeOf(false): NullBoolConverter, }
NullConverters is a map of data type names (from reflect.TypeOf(...).String()) to converters Converters supplied here are used as defaults for fields that do not have a supplied Converter
Functions ¶
func Append ¶
Append appends the row to the dataframe, using the converters to convert the scanned value into a value that can be put into a data.Frame
func DefaultConverterFunc ¶
DefaultConverterFunc assumes that the scanned value, in, is already a type that can be put into a dataframe.
func FrameFromRows ¶
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.
A converter must be supplied in order to support data types that are scanned from sql.Rows, but not supported in data.Frame. The converter defines what type to use for scanning, what type to place in the data frame, and a function for converting from one to the other. If you find yourself here after upgrading, you can continue to your StringConverters here by using the `ToConverters` function.
func MakeScanRow ¶
func MakeScanRow(colTypes []*sql.ColumnType, colNames []string, converters ...Converter) (*ScanRow, []Converter, error)
MakeScanRow creates a new scan row given the column types and names. Applicable converters will substitute the SQL scan type with the one provided by the converter. The list of returned converters is the same length as the SQL rows and corresponds with the rows at the same index. (e.g. value at slice element 3 corresponds with the converter at slice element 3) If no converter is provided for a row that has a type that does not fit into a dataframe, it is skipped.
Types ¶
type Converter ¶
type Converter struct { // Name is the name of the converter that is used to distinguish them when debugging or parsing log output Name string // InputScanType is the type that is used when (*sql.Rows).Scan(...) is called. // Some drivers require certain data types to be used when scanning data from sql rows, and this type should reflect that. InputScanType reflect.Type // InputTypeName is the case-sensitive name that must match the type that this converter matches InputTypeName string // InputTypeRegex will be used if not nil instead of InputTypeName InputTypeRegex *regexp.Regexp // FrameConverter defines how to convert the scanned value into a value that can be put into a dataframe FrameConverter FrameConverter // contains filtered or unexported fields }
Converter is used to convert known types returned in sql.Row to a type usable in a dataframe.
func NewDefaultConverter ¶
NewDefaultConverter creates a Converter that assumes that the value is scannable into a String, and placed into the dataframe as a nullable string.
func ToConverters ¶
func ToConverters(s ...StringConverter) []Converter
ToConverters creates a slice of Converters from a slice of StringConverters
type FrameConverter ¶
type FrameConverter struct { // FieldType is the type that is created for the dataframe field. // The returned value from `ConverterFunc` should match this type, otherwise the data package will panic. FieldType data.FieldType // ConverterFunc defines how to convert the scanned `InputScanType` to the supplied `FieldType`. // `in` is always supplied as a pointer, as it is scanned as a pointer, even if `InputScanType` is not a pointer. // For example, if `InputScanType` is `string`, then `in` is `*string` ConverterFunc func(in interface{}) (interface{}, error) // ConvertWithColumn is the same as ConverterFunc, but allows passing the column type // useful when column attributes are needed during conversion ConvertWithColumn func(in interface{}, col sql.ColumnType) (interface{}, error) }
FrameConverter defines how to convert the scanned value into a value that can be put into a dataframe (OutputFieldType)
func StringFrameConverter ¶
func StringFrameConverter(s StringConverter) FrameConverter
StringFrameConverter creates a FrameConverter from a StringConverter
type ScanRow ¶
A ScanRow is a container for SQL metadata for a single row. The row metadata is used to generate dataframe fields and a slice that can be used with sql.Scan
func NewScanRow ¶
NewScanRow creates a new ScanRow with a length of `length`. Use the `Set` function to manually set elements at specific indices.
func (*ScanRow) NewScannableRow ¶
func (s *ScanRow) NewScannableRow() []interface{}
NewScannableRow creates a slice where each element is usable in a call to `(database/sql.Rows).Scan` aka a pointer
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. Note, a Converter should be favored over a StringConverter as not all SQL rows can be scanned into a string. This type is only here for backwards compatibility.
func (StringConverter) ToConverter ¶
func (s StringConverter) ToConverter() Converter
ToConverter turns this StringConverter into a Converter, using the ScanType of string
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. Note, a Converter should be favored over a StringConverter as not all SQL rows can be scanned into a string. This type is only here for backwards compatibility.