querysql

package
v1.0.6 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2025 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package querysql is a newer interface to the capabilities in query ("query v2" in a sense). Intention is to also replace misc testutils.Scan functions ec. May be separated into another repo longer term, but is convenient to test it together with testdb package for now.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoMoreSets = fmt.Errorf("no more result sets")
View Source
var ErrNotDone = fmt.Errorf("there are more result sets after reading last expected result")
View Source
var ManyRowsExpectedOne = QuerySqlError{
	// contains filtered or unexported fields
}
View Source
var ZeroRowsExpectedOne = QuerySqlError{
	// contains filtered or unexported fields
}

Functions

func Call

func Call[T any](visit func(row T) error) func() Result[int]

Call lets you provide a callback visit function that is called for each row. The returned data is the number of rows scanned.

func DeepFieldNames

func DeepFieldNames(v interface{}) []string

Return names of fields of struct instance v, recursing into embedded structs (but not named struct members)

func DeepFieldPointers

func DeepFieldPointers(obj interface{}) []interface{}

Return pointers to fields of struct instance v, recursing into embedded structs (but not named struct members)

func Exec

func Exec(querier CtxQuerier, qry string, args ...any) (sql.Result, error)

func ExecContext

func ExecContext(
	ctx context.Context,
	querier CtxQuerier,
	qry string,
	args ...any,
) (sql.Result, error)

func Iter

func Iter[T any](ctx context.Context, querier CtxQuerier, visit func(T) error, qry string, args ...any) error

func MustIter

func MustIter[T any](ctx context.Context, querier CtxQuerier, visit func(T) error, qry string, args ...any)

func MustNext

func MustNext(rs *ResultSets, scanner Target)

func MustNextResult

func MustNextResult[T any](rs *ResultSets, typ func() Result[T]) T

func MustSingle

func MustSingle[T any](ctx context.Context, querier CtxQuerier, qry string, args ...any) T

func MustSlice

func MustSlice[T any](ctx context.Context, querier CtxQuerier, qry string, args ...any) []T

func MustStructType

func MustStructType(v reflect.Type) reflect.Type

func MustStructValue

func MustStructValue(v reflect.Value) reflect.Value

func Next

func Next(rs *ResultSets, scanner Target) error

Next reads the next result set from `rs`, passing each row to `scanner`; taking care of checking errors and advancing result sets. On errors, `rs` will be closed. If EnsureDoneAfterNext is used, `rs` will also be closed on successful return.

func NextNoScanner

func NextNoScanner(rs *ResultSets) error

func NextResult

func NextResult[T any](rs *ResultSets, typ func() Result[T]) (T, error)

NextResult reads the next result set from `rs`, into the type/scanner provided in the `typ` argument. Typical arguments for `typ` is `SliceOf[int]`, `SingleOf[MyStruct]`, `Call[MyStruct](func(MyStruct) error { ... })`

func ParseSQLUUIDBytes

func ParseSQLUUIDBytes(v []uint8) (uuid.UUID, error)

func Query

func Query(
	targets []Target,
	ctx context.Context,
	querier CtxQuerier,
	qry string,
	args ...any,
) error

func Query2

func Query2[T1 any, T2 any](
	type1 func() Result[T1],
	type2 func() Result[T2],
	ctx context.Context,
	querier CtxQuerier,
	qry string,
	args ...any) (T1, T2, error)

func Query3

func Query3[T1 any, T2 any, T3 any](
	type1 func() Result[T1],
	type2 func() Result[T2],
	type3 func() Result[T3],
	ctx context.Context,
	querier CtxQuerier,
	qry string,
	args ...any,
) (T1, T2, T3, error)

func Query4

func Query4[T1 any, T2 any, T3 any, T4 any](
	type1 func() Result[T1],
	type2 func() Result[T2],
	type3 func() Result[T3],
	type4 func() Result[T4],
	ctx context.Context,
	querier CtxQuerier,
	qry string,
	args ...any,
) (T1, T2, T3, T4, error)

func Single

func Single[T any](ctx context.Context, querier CtxQuerier, qry string, args ...any) (T, error)

func SingleOrNil added in v1.0.2

func SingleOrNil[T any](ctx context.Context, querier CtxQuerier, qry string, args ...any) (*T, error)

func Slice

func Slice[T any](ctx context.Context, querier CtxQuerier, qry string, args ...any) ([]T, error)

func WithDispatcher

func WithDispatcher(ctx context.Context, dispatcher RowsGoDispatcher) context.Context

func WithLogger

