scan

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 2, 2025 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package scan has useful functions for handling rows from Query, QueryRow, Exec:

  • CollectRows - collects slice of items
  • CollectRowsKV - collects map of items
  • CollectRow - collects single item

These functions require special row handler row (RowColsCollector, RowColsCollectorKV or RowCollector) that accepts row and should return required type. Basic generic implementation are:

  • Direct scanning: DirectCollectorRowCols, DirectCollectorRowColsKV, DirectCollectorRow
  • Struct fields by position: StructPosCollectorRowCols, StructPosCollectorRow, StructPosCollectorRowColsKV
  • Struct fields by tag: StructTagCollectorRowCols, StructTagCollectorRowColsKV

Examples:

DirectCollectorRowCols:

var ids []int64
rows, _ = db.Query("SELECT id FROM users")
ids, _ = CollectRows(rows, DirectCollectorRowCols[int64])

DirectCollectorRowColsKV:

 var users map[int]string
	rows, _ = db.Query("SELECT id, name FROM users")
	users, _ = CollectRowsKV(rows, DirectCollectorRowColsKV[int64, string])

DirectCollectorRow:

 var name string
	var ok bool
	row = db.QueryRow("SELECT name FROM users where id = $1")
	name, ok, _ = CollectRow(row, DirectCollectorRow[string])

StructTagCollectorRowCols:

 type User struct {
	    Id    int64  `scan:"id"`
	    Name  string `scan:"name"`
	    Email string `scan:"email"`
 }
	var users []User
	rows, _ = db.Query("SELECT id, name, email FROM users")
	users, _ = CollectRows(rows, StructTagCollectorRowCols[User])

StructTagCollectorRowColsKV:

 type User struct {
	    Name  string `scan:"name"`
	    Email string `scan:"email"`
	}
	var users map[int64]User
	rows, _ = db.Query("SELECT id, name, email FROM users")
	users, _ = CollectRowsKV(rows, StructTagCollectorRowColsKV[int64, User])

And so on ...

Package also has Slice for scanning SQL arrays. Example:

 var arr []int
	db.QueryRow(`SELECT ARRAY[1, 2, 3]`).Scan(scan.NewSlice(&arr))

Now arr is [1, 2, 3]

Index

Constants

View Source
const (
	StructTag = "scan"
)

Variables

View Source
var (
	ErrSrcIsNotArray              = errors.New("src is not an array")
	ErrSliceConversionUnsupported = errors.New("slice conversion is unsupported")
	ErrNilUnderlyingSlice         = errors.New("underlying slice is nil")
)
View Source
var (
	ErrStructRequired = errors.New("type is not a struct")
)
View Source
var (
	// PreAllocCollection can be used to override the default capacity of collections returned by CollectRows, CollectRowsKV, CollectRow
	PreAllocCollection uint = 64
)

Functions

func CollectRow

func CollectRow[T any](row *sql.Row, sc RowCollector[T]) (T, bool, error)

CollectRow can be used for scanning single value T from a single a row.

func CollectRows

func CollectRows[T any](rows *sql.Rows, sc RowColsCollector[T]) ([]T, error)

CollectRows can be used for easy scanning collection of T. Note, that it does NOT explicitly close sql.Rows.

func CollectRowsKV

func CollectRowsKV[K comparable, V any](rows *sql.Rows, sc RowColsCollectorKV[K, V]) (map[K]V, error)

CollectRowsKV can be used for scanning a map of K and V. Note, that it does NOT explicitly close sql.Rows.

func DirectCollectorRow

func DirectCollectorRow[T any](row Row) (T, error)

DirectCollectorRow simply passes a T pointer into Scan. T can be a primitive type or sql.Scanner implementation. Roughly equivalent to .Scan(&T)

func DirectCollectorRowCols

func DirectCollectorRowCols[T any](row RowCols) (T, error)

DirectCollectorRowCols simply passes a T pointer into Scan. T can be a primitive type or sql.Scanner implementation. Roughly equivalent to .Scan(&T)

func DirectCollectorRowColsKV

