Help us shape the future of Go! Take the 2026 Go Developer Survey

rowscan

package
v0.23.0 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Scanner

type Scanner[T any] struct {
	// contains filtered or unexported fields
}

Scanner scans a result set into a struct by `db` tag while tolerating a result set whose columns do not match the struct exactly.

sqlx's StructScan is all-or-nothing in one direction: a single result column that no `db` tag claims fails every row with "missing destination name X in *T". Two things routinely produce such a column, and both are outside our control. A warehouse-managed view gains one on a vendor release, which turns an ingest into a total outage rather than a missing field. And an account configured to fold quoted identifiers to upper case returns every alias in a case the query did not ask for, so nothing matches at all.

Pinning an explicit column list in the query instead only moves the problem: the query then fails outright the day a column is withdrawn, or against a narrowed view exposing a subset.

So neither the struct nor the query decides the shape — the result set does. A column with no field is discarded and reported by UnknownColumns; a `db` tag with no column is left at its zero value and reported by MissingColumns. Callers that cannot work without a given column say so with RequireColumns rather than leaving it to the scan to fail somewhere downstream.

Only fields carrying an explicit `db` tag participate; fields the scrapper fills in itself stay untouched. Matching is case-insensitive.

func New

func New[T any](rows *sqlx.Rows) (*Scanner[T], error)

New plans how the columns of an open result set map onto T.

func (*Scanner[T]) LogColumnDrift

func (s *Scanner[T]) LogColumnDrift(ctx context.Context, source string)

LogColumnDrift reports the difference between the result set and the struct, so a vendor adding or withdrawing a column surfaces in logs on the run it first happens rather than the next time someone reads the code. source names the object read, for example "SNOWFLAKE.ACCOUNT_USAGE.TASK_HISTORY"; it is left empty by callers that read an arbitrary statement rather than a named object, where the target type is what identifies the read.

func (*Scanner[T]) MissingColumns

func (s *Scanner[T]) MissingColumns() []string

MissingColumns lists `db` tags the result set does not carry. Those fields stay at their zero value.

func (*Scanner[T]) RequireColumns

func (s *Scanner[T]) RequireColumns(columns ...string) error

RequireColumns fails when a column the caller cannot do without is absent from the result set, so an unusable read is rejected up front instead of producing rows with holes in them.

func (*Scanner[T]) Scan

func (s *Scanner[T]) Scan(rows *sqlx.Rows, dest *T) error

Scan reads the current row into dest.

func (*Scanner[T]) UnknownColumns

func (s *Scanner[T]) UnknownColumns() []string

UnknownColumns lists result columns the struct has no field for. They are discarded rather than fatal, and are the expected shape of a vendor adding a column to a view we read.

Jump to

Keyboard shortcuts

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