sqlbind

package
v0.5.34 Latest Latest
Warning

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

Go to latest
Published: Sep 19, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package sqlbind provides generated, reflection-free database/sql row mapping.

Index

Constants

This section is empty.

Variables

View Source
var ErrEmptyValueList = errors.New("tinybind SQL: an expanded value list cannot be empty")

ErrEmptyValueList reports that an expanded value list had no elements, which would produce invalid SQL such as "IN ()".

View Source
var ErrNoSQLExecutor = errors.New("sqlbind: no SQL executor in context")

ErrNoSQLExecutor reports that a Context does not contain a database executor. It is returned instead of panicking so generated Context wrappers remain ordinary error-returning APIs.

View Source
var ErrReadOnlyExecutor = errors.New("sqlbind: SQL executor in context is read-only")

ErrReadOnlyExecutor reports that a write statement resolved an executor the caller declared read-only. It is returned before the statement is built, so a misrouted write fails deterministically instead of depending on whether the connection happens to reach a read replica.

Functions

func Bool

func Bool(row Row, column string) (bool, error)

func Float64

func Float64(row Row, column string) (float64, error)

func ForEach

func ForEach(rows Rows, fn func(Row) error) error

ForEach scans rows without retaining the full result.

func Int

func Int(row Row, column string) (int, error)

func Int64

func Int64(row Row, column string) (int64, error)

func Key

func Key(row Row, column string) (key string, present bool, err error)

Key returns a stable grouping key. present is false for SQL NULL.

func RegisterScanRows

func RegisterScanRows[T any](fn func(Rows) ([]T, error))

RegisterScanRows registers a generated SQL tree scanner for T.

func RequiredKey

func RequiredKey(row Row, column string) (string, error)

RequiredKey is Key with NULL rejected for a root object.

func ScanOptionalURL added in v0.2.2

func ScanOptionalURL(target **url.URL) optionalURLTarget

ScanOptionalURL is ScanURL for an optional field, where SQL NULL leaves a nil pointer instead of failing.

func ScanRows

func ScanRows[T any](rows Rows) ([]T, error)

ScanRows maps joined SQL rows into a grouped object tree using generated code.

func ScanURL added in v0.2.2

func ScanURL(target *url.URL) urlTarget

ScanURL adapts a url.URL field to Rows.Scan. Generated code passes it in place of the field address, so the column is parsed rather than assigned.

func SignedN added in v0.5.23

func SignedN(row Row, column string, bits int) (int64, error)

SignedN scans a column as a signed integer of the given width, reporting a value the width cannot hold rather than truncating it. It is what generated code calls for int8, int16 and int32; int and int64 keep Int and Int64.

func String

func String(row Row, column string) (string, error)

func Uint64 added in v0.5.23

func Uint64(row Row, column string) (uint64, error)

Uint64 scans a column as uint64, refusing a negative value rather than wrapping it into a large positive one.

This is the one unsigned scanner. The narrower widths are read through it and range-checked by the generated code against bounds it knows at generation, which is what [jsonbind.Parser.Uint64] does on the document side and keeps four more scanners out of the runtime.

func UnsignedN added in v0.5.23

func UnsignedN(row Row, column string, bits int) (uint64, error)

UnsignedN is the SignedN twin. Passing 64 checks nothing beyond what Uint64 already refuses, which is a negative value.

func WithSQLExecutor added in v0.1.6

func WithSQLExecutor(ctx context.Context, executor SQLExecutor, options ...ExecutorOption) context.Context

WithSQLExecutor returns a child Context containing a database executor. Framework transaction middleware can store a *sql.Tx for generated <Component>Context wrappers to resolve.

Types

type Builder added in v0.1.16

type Builder struct {
	strings.Builder
	// contains filtered or unexported fields
}

Builder accumulates SQL text and its bound arguments. Generated statement builders write into it; template authors never construct placeholders themselves.

func NewBuilder added in v0.1.16

func NewBuilder(style PlaceholderStyle) Builder

NewBuilder returns a Builder emitting placeholders in the given style.

func (*Builder) AppendValues added in v0.5.28

func (b *Builder) AppendValues[T any](values []T) error

AppendValues expands a slice into a comma-separated placeholder list.

The element type is the method's own type parameter, which is what kept it a package function before Go 1.27; it is inferred from values.

func (*Builder) Arg added in v0.1.16

func (b *Builder) Arg(value any)

Arg binds one value and writes its placeholder. Appending the argument and emitting its placeholder is a single operation, so numbering always matches argument order.

func (*Builder) CloseGroup added in v0.5.15

func (b *Builder) CloseGroup(closer string)

CloseGroup ends the innermost group, writing closer only if the group was opened. A clause group passes an empty closer: it ends at the keyword that starts the next clause, which belongs outside it. A separator the group was holding is dropped, because nothing followed it.

func (*Builder) Item added in v0.5.15

func (b *Builder) Item()

Item is called immediately before every fragment that writes a token or binds a value. It opens whatever groups are still withheld, outermost first, so that each opener is preceded by the separator attaching it to its own parent.

func (*Builder) Joiner added in v0.5.15

func (b *Builder) Joiner(separator string)

Joiner records the separator between two items of the innermost open group. It is dropped when the group has written no item yet, which is what makes a leading operator vanish along with the condition it was meant to join.

func (*Builder) OpenGroup added in v0.5.15

func (b *Builder) OpenGroup(opener string)

