Documentation
¶
Overview ¶
Package operation is the base module's contract layer: constructors shaped by what a consumer means to do, lowering to rendered statements from the ast package's vocabulary. The query side is a Projection of name-to-expression fields with its two queries — Projection.List lowers Directives of page, sort, and operator-keyed filters into a count-and-page pair over one WHERE clause, and Projection.One forms the single-row read. The command side is Insertion, GuardedUpdate, and GuardedDelete: the identity-returning insert and the two optimistic-concurrency commands, each lowering through its SQL method. The exec package runs what this layer produces.
The field contract ¶
Directives reference a projection's field names, never SQL. An unknown name or operator is a typed error — UnknownFieldError, UnknownOperatorError — the consumer maps to its own response, and the projection's key field joins every ORDER BY as the tie-breaker, so offset paging is stable.
The guard contract ¶
A guarded command matches its row by key and expected version and increments the version itself, so the new version is deterministic. The Guard names the consumer's version column — the library fixes the mechanism, never the schema — and the Guarded pair keeps the contract in pure standard SQL: the command first, the check only when no row was touched, splitting not-found from version-mismatch. Insertion is the one command needing a dialect capability: its returning clause renders only through ast.ReturningRenderer and fails typed without it.
Index ¶
- func Columns(prefix string, names []string, extra ...ast.Column) []ast.Column
- type Directives
- type Field
- type FieldUse
- type Filter
- type Guard
- type Guarded
- type GuardedDelete
- type GuardedUpdate
- type Insertion
- type List
- type Op
- type Page
- type Projection
- type RecursivePath
- type Sort
- type UnknownFieldError
- type UnknownOperatorError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Directives ¶
Directives is one read request against a projection. Filters and Sort reference projected field names — an unknown name is an UnknownFieldError, never SQL. Where optionally carries a composed [Predicate] beyond the field vocabulary, ANDed with the filters: the door back down to the composition core.
type Field ¶
type Field struct {
Name string
Expr ast.Expression
}
Field is the contract layer's shared field vocabulary: a contract name and the expression that computes it. Both CQRS sides speak it — a projection's key and fields on the query side, a command's identity on the command side.
type FieldUse ¶
type FieldUse string
FieldUse names the directive position where a projected field was referenced, carried by UnknownFieldError.
type Filter ¶
Filter is one filter directive: a projected field name, an operator, and the value. OpIsNull and OpIsNotNull ignore Value; OpIn requires Value to be a []any.
type Guard ¶
Guard is the optimistic-concurrency spec: the consumer's version column — a schema decision the library never fixes — and the version the caller expects. Within a guarded command the contract manages that column exclusively: the guard appends the increment itself and rejects a caller assignment to it, which is what makes the new version deterministic.
type Guarded ¶
Guarded is a guarded command's envelope: the command statement, run first, and the check statement, run only when the command touched no row, splitting not-found from version-mismatch. Both are pure standard SQL; the runner in the exec package is the contract and this portable pair sits behind it.
type GuardedDelete ¶
GuardedDelete is the guarded delete command: the row goes only when both the key and the expected version match.
type GuardedUpdate ¶
GuardedUpdate is the guarded update command: SET under the key and version guard, the version increment appended by the guard itself.
type Insertion ¶
type Insertion struct {
Into string
Values []ast.Assignment
Identity Field
Version Field
}
Insertion is the identity-returning insert command: one row of values, with the engine handing back the caller-named identity and version fields it minted. It lowers through the write statements' Returning clause, so it requires a dialect implementing ast.ReturningRenderer and fails typed otherwise. Which columns exist, including what the version column is called, is the consumer's schema decision.
type List ¶
List is the list query's envelope: the count and page statements over one shared WHERE clause. The consumer runs both — Count for the total, Page for the rows — and they can never disagree.
type Op ¶
type Op string
Op is a filter directive's operator. The values are short strings so a read contract can carry them verbatim.
type Page ¶
Page is the 1-based page directive of a read: which page, and how many rows per page. Both fields must be at least 1.
type Projection ¶
Projection is a read model over one FROM: name-to-expression fields, one key field, and the CTEs the FROM references. It is plain data; every read against it goes through the query operations Projection.List and Projection.One. The key field is the identity a read pages by — it joins every ORDER BY as the tie-breaker, so offset paging is stable. CTEs declared here hoist to the top of every generated statement, the one placement every engine accepts.
func (Projection) List ¶
func (p Projection) List(d database.Dialect, dir Directives) (List, error)
List forms the list query, lowering the directives onto the projection: field names resolve to expressions or fail with UnknownFieldError, filters become the shared WHERE clause, sorts gain the key tie-breaker whenever the caller didn't sort by it, and the page directive becomes bound offset/fetch arguments.
func (Projection) One ¶
One forms the single-row query: the full projection under one equality filter on a projected field, with no ordering, no paging, and no count. An unknown field is an UnknownFieldError. When the filtered field is not unique, the first row wins; execution outcomes, sql.ErrNoRows included, belong to the runner.
type RecursivePath ¶
type RecursivePath struct {
Table string
Key string
Parent string
Segment string
Field string
Separator string
Rooted bool
Columns []string
}
RecursivePath is a computed-field pattern: a self-referencing table whose rows compose a path by walking the parent chain — Segment joined by Separator, prefixed with it when Rooted ("/acme/engineering"; unrooted, "v1.data.reads"). Parent names the self-reference, Key the column it joins, and Columns the carried set, Key included, in scan order.
func (RecursivePath) Projection ¶
func (r RecursivePath) Projection() Projection
Projection builds the pattern's whole read model: a recursive CTE (standard SQL:1999) re-presenting the table with Field as one extra column, and the projection reading from it — Key first, the carried columns, Field last. The pattern owns the full projection because the CTE replaces the FROM and already requires every input the projection needs; a consumer composing several computed fields would decompose this into projection transformers each contributing a CTE and a field, a seam recorded in the design notes and not yet built. An empty Separator panics as a wiring mistake.
type UnknownFieldError ¶
UnknownFieldError reports a sort or filter directive naming a field the projection does not declare. It is the field contract's boundary: the name never reaches the SQL, and a consumer maps the error to its own response with errors.As.
func (*UnknownFieldError) Error ¶
func (e *UnknownFieldError) Error() string
type UnknownOperatorError ¶
type UnknownOperatorError struct {
Op Op
}
UnknownOperatorError reports a filter directive carrying an operator the vocabulary does not define, mapped by the consumer the same way as UnknownFieldError.
func (*UnknownOperatorError) Error ¶
func (e *UnknownOperatorError) Error() string