Type Mapping¶
db-gen maps each PostgreSQL type to a target-language type. Because a type can appear as a non-null return, a nullable return, a nullable parameter, or an optional (DEFAULT) parameter — each potentially needing a different target type — db-gen uses a three-tier mapping system.
Defining mappings¶
Mappings is an array; each entry covers one or more PostgreSQL udt_names:
{
"Mappings": [
{
"DatabaseTypes": ["int4"],
"MappedType": "int",
"MappingFunction": "GetInt32",
"NullableReturnType": "int?",
"NullableParameterType": "int?",
"OptionalParameterType": "Optional<int>"
},
{
"DatabaseTypes": ["text", "varchar"],
"MappedType": "string",
"MappingFunction": "GetString",
"NullableReturnType": "string?"
},
{
"DatabaseTypes": ["*"],
"MappedType": "object",
"MappingFunction": "GetValue"
}
]
}
Catch-all fallback
Add a "*" entry as a fallback for unmapped types. Without it, an unmapped type stops generation with an error. If a type appears in multiple entries, the last one wins.
The four target types¶
| Field | Used for | Example |
|---|---|---|
MappedType |
base — non-nullable, non-optional | int |
NullableReturnType |
a nullable return value / model property | int? |
NullableParameterType |
a nullable parameter without a DEFAULT | int? |
OptionalParameterType |
a parameter with a DEFAULT | Optional<int> |
Resolution rules¶
For parameters:
flowchart TD
A[Parameter] --> B{Optional?<br/>has DEFAULT}
B -->|yes, and OptionalParameterType set| C[OptionalParameterType]
B -->|no| D{Nullable?<br/>accepts NULL}
D -->|yes, and NullableParameterType set| E[NullableParameterType]
D -->|no| F[MappedType]
For return / model columns: nullable → NullableReturnType if set; otherwise MappedType.
Nullable vs optional¶
This distinction is central:
| Meaning | Passed to DB? | Type | |
|---|---|---|---|
| Nullable | no DEFAULT, accepts NULL | always (may be null) | T? |
| Optional | has a DEFAULT | may be omitted entirely | Optional<T> |
In templates, check $parameter.Optional to decide between "omit if absent" and "always pass":
{{- if $param.Optional}}
{{$param.PropertyName}}.ToObjectOptional()
{{- else}}
{{$param.PropertyName}}
{{- end}}
Why nullable parameters use T?, not Optional<T>
A nullable parameter must always be sent to the database (it can legitimately be null). If it were typed Optional<T>, an absent value could be dropped from the call entirely, changing behavior. Only parameters with a DEFAULT use the optional type.
Per-function overrides¶
You can override types for a single function's parameters or model columns via Generate[].Functions. See Templating → per-routine overrides.
{
"Functions": {
"get_report": {
"Model": { "total": { "MappedType": "decimal", "IsNullable": true } },
"Parameters": { "page_size": { "MappedType": "int", "IsOptional": true } }
}
}
}
When you set only MappedType, db-gen looks up the matching MappingFunction from the global mappings (and errors if none exists).