record

package
v0.36.0 Latest Latest
Warning

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

Go to latest
Published: May 26, 2023 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package record holds the record.Record type, which is the core type for holding query results.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Equal

func Equal(a, b Record) bool

Equal returns true if rec1 and rec2 contain the same values.

func SetKindIfUnknown

func SetKindIfUnknown(meta Meta, i int, k kind.Kind)

SetKindIfUnknown sets meta[i].kind to k, iff the kind is currently kind.Unknown or kind.Null. This function can be used to set the kind after-the-fact, which is useful for some databases that don't always return sufficient type info upfront.

func Valid

func Valid(_ Meta, rec Record) (i int, err error)

Valid checks that each element of the record vals is of an acceptable type. On the first unacceptable element, the index of that element and an error are returned. On success (-1, nil) is returned.

These acceptable types, per the stdlib sql pkg, are:

nil, *int64, *float64, *bool, *string, *[]byte, *time.Time

Types

type ColumnTypeData

type ColumnTypeData struct {
	Name string `json:"name"`

	HasNullable       bool `json:"has_nullable"`
	HasLength         bool `json:"has_length"`
	HasPrecisionScale bool `json:"has_precision_scale"`

	Nullable         bool         `json:"nullable"`
	Length           int64        `json:"length"`
	DatabaseTypeName string       `json:"database_type_name"`
	Precision        int64        `json:"precision"`
	Scale            int64        `json:"scale"`
	ScanType         reflect.Type `json:"scan_type"`

	Kind kind.Kind `json:"kind"`
}

ColumnTypeData contains the same data as sql.ColumnType as well SQ's derived data kind. This type exists with exported fields instead of methods (as on sql.ColumnType) due to the need to work with the fields for testing, and also because for some drivers it's useful to twiddle with the scan type.

This is all a bit ugly.

func NewColumnTypeData

func NewColumnTypeData(col *sql.ColumnType, knd kind.Kind) *ColumnTypeData

NewColumnTypeData returns a new instance with field values taken from col, supplemented with the kind param.

type FieldMeta

type FieldMeta struct {
	// contains filtered or unexported fields
}

FieldMeta is a bit of a strange entity, and in an ideal world, it wouldn't exist. It's here because:

- The DB driver impls that sq utilizes (postgres, sqlite, etc) often have individual quirks (not reporting nullability etc) that necessitate modifying sql.ColumnType so that there's consistent behavior across the drivers.

- We wanted to retain (and supplement) the method set of sql.ColumnType (basically, use the same "interface", even though sql.ColumnType is a struct, not interface) so that devs don't need to learn a whole new thing.

- For that reason, stdlib sql.ColumnType needs to be supplemented with kind.Kind, and there needs to be a mechanism for modifying sql.ColumnType's fields.

- But sql.ColumnType is sealed (its fields cannot be changed from outside its package).

- Hence this construct where we have FieldMeta (which abstractly is an adapter around sql.ColumnType) and also a data holder struct (ColumnDataType), which permits the mutation of the column type fields.

Likely there's a better design available than this one, but it suffices.

func NewFieldMeta

func NewFieldMeta(data *ColumnTypeData) *FieldMeta

NewFieldMeta returns a new instance backed by the data arg.

func (*FieldMeta) DatabaseTypeName

func (fm *FieldMeta) DatabaseTypeName() string

DatabaseTypeName is documented by sql.ColumnType.DatabaseTypeName.

func (*FieldMeta) DecimalSize

func (fm *FieldMeta) DecimalSize() (precision, scale int64, ok bool)

DecimalSize is documented by sql.ColumnType.DecimalSize.

func (*FieldMeta) Kind

func (fm *FieldMeta) Kind() kind.Kind

Kind returns the data kind for the column.

func (*FieldMeta) Length

func (fm *FieldMeta) Length() (length int64, ok bool)

Length is documented by sql.ColumnType.Length.

func (*FieldMeta) Name

func (fm *FieldMeta) Name() string

Name is documented by sql.ColumnType.Name.

func (*FieldMeta) Nullable

func (fm *FieldMeta) Nullable() (nullable, ok bool)

Nullable is documented by sql.ColumnType.Nullable.

func (*FieldMeta) ScanType

func (fm *FieldMeta) ScanType() reflect.Type

ScanType is documented by sql.ColumnType.ScanType.

func (*FieldMeta) String

func (fm *FieldMeta) String() string

type Meta

type Meta []*FieldMeta

Meta is a slice of *FieldMeta, encapsulating the metadata for a record.

func (Meta) Kinds

func (rm Meta) Kinds() []kind.Kind

Kinds returns the data kinds for the record.

func (Meta) Names

func (rm Meta) Names() []string

Names returns the column names.

func (Meta) NewScanRow

func (rm Meta) NewScanRow() []any

NewScanRow returns a new []any that can be scanned into by sql.Rows.Scan.

func (Meta) ScanTypes

func (rm Meta) ScanTypes() []reflect.Type

ScanTypes returns the scan types for the record.

type Record

type Record []any

Record is a []any row of field values returned from a query.

In the codebase, we distinguish between a "Record" and a "ScanRow", although both are []any and are closely related.

An instance of ScanRow is passed to the sql rows.Scan method, and its elements may include implementations of the sql.Scanner interface such as sql.NullString, sql.NullInt64 or even driver-specific types.

A Record is typically built from a ScanRow, unwrapping and munging elements such that the Record only contains standard types:

nil, *int64, *float64, *bool, *string, *[]byte, *time.Time

It is an error for a Record to contain elements of any other type.

Jump to

Keyboard shortcuts

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