Documentation
¶
Overview ¶
Package orm provides a small, code-generation-oriented data mapper over database/sql. It does not inspect model values with reflection or discover tables at runtime. Generated code defines tables, mappers, and columns; an application may always use the underlying *sql.DB or *sql.Tx directly. Reflection is used only at the argument boundary to reject typed nil values and defensively copy byte-slice aliases; model mapping never uses reflection.
Index ¶
- Constants
- Variables
- type Assignment
- type BelongsTo
- type BulkInsertBuilder
- type Column
- func (column Column[M, V]) Asc() Order[M]
- func (column Column[M, V]) Desc() Order[M]
- func (column Column[M, V]) Eq(value V) Predicate[M]
- func (column Column[M, V]) From(field Field[V]) Assignment[M]
- func (column Column[M, V]) Gt(value V) Predicate[M]
- func (column Column[M, V]) Gte(value V) Predicate[M]
- func (column Column[M, V]) In(values ...V) Predicate[M]
- func (column Column[M, V]) IsNotNull() Predicate[M]
- func (column Column[M, V]) IsNull() Predicate[M]
- func (column Column[M, V]) Lt(value V) Predicate[M]
- func (column Column[M, V]) Lte(value V) Predicate[M]
- func (column Column[M, V]) NotEq(value V) Predicate[M]
- func (column Column[M, V]) Set(value V) Assignment[M]
- type ConstraintError
- type ConstraintKind
- type DeleteBuilder
- type Executor
- type Field
- type FieldState
- type HasMany
- type HasOne
- type InsertBuilder
- func (builder InsertBuilder[M]) Build() (Statement, error)
- func (builder InsertBuilder[M]) One(ctx context.Context, executor Executor) (M, error)
- func (builder InsertBuilder[M]) Rows(rows ...InsertRow[M]) BulkInsertBuilder[M]
- func (builder InsertBuilder[M]) Values(assignments ...Assignment[M]) InsertBuilder[M]
- type InsertRow
- type ManyToMany
- func (relation ManyToMany[P, T, PK, TK]) Attach(ctx context.Context, executor Executor, parentKey PK, targetKey TK) (bool, error)
- func (relation ManyToMany[P, T, PK, TK]) Build(parents []P, scope SelectBuilder[T]) ([]Statement, error)
- func (relation ManyToMany[P, T, PK, TK]) BuildAttach(parentKey PK, targetKey TK) (Statement, error)
- func (relation ManyToMany[P, T, PK, TK]) BuildDetach(parentKey PK, targetKey TK) (Statement, error)
- func (relation ManyToMany[P, T, PK, TK]) Detach(ctx context.Context, executor Executor, parentKey PK, targetKey TK) (bool, error)
- func (relation ManyToMany[P, T, PK, TK]) Load(ctx context.Context, executor Executor, parents []P, scope SelectBuilder[T]) ([]P, error)
- type Mapper
- type Number
- type Operation
- type Order
- type PersistenceError
- type Predicate
- func And[M any](predicates ...Predicate[M]) Predicate[M]
- func ContainsFold[M any, S ~string](column Column[M, S], literal string) Predicate[M]
- func ContainsFoldNullable[M any, S ~string](column Column[M, *S], literal string) Predicate[M]
- func Like[M any](column Column[M, string], pattern string) Predicate[M]
- func Not[M any](predicate Predicate[M]) Predicate[M]
- func Or[M any](predicates ...Predicate[M]) Predicate[M]
- type RelationOptions
- type RowScanner
- type SelectBuilder
- func (builder SelectBuilder[M]) All(ctx context.Context, executor Executor) ([]M, error)
- func (builder SelectBuilder[M]) Build() (Statement, error)
- func (builder SelectBuilder[M]) BuildCount() (Statement, error)
- func (builder SelectBuilder[M]) BuildExists() (Statement, error)
- func (builder SelectBuilder[M]) Count(ctx context.Context, executor Executor) (int64, error)
- func (builder SelectBuilder[M]) Exists(ctx context.Context, executor Executor) (bool, error)
- func (builder SelectBuilder[M]) First(ctx context.Context, executor Executor) (M, error)
- func (builder SelectBuilder[M]) ForShare() SelectBuilder[M]
- func (builder SelectBuilder[M]) ForUpdate() SelectBuilder[M]
- func (builder SelectBuilder[M]) Limit(limit int) SelectBuilder[M]
- func (builder SelectBuilder[M]) Offset(offset int) SelectBuilder[M]
- func (builder SelectBuilder[M]) OrderBy(orders ...Order[M]) SelectBuilder[M]
- func (builder SelectBuilder[M]) Where(predicates ...Predicate[M]) SelectBuilder[M]
- type Statement
- type StatementEvent
- type StatementObserver
- type Table
- type TransientError
- type TransientKind
- type UpdateBuilder
- func (builder UpdateBuilder[M]) AllRows() UpdateBuilder[M]
- func (builder UpdateBuilder[M]) Build() (Statement, error)
- func (builder UpdateBuilder[M]) BuildReturning() (Statement, error)
- func (builder UpdateBuilder[M]) Exec(ctx context.Context, executor Executor) (int64, error)
- func (builder UpdateBuilder[M]) One(ctx context.Context, executor Executor) (M, error)
- func (builder UpdateBuilder[M]) OptimisticVersion(guard VersionGuard[M]) UpdateBuilder[M]
- func (builder UpdateBuilder[M]) Set(assignments ...Assignment[M]) UpdateBuilder[M]
- func (builder UpdateBuilder[M]) StaleOnZero() UpdateBuilder[M]
- func (builder UpdateBuilder[M]) Where(predicates ...Predicate[M]) UpdateBuilder[M]
- type VersionGuard
Constants ¶
const PostgreSQLParameterLimit = 65_535
PostgreSQLParameterLimit is the maximum number of bind parameters in one PostgreSQL statement. Builders reject larger statements before execution.
Variables ¶
var ( ErrNotFound = errors.New("orm: record not found") ErrUnsafeMutation = errors.New("orm: mutation requires a predicate or AllRows") ErrStale = errors.New("orm: stale record") ErrTransactionRequired = errors.New("orm: row locking requires a transaction executor") ErrUnique = errors.New("orm: unique constraint violation") ErrForeignKey = errors.New("orm: foreign key constraint violation") ErrNotNull = errors.New("orm: not-null constraint violation") ErrCheck = errors.New("orm: check constraint violation") ErrSerialization = errors.New("orm: serialization failure") ErrDeadlock = errors.New("orm: deadlock detected") )
Functions ¶
This section is empty.
Types ¶
type Assignment ¶
type Assignment[M any] struct { // contains filtered or unexported fields }
Assignment is created from a typed Column and therefore cannot assign a value of the wrong Go type or a column belonging to another model type.
func Increment ¶
func Increment[M any, V Number](column Column[M, V], delta V) Assignment[M]
Increment creates a column arithmetic expression without accepting raw SQL. The delta remains a bound argument.
func SetCurrentTime ¶
func SetCurrentTime[M any](column Column[M, time.Time]) Assignment[M]
SetCurrentTime is the only built-in clock expression and is available only for time.Time columns. It never accepts SQL text.
type BelongsTo ¶
type BelongsTo[P, T any, K comparable] struct { // contains filtered or unexported fields }
BelongsTo explicitly maps a parent foreign key to one target key.
func MustBelongsTo ¶
func MustBelongsTo[P, T, PV, TV any, K comparable]( parent Table[P], target Table[T], parentForeignKey Column[P, PV], targetKeyColumn Column[T, TV], parentKey func(P) (K, bool), targetKey func(T) (K, bool), assign func(*P, *T), options RelationOptions, ) BelongsTo[P, T, K]
func NewBelongsTo ¶
type BulkInsertBuilder ¶
type BulkInsertBuilder[M any] struct { // contains filtered or unexported fields }
BulkInsertBuilder compiles one PostgreSQL multi-row INSERT ... RETURNING.
func (BulkInsertBuilder[M]) All ¶
func (builder BulkInsertBuilder[M]) All(ctx context.Context, executor Executor) ([]M, error)
All inserts all rows atomically in one statement and maps RETURNING rows.
func (BulkInsertBuilder[M]) Build ¶
func (builder BulkInsertBuilder[M]) Build() (Statement, error)
Build returns deterministic multi-row PostgreSQL SQL. Every row must have the same present column set; assignment order after the first row may differ. Omitted fields do not participate in the shape, while Null and Default do.
type Column ¶
type Column[M, V any] struct { // contains filtered or unexported fields }
Column is a typed reference to a column belonging to one generated model.
func MustColumn ¶
MustColumn is intended for package-level generated declarations.
func (Column[M, V]) From ¶
func (column Column[M, V]) From(field Field[V]) Assignment[M]
From turns a partial Field into an assignment. Omitted fields are ignored.
func (Column[M, V]) In ¶
In copies values so subsequent caller mutation cannot change the predicate. An empty set compiles to FALSE.
func (Column[M, V]) Set ¶
func (column Column[M, V]) Set(value V) Assignment[M]
type ConstraintError ¶
type ConstraintError struct {
Kind ConstraintKind
Constraint string
Code string
Cause error
}
ConstraintError is the driver-neutral shape for a constraint failure.
func (*ConstraintError) Error ¶
func (err *ConstraintError) Error() string
func (*ConstraintError) Is ¶
func (err *ConstraintError) Is(target error) bool
Is exposes a stable errors.Is target while Unwrap retains the native driver error for errors.As.
func (*ConstraintError) Unwrap ¶
func (err *ConstraintError) Unwrap() error
type ConstraintKind ¶
type ConstraintKind string
ConstraintKind classifies database constraint failures. Driver adapters may wrap their native errors in ConstraintError without discarding driver detail.
const ( ConstraintUnique ConstraintKind = "unique" ConstraintForeignKey ConstraintKind = "foreign_key" ConstraintNotNull ConstraintKind = "not_null" ConstraintCheck ConstraintKind = "check" )
type DeleteBuilder ¶
type DeleteBuilder[M any] struct { // contains filtered or unexported fields }
func Delete ¶
func Delete[M any](table Table[M]) DeleteBuilder[M]
func (DeleteBuilder[M]) AllRows ¶
func (builder DeleteBuilder[M]) AllRows() DeleteBuilder[M]
func (DeleteBuilder[M]) Build ¶
func (builder DeleteBuilder[M]) Build() (Statement, error)
func (DeleteBuilder[M]) Where ¶
func (builder DeleteBuilder[M]) Where(predicates ...Predicate[M]) DeleteBuilder[M]
type Executor ¶
type Executor interface {
ExecContext(context.Context, string, ...any) (sql.Result, error)
QueryContext(context.Context, string, ...any) (*sql.Rows, error)
QueryRowContext(context.Context, string, ...any) *sql.Row
}
Executor is implemented by both *sql.DB and *sql.Tx.
func ObserveExecutor ¶
func ObserveExecutor(executor Executor, observer StatementObserver) Executor
ObserveExecutor wraps an Executor without changing its database/sql surface. A nil observer returns the original executor.
type Field ¶
type Field[T any] struct { // contains filtered or unexported fields }
Field represents one partial insert or update field. Its zero value is omitted, so generated change structs remain convenient and safe.
func Value ¶
Value constructs a present non-NULL field, including the zero value of T. Builders reject nil and typed-nil values; use Null for SQL NULL.
func (Field[T]) State ¶
func (field Field[T]) State() FieldState
type FieldState ¶
type FieldState uint8
FieldState distinguishes an omitted field from SQL NULL and a concrete value.
const ( FieldOmitted FieldState = iota FieldNull FieldValue FieldDefault )
type HasMany ¶
type HasMany[P, T any, K comparable] struct { // contains filtered or unexported fields }
HasMany explicitly maps a parent key to an ordered target collection.
func MustHasMany ¶
func MustHasMany[P, T, PV, TV any, K comparable]( parent Table[P], target Table[T], parentKeyColumn Column[P, PV], targetForeignKey Column[T, TV], parentKey func(P) (K, bool), targetForeignKeyValue func(T) (K, bool), assign func(*P, []T), options RelationOptions, ) HasMany[P, T, K]
func NewHasMany ¶
type HasOne ¶
type HasOne[P, T any, K comparable] struct { // contains filtered or unexported fields }
HasOne explicitly maps a parent key to at most one target foreign key.
func MustHasOne ¶
func MustHasOne[P, T, PV, TV any, K comparable]( parent Table[P], target Table[T], parentKeyColumn Column[P, PV], targetForeignKey Column[T, TV], parentKey func(P) (K, bool), targetForeignKeyValue func(T) (K, bool), assign func(*P, *T), options RelationOptions, ) HasOne[P, T, K]
type InsertBuilder ¶
type InsertBuilder[M any] struct { // contains filtered or unexported fields }
func Insert ¶
func Insert[M any](table Table[M]) InsertBuilder[M]
func (InsertBuilder[M]) Build ¶
func (builder InsertBuilder[M]) Build() (Statement, error)
func (InsertBuilder[M]) One ¶
func (builder InsertBuilder[M]) One(ctx context.Context, executor Executor) (M, error)
One inserts and maps the returned model.
func (InsertBuilder[M]) Rows ¶
func (builder InsertBuilder[M]) Rows(rows ...InsertRow[M]) BulkInsertBuilder[M]
Rows starts a bulk insert. It is intentionally incompatible with Values on the same builder so the distinction between a single row and a row set stays visible at the call site.
func (InsertBuilder[M]) Values ¶
func (builder InsertBuilder[M]) Values(assignments ...Assignment[M]) InsertBuilder[M]
type InsertRow ¶
type InsertRow[M any] struct { // contains filtered or unexported fields }
InsertRow is one explicitly shaped row in a bulk insert. Row copies the assignment list so builders remain immutable when callers reuse slices.
func Row ¶
func Row[M any](assignments ...Assignment[M]) InsertRow[M]
Row constructs one typed bulk-insert row.
type ManyToMany ¶
type ManyToMany[P, T any, PK, TK comparable] struct { // contains filtered or unexported fields }
ManyToMany explicitly maps parent and target keys through a generated join table definition. scan reads join-parent-key followed by the target columns.
func MustManyToMany ¶
func MustManyToMany[P, T any, PK, TK comparable]( parent Table[P], target Table[T], parentKeyColumn Column[P, PK], targetKeyColumn Column[T, TK], joinTableName, joinParentColumnName, joinTargetColumnName string, parentKey func(P) (PK, bool), targetKey func(T) (TK, bool), scan func(RowScanner) (PK, T, error), assign func(*P, []T), options RelationOptions, ) ManyToMany[P, T, PK, TK]
func NewManyToMany ¶
func NewManyToMany[P, T any, PK, TK comparable]( parent Table[P], target Table[T], parentKeyColumn Column[P, PK], targetKeyColumn Column[T, TK], joinTableName, joinParentColumnName, joinTargetColumnName string, parentKey func(P) (PK, bool), targetKey func(T) (TK, bool), scan func(RowScanner) (PK, T, error), assign func(*P, []T), options RelationOptions, ) (ManyToMany[P, T, PK, TK], error)
func (ManyToMany[P, T, PK, TK]) Build ¶
func (relation ManyToMany[P, T, PK, TK]) Build(parents []P, scope SelectBuilder[T]) ([]Statement, error)
func (ManyToMany[P, T, PK, TK]) BuildAttach ¶
func (relation ManyToMany[P, T, PK, TK]) BuildAttach(parentKey PK, targetKey TK) (Statement, error)
BuildAttach returns an idempotent PostgreSQL join insert. A unique constraint on the generated join key pair makes duplicate attaches report false; other constraint failures are not swallowed.
func (ManyToMany[P, T, PK, TK]) BuildDetach ¶
func (relation ManyToMany[P, T, PK, TK]) BuildDetach(parentKey PK, targetKey TK) (Statement, error)
BuildDetach always constrains both generated join columns.
func (ManyToMany[P, T, PK, TK]) Load ¶
func (relation ManyToMany[P, T, PK, TK]) Load(ctx context.Context, executor Executor, parents []P, scope SelectBuilder[T]) ([]P, error)
type Mapper ¶
type Mapper[M any] struct { // contains filtered or unexported fields }
Mapper explicitly describes how selected columns become a model. Generated declarations should build it once with NewMapper or MustMapper.
func MustMapper ¶
func MustMapper[M any](columns []string, scan func(RowScanner) (M, error)) Mapper[M]
MustMapper is intended for package-level generated declarations.
type Number ¶
type Number interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
~float32 | ~float64
}
Number is the set of values accepted by Increment.
type Operation ¶
type Operation string
Operation identifies a persistence operation without depending on a driver.
type Order ¶
type Order[M any] struct { // contains filtered or unexported fields }
Order is tied at compile time to one model type.
type PersistenceError ¶
PersistenceError adds operation and table context while preserving Cause for errors.Is and errors.As.
func (*PersistenceError) Error ¶
func (err *PersistenceError) Error() string
func (*PersistenceError) Unwrap ¶
func (err *PersistenceError) Unwrap() error
type Predicate ¶
type Predicate[M any] struct { // contains filtered or unexported fields }
Predicate is tied at compile time to one model type.
func ContainsFold ¶ added in v0.22.0
ContainsFold matches a literal substring using PostgreSQL ILIKE and the database's case/collation rules. Percent, underscore, and backslash are data, not user-controlled pattern syntax. An empty literal matches every non-NULL string. Named string types are supported.
func ContainsFoldNullable ¶ added in v0.22.0
ContainsFoldNullable is ContainsFold for nullable string columns, including pointers to named string types. SQL NULL does not match, and no Go pointer is dereferenced. Use IsNull when NULL itself should match.
type RelationOptions ¶
type RelationOptions struct {
ParameterLimit int
}
RelationOptions controls predictable loader batching. Zero uses PostgreSQL's parameter limit. Smaller values are useful for application-specific budgets.
type RowScanner ¶
RowScanner is the common scanning surface of *sql.Row and *sql.Rows.
type SelectBuilder ¶
type SelectBuilder[M any] struct { // contains filtered or unexported fields }
SelectBuilder is an immutable query for one mapped model.
func Select ¶
func Select[M any](table Table[M]) SelectBuilder[M]
func (SelectBuilder[M]) All ¶
func (builder SelectBuilder[M]) All(ctx context.Context, executor Executor) ([]M, error)
func (SelectBuilder[M]) Build ¶
func (builder SelectBuilder[M]) Build() (Statement, error)
Build returns inspectable PostgreSQL SQL and a copied parameter list.
func (SelectBuilder[M]) BuildCount ¶
func (builder SelectBuilder[M]) BuildCount() (Statement, error)
BuildCount returns the filtered count query; ordering, pagination, and locks intentionally do not affect the total.
func (SelectBuilder[M]) BuildExists ¶
func (builder SelectBuilder[M]) BuildExists() (Statement, error)
BuildExists returns the filtered existence query; ordering, pagination, and locks intentionally do not affect existence.
func (SelectBuilder[M]) First ¶
func (builder SelectBuilder[M]) First(ctx context.Context, executor Executor) (M, error)
func (SelectBuilder[M]) ForShare ¶
func (builder SelectBuilder[M]) ForShare() SelectBuilder[M]
func (SelectBuilder[M]) ForUpdate ¶
func (builder SelectBuilder[M]) ForUpdate() SelectBuilder[M]
func (SelectBuilder[M]) Limit ¶
func (builder SelectBuilder[M]) Limit(limit int) SelectBuilder[M]
func (SelectBuilder[M]) Offset ¶
func (builder SelectBuilder[M]) Offset(offset int) SelectBuilder[M]
func (SelectBuilder[M]) OrderBy ¶
func (builder SelectBuilder[M]) OrderBy(orders ...Order[M]) SelectBuilder[M]
func (SelectBuilder[M]) Where ¶
func (builder SelectBuilder[M]) Where(predicates ...Predicate[M]) SelectBuilder[M]
type Statement ¶
type Statement struct {
// contains filtered or unexported fields
}
Statement is immutable inspectable SQL produced by a builder.
type StatementEvent ¶
type StatementEvent uint8
StatementEvent distinguishes observed queries from observed executions.
const ( StatementQuery StatementEvent = iota StatementExec )
type StatementObserver ¶
type StatementObserver func(context.Context, StatementEvent, Statement)
StatementObserver receives an immutable statement immediately before it is sent to the wrapped Executor. It is intended for query budgets, tracing, and tests; it cannot change execution.
type Table ¶
type Table[M any] struct { // contains filtered or unexported fields }
Table binds a validated generated table name to an explicit mapper.
type TransientError ¶
type TransientError struct {
Kind TransientKind
Code string
Cause error
}
TransientError retains the driver error and provides a stable retry class.
func (*TransientError) Error ¶
func (err *TransientError) Error() string
func (*TransientError) Is ¶
func (err *TransientError) Is(target error) bool
func (*TransientError) Unwrap ¶
func (err *TransientError) Unwrap() error
type TransientKind ¶
type TransientKind string
TransientKind classifies persistence failures callers may safely choose to retry at an application transaction boundary.
const ( TransientSerialization TransientKind = "serialization" TransientDeadlock TransientKind = "deadlock" )
type UpdateBuilder ¶
type UpdateBuilder[M any] struct { // contains filtered or unexported fields }
func Update ¶
func Update[M any](table Table[M]) UpdateBuilder[M]
func (UpdateBuilder[M]) AllRows ¶
func (builder UpdateBuilder[M]) AllRows() UpdateBuilder[M]
AllRows explicitly allows a mutation without predicates.
func (UpdateBuilder[M]) Build ¶
func (builder UpdateBuilder[M]) Build() (Statement, error)
func (UpdateBuilder[M]) BuildReturning ¶
func (builder UpdateBuilder[M]) BuildReturning() (Statement, error)
BuildReturning adds an atomic PostgreSQL RETURNING clause for the mapped model. Generated repositories use this instead of update-then-select.
func (UpdateBuilder[M]) One ¶
func (builder UpdateBuilder[M]) One(ctx context.Context, executor Executor) (M, error)
One updates and returns one model atomically. The caller must supply predicates that identify at most one row; PostgreSQL applies the update to every match before database/sql returns the first RETURNING row. A no-row result is ErrNotFound, or ErrStale only when StaleOnZero was explicitly selected by generated code.
func (UpdateBuilder[M]) OptimisticVersion ¶
func (builder UpdateBuilder[M]) OptimisticVersion(guard VersionGuard[M]) UpdateBuilder[M]
OptimisticVersion atomically adds both halves of an ExpectVersion guard to this immutable builder. It deliberately does not enable StaleOnZero: a zero match may be caused by any other predicate, including tenant or ownership scope. Generated repositories may add StaleOnZero only after they have made that distinction explicitly.
func (UpdateBuilder[M]) Set ¶
func (builder UpdateBuilder[M]) Set(assignments ...Assignment[M]) UpdateBuilder[M]
func (UpdateBuilder[M]) StaleOnZero ¶
func (builder UpdateBuilder[M]) StaleOnZero() UpdateBuilder[M]
StaleOnZero makes a zero-row optimistic update return ErrStale. Generated owner-scoped repositories must preserve wrong-owner and missing rows as ErrNotFound rather than enabling this directly on an ownership predicate.
func (UpdateBuilder[M]) Where ¶
func (builder UpdateBuilder[M]) Where(predicates ...Predicate[M]) UpdateBuilder[M]
type VersionGuard ¶
type VersionGuard[M any] struct { // contains filtered or unexported fields }
VersionGuard is a generated-only optimistic-version predicate and increment pair. Construct it with ExpectVersion rather than assembling the two halves independently.
func ExpectVersion ¶
func ExpectVersion[M any, V Number](column Column[M, V], expected V) VersionGuard[M]
ExpectVersion requires the current version and increments it by one in the same UPDATE statement. The expected value remains a bound argument.