Skip to content

Templating

db-gen output is generated entirely from Go templates you control. The tool stays language-agnostic — the template decides the syntax. This page covers the core templates, the data they receive, the helper functions, and per-routine overrides.

For the full struct definitions, see the Template data reference.

Core templates

Configured in db-gen.json:

Key Receives Generates
DbContextTemplate all routines (Functions) the database-call code
ModelTemplate one routine a model per routine return shape
ProcessorTemplate one routine a mapper from db reader → model

For anything else (TypeScript types, providers, …) use Additional Generators. For bulk-COPY code, see Copy Targets.

Template data

Every template can access Config (the full configuration), BuildInfo (version/build metadata), and routine data. The DbContext template gets all routines; Model/Processor templates get one.

type DbContextData struct {
    Config    *Config
    Functions []Routine
    BuildInfo *version.BuildInformation
}

type Routine struct {
    FunctionName       string
    DbFullFunctionName string
    ModelName          string
    ProcessorName      string
    Schema             string
    DbFunctionName     string
    HasReturn          bool
    IsProcedure        bool
    Parameters         []Property   // all parameters, in order
    ReturnProperties   []Property
    UsesUserContext    bool
    ContextParameters  []Property   // params mapped to the context object
    RegularParameters  []Property   // params not mapped to context
}

See the Template data reference for Property and the rest.

Template functions

Default output is camelCase. Use these helpers to change case or clean names:

Function Example result
pascalCased GetUserById
camelCased getUserById
snakeCased get_user_by_id
normalizeStr strips leading underscores (_user_iduser_id); keeps underscores before digits (country_iso_2)
trimPrefix strips a given prefix
{{pascalCased $func.FunctionName}}

normalizeStr vs round-tripping

Since v0.6.1 the bundled Model/Processor templates use {{normalizeStr $property.DbColumnName}} instead of {{snakeCased $property.PropertyName}}. Round-tripping through PascalCase loses information — e.g. country_iso_2 would collapse to country_iso2.

A minimal example

// Generated by db-gen {{.BuildInfo.Version}}
public partial class DbContext
{
{{- range .Functions}}
    public async Task<{{.ModelName}}> {{.FunctionName}}Async(
    {{- range $i, $p := .Parameters}}{{if $i}}, {{end}}{{$p.PropertyType}} {{camelCased $p.PropertyName}}{{end}})
    {
        // call {{.Schema}}.{{.DbFunctionName}}
    }
{{- end}}
}
public class {{.Routine.ModelName}}
{
{{- range .Routine.ReturnProperties}}
    public {{.PropertyType}} {{.PropertyName}} { get; set; }
{{- end}}
}

Per-routine overrides

In Generate[].Functions, a function key maps to either a boolean (generate or not) or an override object. The key may be a bare name (my_func) or include a signature (my_func(text,int)).

Field Effect
MappedName Override the generated name; model/processor names append Model/Processor.
DontRetrieveValues Disable value selection for a function that has return values (off-only).
SelectOnlySpecified In Model, select only the columns you explicitly list.
Model Object keyed by db column name. false skips it; true or an object selects it. The object may override MappedName, IsNullable, MappedType, MappingFunction.
Parameters Object keyed by parameter name. Values must be objects (not booleans). Override MappedName, MappedType, IsNullable, IsOptional.
{
  "Functions": {
    "get_report": {
      "MappedName": "GetReport",
      "Model": {
        "total": { "MappedType": "decimal", "IsNullable": true },
        "internal_flag": false
      }
    }
  }
}

Type overrides and global lookup

When overriding a column's MappedType only, db-gen looks up the mapping function from the global type mappings. Setting MappingFunction without MappedType does nothing. Leave fields you don't intend to change empty so the global mapping is used.

Overloaded functions

Every overloaded function must be given a unique MappedName, because their generated names would otherwise collide. The name must be unique within the schema.

{
  "Functions": {
    "search(text)": { "MappedName": "SearchByText" },
    "search(int)":  { "MappedName": "SearchById" }
  }
}