Documentation
¶
Overview ¶
Package database supplies advisory typed model validation. It reuses the query compiler and leaves the base validation package independent of SQL. Import it as databasevalidation alongside the database runtime package.
Index ¶
- func Exists[M any, V comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V]) validation.Rule[V]
- func ExistsAll[M any, V comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V]) validation.Rule[[]V]
- func ExistsEach[E, M any, V comparable](executor database.Executor, source orm.Query[M], column orm.KeyColumn[M, V], ...) validation.Rule[[]E]
- func Unique[M any, V comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V]) validation.Rule[V]
- func UniqueAll[M any, V comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V]) validation.Rule[[]V]
- func UniqueEach[E, M any, V comparable](executor database.Executor, source orm.Query[M], column orm.KeyColumn[M, V], ...) validation.Rule[[]E]
- func UniqueIgnoring[M any, V, K comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V], ...) validation.Rule[V]
- type ModelLookup
- func (l ModelLookup[M, V]) AllExist(ctx context.Context, input []V) (bool, error)
- func (l ModelLookup[M, V]) AnyExist(ctx context.Context, input []V) (bool, error)
- func (l ModelLookup[M, V]) Exists(ctx context.Context, input V) (bool, error)
- func (l ModelLookup[M, V]) Format(s fmt.State, _ rune)
- func (l ModelLookup[M, V]) GoString() string
- func (ModelLookup[M, V]) String() string
- func (l ModelLookup[M, V]) Validate() error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Exists ¶
func Exists[M any, V comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V]) validation.Rule[V]
Exists requires a stored value in the supplied model scope. The declared source and field must share a model owner, and input retains the field type. Example: databasevalidation.Exists(db, Users.Query(), orm.KeyExpr(Users.Key())).
func ExistsAll ¶
func ExistsAll[M any, V comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V]) validation.Rule[[]V]
ExistsAll validates a list with bounded database batches, preserving the model scope and concrete field type. Missing values are reported at their index paths. Duplicate input values are allowed; combine with Distinct when the application prohibits duplicates. Example: databasevalidation.ExistsAll(db, Users.Query(), orm.KeyExpr(Users.Key())).
func ExistsEach ¶
func ExistsEach[E, M any, V comparable](executor database.Executor, source orm.Query[M], column orm.KeyColumn[M, V], item validation.Field[E, V]) validation.Rule[[]E]
ExistsEach selects item from every element, for example each order line's product ID, and checks all selected values with batched statements. Missing values are reported at paths such as /items/3/product_id. Example: databasevalidation.ExistsEach(db, Users.Query(), orm.KeyExpr(Users.Key()), assignee).
func Unique ¶
func Unique[M any, V comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V]) validation.Rule[V]
Unique requires no matching value in the supplied model scope. For updates, use UniqueIgnoring, or exclude the current row with its typed primary-key predicate before passing the source. Include trashed rows when the database unique constraint does. This read does not reserve a value or replace the database constraint. Example: databasevalidation.Unique(db, Users.Query(), orm.TextExpr(Users.Email)).
func UniqueAll ¶
func UniqueAll[M any, V comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V]) validation.Rule[[]V]
UniqueAll requires that no listed value is stored in the scope, reporting each conflict at its index path with batched IN observations. Example: databasevalidation.UniqueAll(db, Users.Query(), orm.TextExpr(Users.Email)).
func UniqueEach ¶
func UniqueEach[E, M any, V comparable](executor database.Executor, source orm.Query[M], column orm.KeyColumn[M, V], item validation.Field[E, V]) validation.Rule[[]E]
UniqueEach requires that no element's selected value is stored in the scope, reporting conflicts at each element's field path. Example: databasevalidation.UniqueEach(db, Users.Query(), orm.TextExpr(Users.Email), email).
func UniqueIgnoring ¶
func UniqueIgnoring[M any, V, K comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V], key orm.KeyColumn[M, K], current validation.Slot[K]) validation.Rule[V]
UniqueIgnoring requires no other stored row with the value, excluding the row whose key the enclosing validation.Provide supplies through current, such as the route key of the record being updated. The exclusion is derived at check time, so one declaration serves every request. validation.ValidateRule rejects the rule until an enclosing Provide supplies current. Derive that key from trusted route or actor data, never from an untrusted body field alone. Example: databasevalidation.UniqueIgnoring(db, Users.Query(), orm.TextExpr(Users.Email), orm.KeyExpr(Users.Key()), current).
Types ¶
type ModelLookup ¶
type ModelLookup[M any, V comparable] struct { // contains filtered or unexported fields }
ModelLookup observes one stored model field for the base validation rules: it implements validation.Lookup, BatchLookup and AnyLookup. Construct it with Lookup for a fixed scope or Scoped for a scope derived at check time. Example: lookup := databasevalidation.Lookup(db, Users.Query(), orm.TextExpr(Users.Email)).
func Lookup ¶
func Lookup[M any, V comparable](executor database.Executor, source orm.Query[M], field orm.KeyColumn[M, V]) ModelLookup[M, V]
Lookup binds a fixed declared model scope and field. Example: databasevalidation.Lookup(db, Users.Query(), orm.TextExpr(Users.Email)).
func Scoped ¶
func Scoped[M any, V comparable](executor database.Executor, scope func(context.Context) (orm.Query[M], error), field orm.KeyColumn[M, V]) ModelLookup[M, V]
Scoped derives the model scope at every check, for example filtering by the tenant of the request's authenticated actor or by a validation.Slot value. The scope function must return a fresh unpaginated scope without ordering or eager loading; an invalid scope or a scope error fails execution and is never treated as a missing or available value. Declaration validation checks the executor and callback only; each check validates the returned scope. Example: databasevalidation.Scoped(db, tenantUsers, orm.TextExpr(Users.Email)).
func (ModelLookup[M, V]) AllExist ¶
func (l ModelLookup[M, V]) AllExist(ctx context.Context, input []V) (bool, error)
AllExist checks all supplied values in bounded batches. Example: lookup.AllExist(ctx, input).
func (ModelLookup[M, V]) AnyExist ¶
func (l ModelLookup[M, V]) AnyExist(ctx context.Context, input []V) (bool, error)
AnyExist checks for any stored conflict in bounded batches. Example: lookup.AnyExist(ctx, input).
func (ModelLookup[M, V]) Exists ¶
func (l ModelLookup[M, V]) Exists(ctx context.Context, input V) (bool, error)
Exists observes one value. Example: lookup.Exists(ctx, input).
func (ModelLookup[M, V]) Format ¶
func (l ModelLookup[M, V]) Format(s fmt.State, _ rune)
Format redacts every formatting verb. Example: fmt.Sprintf("%+v", lookup).
func (ModelLookup[M, V]) GoString ¶
func (l ModelLookup[M, V]) GoString() string
GoString redacts Go-syntax diagnostics. Example: fmt.Sprintf("%#v", lookup).
func (ModelLookup[M, V]) String ¶
func (ModelLookup[M, V]) String() string
String redacts retained scope values. Example: fmt.Sprint(lookup).
func (ModelLookup[M, V]) Validate ¶
func (l ModelLookup[M, V]) Validate() error
Validate checks the declaration without I/O. Example: lookup.Validate().