func DirectCollectorRowColsKV[K comparable, V any](row RowCols) (K, V, error)

DirectCollectorRowColsKV simply passes a K pointer and a V pointer into Scan. K and V can be primitive types or sql.Scanner implementations. Roughly equivalent to .Scan(&K, &V)

func StructPosCollectorRow

func StructPosCollectorRow[T any](row Row) (T, error)

StructPosCollectorRow traverses struct T and uses its field as destinations for Scan. Order of struct fields must be the same as order of returned columns. Roughly equivalent to .Scan(&T.Field1, &T.Field2, &T.Field3, ...)

func StructPosCollectorRowCols

func StructPosCollectorRowCols[T any](row RowCols) (T, error)

StructPosCollectorRowCols traverses struct T and uses its field as destinations for Scan. Order of struct fields must be the same as order of returned columns. Roughly equivalent to .Scan(&T.Field1, &T.Field2, &T.Field3, ...)

func StructPosCollectorRowColsKV

func StructPosCollectorRowColsKV[K comparable, V any](row RowCols) (K, V, error)

StructPosCollectorRowColsKV traverses struct V and uses its field as destinations for Scan. The first column is directly scanned in K, Order of struct fields must be the same as order of returned columns. Roughly equivalent to .Scan(&K, &V.Field1, &V.Field2, &V.Field3, ...)

func StructTagCollectorRowCols

func StructTagCollectorRowCols[T any](row RowCols) (T, error)

StructTagCollectorRowCols maps returned columns on T struct fields by "scan" tag and passes those fields in Scan. If no field is found for column error will be returned. Roughly equivalent to .Scan(&T.FieldForColumn1, &T.FieldForColumn2, &T.FieldForColumn3, ...)

func StructTagCollectorRowColsKV

func StructTagCollectorRowColsKV[K comparable, V any](row RowCols) (K, V, error)

StructTagCollectorRowColsKV maps returned columns on T struct fields by "scan" tag and passes those fields in Scan. The first column is directly scanned in K. If no field is found for column error will be returned. Roughly equivalent to .Scan(&K, &V.FieldForColumn2, &V.FieldForColumn3, &V.FieldForColumn4, ...)

Types

type Row

type Row interface {
	Scan(...interface{}) error
}

Row is an abstraction for sql.Rows that can be used only for scanning.

type RowCollector

type RowCollector[T any] func(row Row) (T, error)

RowCollector should return concrete typed value scanned from row, without any information about columns. Basic implementations are:

  • StructPosCollectorRow to scan row into struct via its field position
  • DirectCollectorRow to scan row into T directly (primitives and sql.Scanner implementations)

type RowCols

type RowCols interface {
	Row
	Columns() ([]string, error)
}

RowCols is the same as Row, but column names are also available

type RowColsCollector

type RowColsCollector[T any] func(row RowCols) (T, error)

RowColsCollector should return concrete typed value scanned from row. Basic implementations are:

  • StructTagCollectorRowCols to scan row into struct via its field tags "scan"
  • StructPosCollectorRowCols to scan row into struct via its field position
  • DirectCollectorRowCols to scan row into T directly (primitives and sql.Scanner implementations)

type RowColsCollectorKV

type RowColsCollectorKV[K comparable, V any] func(row RowCols) (K, V, error)

RowColsCollectorKV should return concrete typed key and value scanned from row. Basic implementations are:

  • StructTagCollectorRowColsKV to scan row into struct via its field tags "scan". Key will be used in scan directly
  • StructPosCollectorRowColsKV to scan row into struct via its field position. Key will be used in scan directly
  • DirectCollectorRowColsKV to scan row into T directly (primitives and sql.Scanner implementations). Both key and value will be used in scan directly

type Slice

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

Slice is an implementation of sql.Scanner for SQL arrays. Use NewSlice to get a new Slice.

func NewSlice

func NewSlice[T any](values *[]T) Slice

NewSlice returns new Slice with underlying values

func (Slice) Scan

func (s Slice) Scan(src any) error

Jump to

Keyboard shortcuts

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