| title | API Reference | ||||
|---|---|---|---|---|---|
| description | Complete API reference for the soy package | ||||
| author | zoobzio | ||||
| published | 2025-12-15 | ||||
| updated | 2025-12-19 | ||||
| tags |
|
Complete API reference for the github.com/zoobz-io/soy package.
The main coordinator type. Create one per table.
func New[T any](db *sqlx.DB, tableName string, renderer astql.Renderer) (*Soy[T], error)Creates a new soy instance for the given struct type and table name with the specified SQL renderer. Inspects struct tags, builds schema, and caches metadata.
Available renderers from github.com/zoobz-io/astql/pkg:
postgres.New()- PostgreSQLmariadb.New()- MariaDBsqlite.New()- SQLitemssql.New()- Microsoft SQL Server
func (c *Soy[T]) Select() *Select[T]Returns a builder for single-record SELECT queries.
func (c *Soy[T]) Query() *Query[T]Returns a builder for multi-record SELECT queries.
func (c *Soy[T]) Insert() *Create[T]Returns a builder for INSERT operations.
func (c *Soy[T]) Modify() *Update[T]Returns a builder for UPDATE operations.
func (c *Soy[T]) Remove() *Delete[T]Returns a builder for DELETE operations.
func (c *Soy[T]) Count() *Aggregate[T]Returns a builder for COUNT(*) aggregates.
func (c *Soy[T]) Sum(field string) *Aggregate[T]Returns a builder for SUM aggregates on the specified field.
func (c *Soy[T]) Avg(field string) *Aggregate[T]Returns a builder for AVG aggregates on the specified field.
func (c *Soy[T]) Min(field string) *Aggregate[T]Returns a builder for MIN aggregates on the specified field.
func (c *Soy[T]) Max(field string) *Aggregate[T]Returns a builder for MAX aggregates on the specified field.
func (c *Soy[T]) OnScan(fn func(ctx context.Context, result *T) error)Registers a callback that fires after scanning a row into *T. Called in Select, Query, Update, Create, and Compound execution paths. Pass nil to unregister.
func (c *Soy[T]) OnRecord(fn func(ctx context.Context, record *T) error)Registers a callback that fires before writing a *T. Called in Create execution paths (single insert, batch insert, upsert) before the INSERT is executed. Pass nil to unregister.
func (c *Soy[T]) QueryFromSpec(spec QuerySpec) *Query[T]Creates a Query builder from a JSON-serializable spec.
func (c *Soy[T]) SelectFromSpec(spec SelectSpec) *Select[T]Creates a Select builder from a JSON-serializable spec.
func (c *Soy[T]) InsertFromSpec(spec CreateSpec) *Create[T]Creates a Create builder from a JSON-serializable spec.
func (c *Soy[T]) ModifyFromSpec(spec UpdateSpec) *Update[T]Creates an Update builder from a JSON-serializable spec.
func (c *Soy[T]) RemoveFromSpec(spec DeleteSpec) *Delete[T]Creates a Delete builder from a JSON-serializable spec.
func (c *Soy[T]) CountFromSpec(spec AggregateSpec) *Aggregate[T]Creates a COUNT aggregate from a spec.
func (c *Soy[T]) SumFromSpec(spec AggregateSpec) *Aggregate[T]Creates a SUM aggregate from a spec. Uses spec.Field as the column to sum.
func (c *Soy[T]) AvgFromSpec(spec AggregateSpec) *Aggregate[T]Creates an AVG aggregate from a spec. Uses spec.Field as the column to average.
func (c *Soy[T]) MinFromSpec(spec AggregateSpec) *Aggregate[T]Creates a MIN aggregate from a spec. Uses spec.Field as the column.
func (c *Soy[T]) MaxFromSpec(spec AggregateSpec) *Aggregate[T]Creates a MAX aggregate from a spec. Uses spec.Field as the column.
func (c *Soy[T]) CompoundFromSpec(spec CompoundQuerySpec) *Compound[T]Creates a Compound builder from a JSON-serializable spec.
Builder for single-record SELECT queries.
func (s *Select[T]) Fields(fields ...string) *Select[T]Selects specific columns. Returns all columns if not called.
func (s *Select[T]) Where(field, operator, param string) *Select[T]Adds a WHERE condition. Multiple calls produce AND.
func (s *Select[T]) WhereAnd(conditions ...Condition) *Select[T]Adds grouped AND conditions.
func (s *Select[T]) WhereOr(conditions ...Condition) *Select[T]Adds grouped OR conditions.
func (s *Select[T]) WhereNull(field string) *Select[T]Adds IS NULL condition.
func (s *Select[T]) WhereNotNull(field string) *Select[T]Adds IS NOT NULL condition.
func (s *Select[T]) WhereBetween(field, lowParam, highParam string) *Select[T]Adds a WHERE field BETWEEN low AND high condition.
func (s *Select[T]) WhereNotBetween(field, lowParam, highParam string) *Select[T]Adds a WHERE field NOT BETWEEN low AND high condition.
func (s *Select[T]) WhereFields(leftField, operator, rightField string) *Select[T]Adds a WHERE condition comparing two fields (e.g., WHERE "created_at" < "updated_at").
func (s *Select[T]) OrderBy(field, direction string) *Select[T]Adds ORDER BY clause. Direction: "asc" or "desc".
func (s *Select[T]) OrderByNulls(field, direction, nulls string) *Select[T]Adds ORDER BY with NULLS FIRST or NULLS LAST. The nulls parameter must be "first" or "last" (case insensitive).
func (s *Select[T]) OrderByExpr(field, operator, param, direction string) *Select[T]Adds ORDER BY with expression (e.g., for pgvector).
func (s *Select[T]) Distinct() *Select[T]Adds DISTINCT clause.
func (s *Select[T]) DistinctOn(fields ...string) *Select[T]Adds DISTINCT ON clause (PostgreSQL).
func (s *Select[T]) GroupBy(fields ...string) *Select[T]Adds GROUP BY clause.
func (s *Select[T]) Having(field, operator, param string) *Select[T]Adds HAVING condition.
func (s *Select[T]) HavingAgg(function, field, operator, param string) *Select[T]Adds HAVING with aggregate function.
func (s *Select[T]) ForUpdate() *Select[T]Adds FOR UPDATE lock.
func (s *Select[T]) ForNoKeyUpdate() *Select[T]Adds FOR NO KEY UPDATE lock.
func (s *Select[T]) ForShare() *Select[T]Adds FOR SHARE lock.
func (s *Select[T]) ForKeyShare() *Select[T]Adds FOR KEY SHARE lock.
func (s *Select[T]) Exec(ctx context.Context, params map[string]any) (*T, error)Executes the query and returns a single result. Returns an error if no rows found.
func (s *Select[T]) ExecTx(ctx context.Context, tx *sqlx.Tx, params map[string]any) (*T, error)Executes within a transaction.
func (s *Select[T]) ExecAtom(ctx context.Context, params map[string]any) (*atom.Atom, error)Executes the query and scans the result directly into an *atom.Atom. Returns an error if no rows found.
func (s *Select[T]) ExecTxAtom(ctx context.Context, tx *sqlx.Tx, params map[string]any) (*atom.Atom, error)Executes within a transaction and returns an *atom.Atom.
func (s *Select[T]) Render() (*astql.QueryResult, error)Returns the generated SQL as a QueryResult without executing. The QueryResult contains the SQL string and parameter information.
func (s *Select[T]) MustRender() *astql.QueryResultLike Render but panics on error.
Builder for multi-record SELECT queries. Inherits all Select methods plus:
func (q *Query[T]) Limit(n int) *Query[T]Sets the maximum number of rows to return (static value).
func (q *Query[T]) LimitParam(param string) *Query[T]Sets the LIMIT clause to a parameterized value. Useful for API pagination where limit comes from request parameters.
func (q *Query[T]) Offset(n int) *Query[T]Sets the number of rows to skip (static value).
func (q *Query[T]) OffsetParam(param string) *Query[T]Sets the OFFSET clause to a parameterized value. Useful for API pagination where offset comes from request parameters.
func (q *Query[T]) Union(other *Query[T]) *Compound[T]Combines with another query using UNION.
func (q *Query[T]) UnionAll(other *Query[T]) *Compound[T]Combines using UNION ALL.
func (q *Query[T]) Intersect(other *Query[T]) *Compound[T]Combines using INTERSECT.
func (q *Query[T]) IntersectAll(other *Query[T]) *Compound[T]Combines using INTERSECT ALL.
func (q *Query[T]) Except(other *Query[T]) *Compound[T]Combines using EXCEPT.
func (q *Query[T]) ExceptAll(other *Query[T]) *Compound[T]Combines using EXCEPT ALL.
func (q *Query[T]) Exec(ctx context.Context, params map[string]any) ([]*T, error)Executes and returns all matching rows.
func (q *Query[T]) ExecTx(ctx context.Context, tx *sqlx.Tx, params map[string]any) ([]*T, error)Executes within a transaction.
func (q *Query[T]) ExecAtom(ctx context.Context, params map[string]any) ([]*atom.Atom, error)Executes the query and scans all results directly into []*atom.Atom. Returns nil for empty results.
func (q *Query[T]) ExecTxAtom(ctx context.Context, tx *sqlx.Tx, params map[string]any) ([]*atom.Atom, error)Executes within a transaction and returns []*atom.Atom.
Builder for compound queries with set operations.
Inherits ordering and pagination methods from Query, plus:
func (c *Compound[T]) Union(other *Query[T]) *Compound[T]Chains additional set operations.
Applied to the final combined result.
func (c *Compound[T]) Exec(ctx context.Context, params map[string]any) ([]*T, error)Builder for INSERT operations.
func (c *Create[T]) OnConflict(columns ...string) *Create[T]Specifies conflict columns for ON CONFLICT handling.
func (c *Create[T]) DoNothing() *Create[T]Sets ON CONFLICT DO NOTHING.
func (c *Create[T]) DoUpdate() *Create[T]Sets ON CONFLICT DO UPDATE.
func (c *Create[T]) Set(field, param string) *Create[T]Adds a SET clause for DO UPDATE.
func (c *Create[T]) Build() *Create[T]Finalises the builder.
func (c *Create[T]) Exec(ctx context.Context, record *T) (*T, error)Inserts a single record and returns the result with RETURNING.
func (c *Create[T]) ExecTx(ctx context.Context, tx *sqlx.Tx, record *T) (*T, error)Inserts within a transaction.
func (c *Create[T]) ExecAtom(ctx context.Context, params map[string]any) (*atom.Atom, error)Inserts a record using a parameter map and returns the result as *atom.Atom. Requires all non-primary-key columns to be provided in params.
func (c *Create[T]) ExecTxAtom(ctx context.Context, tx *sqlx.Tx, params map[string]any) (*atom.Atom, error)Inserts within a transaction and returns an *atom.Atom.
func (c *Create[T]) ExecBatch(ctx context.Context, records []*T) (int64, error)Inserts multiple records and returns the count of records inserted.
Builder for UPDATE operations.
func (u *Update[T]) Set(field, param string) *Update[T]Adds a column to update.
func (u *Update[T]) SetExpr(field, operator, param string) *Update[T]Adds a computed assignment using a binary expression: field = field <op> param. Use for atomic increments, decrements, and similar operations. Supported operators: +, -, *, /, %.
Same as Select. At least one WHERE is required.
func (u *Update[T]) Exec(ctx context.Context, params map[string]any) (*T, error)Executes and returns the updated record. Returns error if no WHERE clause.
func (u *Update[T]) ExecTx(ctx context.Context, tx *sqlx.Tx, params map[string]any) (*T, error)func (u *Update[T]) ExecBatch(ctx context.Context, paramsList []map[string]any) (int64, error)Updates multiple records with different parameter sets.
Builder for DELETE operations.
Same as Select. At least one WHERE is required.
func (d *Delete[T]) Exec(ctx context.Context, params map[string]any) (int64, error)Executes and returns rows affected. Returns error if no WHERE clause.
func (d *Delete[T]) ExecTx(ctx context.Context, tx *sqlx.Tx, params map[string]any) (int64, error)func (d *Delete[T]) ExecBatch(ctx context.Context, paramsList []map[string]any) (int64, error)Builder for aggregate queries.
Same as Select.
func (a *Aggregate[T]) Exec(ctx context.Context, params map[string]any) (float64, error)Returns the aggregate result. NULL results return 0.0.
func (a *Aggregate[T]) ExecTx(ctx context.Context, tx *sqlx.Tx, params map[string]any) (float64, error)func C(field, operator, param string) ConditionCreates a simple condition.
func Null(field string) ConditionCreates an IS NULL condition.
func NotNull(field string) ConditionCreates an IS NOT NULL condition.
JSON-serializable query definitions.
type QuerySpec struct {
Fields []string `json:"fields,omitempty"`
Where []ConditionSpec `json:"where,omitempty"`
OrderBy []OrderBySpec `json:"order_by,omitempty"`
GroupBy []string `json:"group_by,omitempty"`
Having []ConditionSpec `json:"having,omitempty"`
HavingAgg []HavingAggSpec `json:"having_agg,omitempty"`
Limit *int `json:"limit,omitempty"`
Offset *int `json:"offset,omitempty"`
Distinct bool `json:"distinct,omitempty"`
DistinctOn []string `json:"distinct_on,omitempty"`
ForLocking string `json:"for_locking,omitempty"` // "update", "no_key_update", "share", "key_share"
}type SelectSpec struct {
Fields []string `json:"fields,omitempty"`
Where []ConditionSpec `json:"where,omitempty"`
OrderBy []OrderBySpec `json:"order_by,omitempty"`
GroupBy []string `json:"group_by,omitempty"`
Having []ConditionSpec `json:"having,omitempty"`
HavingAgg []HavingAggSpec `json:"having_agg,omitempty"`
Limit *int `json:"limit,omitempty"`
Offset *int `json:"offset,omitempty"`
Distinct bool `json:"distinct,omitempty"`
DistinctOn []string `json:"distinct_on,omitempty"`
ForLocking string `json:"for_locking,omitempty"` // "update", "no_key_update", "share", "key_share"
}type ConditionSpec struct {
// Simple condition fields
Field string `json:"field,omitempty"`
Operator string `json:"operator,omitempty"`
Param string `json:"param,omitempty"`
IsNull bool `json:"is_null,omitempty"`
// Condition group fields (for AND/OR grouping)
Logic string `json:"logic,omitempty"` // "AND" or "OR"
Group []ConditionSpec `json:"group,omitempty"` // Nested conditions
}type OrderBySpec struct {
Field string `json:"field"`
Direction string `json:"direction"` // "asc" or "desc"
Nulls string `json:"nulls,omitempty"` // "first" or "last" for NULLS FIRST/LAST
Operator string `json:"operator,omitempty"` // For vector ops: "<->", "<#>", "<=>", "<+>"
Param string `json:"param,omitempty"` // Parameter for expression-based ordering
}type HavingAggSpec struct {
Func string `json:"func"` // "count", "sum", "avg", "min", "max", "count_distinct"
Field string `json:"field,omitempty"` // Field to aggregate (empty for COUNT(*))
Operator string `json:"operator"` // Comparison operator
Param string `json:"param"` // Parameter name for comparison value
}type CreateSpec struct {
OnConflict []string `json:"on_conflict,omitempty"` // Conflict columns
ConflictAction string `json:"conflict_action,omitempty"` // "nothing" or "update"
ConflictSet map[string]string `json:"conflict_set,omitempty"` // Fields to update on conflict
}type UpdateSpec struct {
Set map[string]string `json:"set"`
Where []ConditionSpec `json:"where"`
}type DeleteSpec struct {
Where []ConditionSpec `json:"where"`
}type AggregateSpec struct {
Field string `json:"field,omitempty"` // Required for SUM/AVG/MIN/MAX, not used for COUNT
Where []ConditionSpec `json:"where,omitempty"`
}The aggregate function is determined by which method you call (CountFromSpec, SumFromSpec, etc.), not by a field in the spec.
type CompoundQuerySpec struct {
Base QuerySpec `json:"base"`
Operands []SetOperandSpec `json:"operands"`
OrderBy []OrderBySpec `json:"order_by,omitempty"`
Limit *int `json:"limit,omitempty"`
Offset *int `json:"offset,omitempty"`
}type SetOperandSpec struct {
Operation string `json:"operation"`
Query QuerySpec `json:"query"`
}Operations: "union", "union_all", "intersect", "intersect_all", "except", "except_all"
| Tag | Purpose | Example |
|---|---|---|
db |
Column name | db:"email" |
type |
SQL column type | type:"text", type:"serial", type:"vector(1536)" |
constraints |
Column constraints | constraints:"primary key", constraints:"not null unique" |
default |
Default value | default:"now()", default:"0" |
check |
Check constraint | check:"age >= 0" |
index |
Create index | index:"true" |
references |
Foreign key | references:"users(id)" |
| Operator | Description |
|---|---|
= |
Equals |
!= |
Not equals |
> |
Greater than |
>= |
Greater than or equal |
< |
Less than |
<= |
Less than or equal |
| Operator | Description |
|---|---|
LIKE |
Case-sensitive pattern |
NOT LIKE |
Negated LIKE |
ILIKE |
Case-insensitive pattern |
NOT ILIKE |
Negated ILIKE |
| Operator | Description |
|---|---|
IN |
Value in list |
NOT IN |
Value not in list |
| Operator | Description |
|---|---|
~ |
Case-sensitive regex |
~* |
Case-insensitive regex |
!~ |
Negated regex |
!~* |
Negated case-insensitive regex |
| Operator | Description |
|---|---|
@> |
Contains |
<@ |
Contained by |
&& |
Overlap |
| Operator | Description |
|---|---|
<-> |
L2 (Euclidean) distance |
<#> |
Inner product distance |
<=> |
Cosine distance |
<+> |
L1 (Manhattan) distance |
| Operator | Description |
|---|---|
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
/ |
Division |
% |
Modulo |
Used with SetExpr for computed UPDATE assignments.
Select and Query builders support expression methods for adding computed columns to SELECT clauses.
| Method | SQL Output |
|---|---|
SelectUpper(field, alias) |
UPPER("field") AS "alias" |
SelectLower(field, alias) |
LOWER("field") AS "alias" |
SelectLength(field, alias) |
LENGTH("field") AS "alias" |
SelectTrim(field, alias) |
TRIM("field") AS "alias" |
SelectLTrim(field, alias) |
LTRIM("field") AS "alias" |
SelectRTrim(field, alias) |
RTRIM("field") AS "alias" |
SelectSubstring(field, startParam, lengthParam, alias) |
SUBSTRING("field", :start, :length) AS "alias" |
SelectReplace(field, searchParam, replaceParam, alias) |
REPLACE("field", :search, :replace) AS "alias" |
SelectConcat(alias, fields...) |
CONCAT("field1", "field2") AS "alias" |
| Method | SQL Output |
|---|---|
SelectAbs(field, alias) |
ABS("field") AS "alias" |
SelectCeil(field, alias) |
CEIL("field") AS "alias" |
SelectFloor(field, alias) |
FLOOR("field") AS "alias" |
SelectRound(field, alias) |
ROUND("field") AS "alias" |
SelectSqrt(field, alias) |
SQRT("field") AS "alias" |
SelectPower(field, exponentParam, alias) |
POWER("field", :exp) AS "alias" |
| Method | SQL Output |
|---|---|
SelectNow(alias) |
NOW() AS "alias" |
SelectCurrentDate(alias) |
CURRENT_DATE AS "alias" |
SelectCurrentTime(alias) |
CURRENT_TIME AS "alias" |
SelectCurrentTimestamp(alias) |
CURRENT_TIMESTAMP AS "alias" |
| Method | SQL Output |
|---|---|
SelectCoalesce(alias, params...) |
COALESCE(:p1, :p2, ...) AS "alias" |
SelectNullIf(param1, param2, alias) |
NULLIF(:p1, :p2) AS "alias" |
func (s *Select[T]) SelectCast(field, castType, alias string) *Select[T]Cast types: text, integer, bigint, smallint, numeric, real, double precision, boolean, date, time, timestamp, timestamptz, interval, uuid, json, jsonb, bytea.
| Method | SQL Output |
|---|---|
SelectSum(field, alias) |
SUM("field") AS "alias" |
SelectAvg(field, alias) |
AVG("field") AS "alias" |
SelectMin(field, alias) |
MIN("field") AS "alias" |
SelectMax(field, alias) |
MAX("field") AS "alias" |
SelectCount(field, alias) |
COUNT("field") AS "alias" |
SelectCountStar(alias) |
COUNT(*) AS "alias" |
SelectCountDistinct(field, alias) |
COUNT(DISTINCT "field") AS "alias" |
Aggregate with FILTER clause for conditional aggregation:
| Method | SQL Output |
|---|---|
SelectSumFilter(field, condField, condOp, condParam, alias) |
SUM("field") FILTER (WHERE "condField" op :param) AS "alias" |
SelectAvgFilter(field, condField, condOp, condParam, alias) |
AVG("field") FILTER (WHERE ...) AS "alias" |
SelectMinFilter(field, condField, condOp, condParam, alias) |
MIN("field") FILTER (WHERE ...) AS "alias" |
SelectMaxFilter(field, condField, condOp, condParam, alias) |
MAX("field") FILTER (WHERE ...) AS "alias" |
SelectCountFilter(field, condField, condOp, condParam, alias) |
COUNT("field") FILTER (WHERE ...) AS "alias" |
SelectCountDistinctFilter(field, condField, condOp, condParam, alias) |
COUNT(DISTINCT "field") FILTER (WHERE ...) AS "alias" |
Build SQL CASE expressions with a fluent API:
result, err := soy.Select().
Fields("id", "name").
SelectCase().
When(soy.C("status", "=", "active"), "active_label").
When(soy.C("status", "=", "pending"), "pending_label").
Else("other_label").
As("status_text").
End().
Render()
// SELECT "id", "name", CASE WHEN "status" = :active THEN :active_label ... END AS "status_text" FROM "table"| Method | Description |
|---|---|
SelectCase() |
Start a CASE expression, returns *SelectCaseBuilder |
When(condition, resultParam) |
Add a WHEN...THEN clause |
Else(resultParam) |
Set the ELSE clause |
As(alias) |
Set the result alias |
End() |
Complete and return to parent builder |
Build SQL window functions with a fluent API:
result, err := soy.Query().
Fields("id", "name", "department").
SelectRowNumber().
PartitionBy("department").
OrderBy("salary", "DESC").
As("rank").
End().
Render()
// SELECT "id", "name", "department", ROW_NUMBER() OVER (PARTITION BY "department" ORDER BY "salary" DESC) AS "rank"| Method | SQL Function |
|---|---|
SelectRowNumber() |
ROW_NUMBER() |
SelectRank() |
RANK() |
SelectDenseRank() |
DENSE_RANK() |
SelectNtile(nParam) |
NTILE(:n) |
SelectLag(field, offsetParam) |
LAG("field", :offset) |
SelectLead(field, offsetParam) |
LEAD("field", :offset) |
SelectFirstValue(field) |
FIRST_VALUE("field") |
SelectLastValue(field) |
LAST_VALUE("field") |
SelectSumOver(field) |
SUM("field") OVER |
SelectAvgOver(field) |
AVG("field") OVER |
SelectCountOver() |
COUNT(*) OVER |
SelectMinOver(field) |
MIN("field") OVER |
SelectMaxOver(field) |
MAX("field") OVER |
| Method | Description |
|---|---|
PartitionBy(fields...) |
Add PARTITION BY clause |
OrderBy(field, direction) |
Add ORDER BY clause |
Frame(start, end) |
Add ROWS BETWEEN frame clause |
As(alias) |
Set result alias |
End() |
Complete and return to parent builder |
Frame bounds: "UNBOUNDED PRECEDING", "CURRENT ROW", "UNBOUNDED FOLLOWING"
func Between(field, lowParam, highParam string) ConditionCreates a BETWEEN condition for use with WhereAnd/WhereOr.
func NotBetween(field, lowParam, highParam string) ConditionCreates a NOT BETWEEN condition for use with WhereAnd/WhereOr.
Soy uses sentinel errors that support errors.Is() and errors.As() for precise error handling.
| Error | Description |
|---|---|
ErrNotFound |
Query expects at least one row but finds none |
ErrMultipleRows |
Query expects exactly one row but finds multiple |
ErrNoRowsAffected |
Operation expects to affect rows but affects none |
ErrEmptyTableName |
Table name is empty |
ErrNilRenderer |
Renderer is nil |
ErrUnsafeUpdate |
UPDATE without WHERE clause |
ErrUnsafeDelete |
DELETE without WHERE clause |
| Sentinel | Matches |
|---|---|
ErrInvalidField |
Invalid field name |
ErrInvalidParam |
Invalid parameter name |
ErrInvalidOperator |
Unsupported operator |
ErrInvalidDirection |
Invalid sort direction |
ErrInvalidNullsOrdering |
Invalid NULLS FIRST/LAST |
ErrInvalidTable |
Invalid table name |
ErrInvalidCondition |
Invalid condition |
ErrInvalidAggregateFunc |
Invalid aggregate function |
| Sentinel | Matches |
|---|---|
ErrQueryFailed |
Query execution failure |
ErrScanFailed |
Result scanning failure |
ErrIterationFailed |
Row iteration failure |
ErrRenderFailed |
Query rendering failure |
| Sentinel | Matches |
|---|---|
ErrBuilderHasErrors |
Builder accumulated errors |
record, err := soy.Select().Where("id", "=", "id").Exec(ctx, params)
if errors.Is(err, soy.ErrNotFound) {
// Handle missing record
}
if errors.Is(err, soy.ErrInvalidField) {
// Handle invalid field name
}Extract details from validation errors:
_, err := soy.Select().Where("bad_field", "=", "id").Exec(ctx, params)
var valErr *soy.ValidationError
if errors.As(err, &valErr) {
fmt.Printf("Invalid %s: %s\n", valErr.Kind, valErr.Name)
}Extract details from query errors:
var qErr *soy.QueryError
if errors.As(err, &qErr) {
fmt.Printf("Operation %s failed at %s phase\n", qErr.Operation, qErr.Phase)
}