On this page
Presets
A Preset controls directive vocabulary, generated names and optional Go output.
Start from DefaultPreset, change the required fields and pass it to WithPreset:
preset := seagull.DefaultPreset()
preset.Directives = seagull.Directives{Canonical: "acme"}
preset.Header = "// Code generated by acme. DO NOT EDIT."
preset.HelperPrefix = "acme"
preset.ErrorPrefix = "acme"
preset.QueryNames = seagull.QueryNames{Enabled: true, File: "query_names.go", Function: "QueryName"}
generator, err := seagull.New(dialect_engine_postgres.New(), seagull.WithPreset(preset))
New validates the preset and returns an error wrapping ErrInvalidConfig or
ErrInvalidPrefix when it cannot be used. Changing generated vocabulary does not
rewrite SQL bodies or user-supplied comments.
Directive and generated names
| Field | Contract |
|---|---|
Directives.Canonical | Prefix rendered by diagnostics and directive formatting. |
Directives.Aliases | Other accepted prefixes. RequireCanonical reports their use with a Q050 hint. |
Directives.Foreign | Other tools' prefixes, reported with Q051 rather than parsed. |
Header | Generated-file header, also used to identify stale output for pruning. |
HelperPrefix, ErrorPrefix | Prefixes of generated helper identifiers and error names/text. |
QueryNames | Enables the query-name file and selects its filename and function name, which must be a Go identifier other than _. |
sgl.yaml exposes directive prefixes through directives.prefixes and
directives.require_canonical. See output writing before changing
a header in an existing project.
SQLConstantSuffix defaults to SQL, so GetUser gets a getUserSQL constant. An
empty suffix adds nothing. SQLConstantLowerCase lower-cases the parts between
underscores before naming constants: GetUser starts getuser, while get_user
starts getUser. It also affects runtime-builder count and allowed-column names.
These two compatibility settings have no sgl.yaml keys.
Go output features
The default preset leaves these optional features off. The matching configuration keys are described in configuration.
| Field | Effect |
|---|---|
Interface | Adds querier_interface.go with an interface implemented by Queries; its default name is Querier. |
JSONTags | Controls column fields' JSON tag case, omission and omitempty. |
StructTags | Adds tags by key, substituting {name} with the column name. Column-specific tags can override them. |
EmptySlices | Returns an empty slice from a many method with no rows. |
DocComments | Includes query descriptions and schema comments as Go documentation. |
ReuseModels | Reuses a table model when the analysed result matches it. |
KeepStars | Preserves SELECT *, RETURNING * and table.* instead of expanding their columns. |
WrapErrors | Labels every error a generated method returns with the error prefix and the method's name, such as sgl: GetUser: sql: no rows in result set, keeping the error beneath for errors.Is and errors.As, and adds error_wrapping.go. |
Expanding stars protects a generated method's scan order when the database gains a
column before regeneration. KeepStars gives up that protection. See
generated Go for the resulting files and APIs, and
labelled errors for what WrapErrors
changes in each method.
ModernIdioms is the one output setting DefaultPreset turns on: a stream method
returns iter.Seq2[<Name>Row, error], and every generated file has a blank line between
each two top-level declarations. A preset that must reproduce code generated before the
setting existed byte for byte leaves it off, and a stream method then returns
func(func(<Name>Row, error) bool), which has the same underlying type, so a for range
loop over either compiles. ModernIdioms has no sgl.yaml key, so sgl generates with it
on; WrapErrors is the go.wrap_errors key, off by default.
Type choices
Types replaces categories of Go types. NonNullElements declares array/list elements
and map values non-null where the engine can otherwise hold NULL, for example producing
[]int32 instead of []*int32 for an int4[] result. It defaults to false; a
column directive or type override can still set element nullability explicitly.
See type mapping for precedence and nullable elements for the consequences.
See customise generation for adoption and output writing for header-based pruning.