func WithLogger(ctx context.Context, logger RowsLogger) context.Context

WithLogger will return the context with a logger registered for use with querysql; during queries, querysql will use Logger() to extract the logger from the context

Types

type CtxQuerier

type CtxQuerier interface {
	QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
	QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
}

type NameAndTag

type NameAndTag struct {
	Name string
	Tag  string
}

type NotImplementedSqlResult

type NotImplementedSqlResult struct{}

func (NotImplementedSqlResult) LastInsertId

func (_ NotImplementedSqlResult) LastInsertId() (int64, error)

func (NotImplementedSqlResult) RowsAffected

func (_ NotImplementedSqlResult) RowsAffected() (int64, error)

type QuerySqlError

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

func (QuerySqlError) Error

func (e QuerySqlError) Error() string

func (QuerySqlError) Is

func (e QuerySqlError) Is(other error) bool

func (QuerySqlError) Unwrap

func (e QuerySqlError) Unwrap() error

type Result

type Result[T any] interface {
	Target
	Result() (T, errorWrapper)
}

func SingleOf

func SingleOf[T any]() Result[T]

SingleOf declares that you want to enforce that the resultset only has a single row, and scan that single row into a value of type T that is returned.

func SliceOf

func SliceOf[T any]() Result[[]T]

SliceOf declares that you want to scan the result into a slice of type T.

type ResultSets

type ResultSets struct {
	Rows *sql.Rows
	// Err is set to defer errors from constructors until the first method call
	Err error

	// Set DoneAfterNext to enable a mode where an error is returned if we did not exhaust the resultset
	DoneAfterNext bool

	// Logger is used for outputting select statements with the special log column (see README)
	// By default it is set by New to the value provided by Logger(ctx), but feel free to set or change it.
	Logger RowsLogger

	// TODO(dsf): Perhaps remove the LogKeyLowercase.  I'm not 100% this feature is justified
	// By default, the use of an underscore column, "select _log=info, ...", will trigger logging
	// This lets you specify a custom key such as "loglevel" for the same purpose in addition.
	// It will be compared with the lowercase name of the column.
	LogKeyLowercase string

	// "select _function=MyFunction" will attempt to fall a Go function (in this case MyFunction)
	// with the remaining arguments to the select as arguments to the function call
	Dispatcher RowsGoDispatcher
	// contains filtered or unexported fields
}

ResultSets is a tiny wrapper around sql.Rows to help managing whether to call NextResultSet or not. It is fine to instantiate this struct yourself.

Template methods are not allowed in Go, so the "methods" of this struct are provided as functions prefixed with ScanRow; NextStructSlice, NextInt, etc

func New

func New(ctx context.Context, querier CtxQuerier, qry string, args ...any) *ResultSets

func (*ResultSets) Close

func (rs *ResultSets) Close() error

func (*ResultSets) Done

func (rs *ResultSets) Done() bool

func (*ResultSets) EnsureDoneAfterNext

func (rs *ResultSets) EnsureDoneAfterNext() *ResultSets

EnsureDoneAfterNext sets the DoneAfterNext flag. The receiver rs is returned for syntactical brevity, a copy is not made

type RowScanner

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

type RowsGoDispatcher

type RowsGoDispatcher func(rows *sql.Rows) error

RowsGoDispatcher takes a sql.Rows and calls a Go function. The first argument, __function is the function name, the other arguments are the arguments to the Go function.

func Dispatcher

func Dispatcher(ctx context.Context) RowsGoDispatcher

func GoMSSQLDispatcher

func GoMSSQLDispatcher(fs []interface{}) RowsGoDispatcher

type RowsLogger

type RowsLogger func(rows *sql.Rows) error

RowsLogger takes a sql.Rows and logs it. A default implementation is available, but sometimes one might wish to improve on the formatting of different data types, hence this low level interface is available.

The convention is that the first column will always contain the log level.

func Logger

func Logger(ctx context.Context) RowsLogger

func LogrusMSSQLLogger

func LogrusMSSQLLogger(logger logrus.FieldLogger, defaultLogLevel logrus.Level) RowsLogger

LogrusMSSQLLogger returns a basic RowsLogger suitable for the combination of MS SQL and logrus

type Target

type Target interface {
	ScanRow(*sql.Rows) error
}

func SingleInto

func SingleInto[T any](target *T) Target

SingleInto set up reading a single row into `target`. If there is not exactly 1 row in the resultset an error is returned.

func SliceInto

func SliceInto[T any](target *[]T) Target

SliceInto declares that you want to scan the result into a slice of type T at the given `target`

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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