OpenGroup begins a group whose opener is withheld. Nothing is written.

func (*Builder) Space added in v0.5.15

func (b *Builder) Space(text string)

Space writes a run of whitespace that separates two items rather than being one. It travels with the separator it follows, so an elided joiner takes its spacing with it, and it is dropped in a group that has written no item, where it would otherwise be spacing in front of nothing. The scanner does not tokenize whitespace and alwaysEmits does not count it, so it can never fill a group.

func (*Builder) Statement added in v0.1.16

func (b *Builder) Statement() Statement

Statement returns the accumulated SQL and arguments.

type Execer added in v0.1.16

type Execer interface {
	ExecContext(context.Context, string, ...any) (sql.Result, error)
}

Execer is the minimal executor a generated sql.exec component needs. It is satisfied by *sql.DB, *sql.Conn, and *sql.Tx.

type ExecutorOption added in v0.2.1

type ExecutorOption func(*sqlExecutorEntry)

ExecutorOption configures how a stored executor may be used.

func AsReadOnly added in v0.2.1

func AsReadOnly() ExecutorOption

AsReadOnly marks the stored executor as read-only, so a generated write statement resolving it fails with ErrReadOnlyExecutor. Use it for a handle pointing at a read replica, or for a transaction begun with sql.TxOptions{ReadOnly: true}.

type PlaceholderStyle added in v0.1.16

type PlaceholderStyle int

PlaceholderStyle selects the bind-placeholder syntax of the target dialect. Generated code passes the style chosen at generation time, so one Builder implementation serves every dialect.

const (
	// Dollar emits PostgreSQL-style $1, $2, ... placeholders.
	Dollar PlaceholderStyle = iota
	// Question emits ?-style placeholders.
	Question
)

type Querier added in v0.1.16

type Querier interface {
	QueryContext(context.Context, string, ...any) (*sql.Rows, error)
}

Querier is the minimal executor a generated row-returning component needs. It is satisfied by *sql.DB, *sql.Conn, and *sql.Tx. Its QueryContext must return the concrete *sql.Rows because those types do, and Go interface satisfaction is exact; a backend outside database/sql cannot construct a *sql.Rows, so it additionally implements RowsQuerier and embeds UnimplementedQuerier.

type Row

type Row map[string]any

Row is a SQL row indexed by result column name.

type Rows added in v0.4.2

type Rows interface {
	Next() bool
	Scan(dest ...any) error
	Err() error
	Close() error
	Columns() ([]string, error)
}

Rows is the row cursor generated code and the sqlbind scanners consume. It is satisfied by *sql.Rows unchanged; a non-database/sql backend such as pgx returns its own implementation (wrapping Close to add the error return, and deriving Columns from its field descriptions). Columns is required by ForEach, which builds column-indexed Row maps; generated statement bodies use only Next, Scan, Err, and Close.

func Query added in v0.4.2

func Query(ctx context.Context, db Querier, query string, args ...any) (Rows, error)

Query executes a row-returning statement through db. A backend implementing RowsQuerier is queried through it; otherwise db is a database/sql handle and its *sql.Rows is returned as Rows. Generated row-returning statements call this instead of db.QueryContext directly, so one generated body serves both kinds of backend.

type RowsQuerier added in v0.4.2

type RowsQuerier interface {
	QueryRows(ctx context.Context, query string, args ...any) (Rows, error)
}

RowsQuerier is the driver-agnostic query surface a non-database/sql executor implements alongside Querier. Query prefers it over Querier.QueryContext, the same way io.Copy prefers io.ReaderFrom: the optional interface upgrades the backend without forking the generated code path or the executor parameter type.

type SQLExecutor added in v0.1.6

type SQLExecutor interface {
	Execer
	Querier
}

SQLExecutor is implemented by *sql.DB, *sql.Conn, and *sql.Tx. It combines the two minimal interfaces generated code takes, so one Context value serves both mutating and row-returning components.

func SQLExecutorFromContext added in v0.1.6

func SQLExecutorFromContext(ctx context.Context) (SQLExecutor, error)

SQLExecutorFromContext returns the executor installed by WithSQLExecutor. It is the resolver generated read statements use, and it accepts a read-only executor.

func WriteExecutorFromContext added in v0.2.1

func WriteExecutorFromContext(ctx context.Context, statement string) (SQLExecutor, error)

WriteExecutorFromContext is the resolver generated write statements use. It rejects an executor stored with AsReadOnly, naming the statement so the error identifies which one was misrouted.

type Statement added in v0.1.16

type Statement struct {
	SQL  string
	Args []any
}

Statement is the low-level result of a generated SQL component: the compiled SQL text plus its bound arguments, with no database handle attached.

type UnimplementedQuerier added in v0.4.2

type UnimplementedQuerier struct{}

UnimplementedQuerier satisfies Querier's QueryContext with an error, for embedding in an executor whose real query path is QueryRows. Query never reaches it when RowsQuerier is implemented; it exists so a custom backend can satisfy Querier without being able to construct a *sql.Rows.

func (UnimplementedQuerier) QueryContext added in v0.4.2

func (UnimplementedQuerier) QueryContext(context.Context, string, ...any) (*sql.Rows, error)

QueryContext always fails: a backend embedding UnimplementedQuerier queries through RowsQuerier. Reaching this method means the executor was used where sqlbind.Query cannot dispatch, such as pre-Rows generated code.

Jump to

Keyboard shortcuts

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