glimr/db/gen/schema_parser/codegen
Schema Codegen Type Mapping
The schema generator reads your migration files and writes Gleam model code — type definitions, decoders, and JSON encoders. But it needs to know that a Timestamp column becomes a String in Gleam, uses decode.string for query results, and json.string for API output. These three mapping functions are the single source of truth for those decisions, so every generated model stays consistent.
Values
pub fn decoder_fn(col_type: schema_parser.ColumnType) -> String
Generated models need decoders to parse database query results into typed records. Most columns use the obvious decoder, but Boolean is the exception — SQLite returns booleans as 0/1 integers, so we use a custom glimr_decode.bool() that handles both true/false and 0/1 instead of the standard decode.bool which would fail on SQLite results.
pub fn enum_type_name(name: String) -> String
Gleam requires PascalCase for custom type names, but schema
column names are snake_case. An enum column named
payment_status with variants becomes a Gleam type
PaymentStatus — this does that conversion.
pub fn gleam_type(col_type: schema_parser.ColumnType) -> String
Database columns like Timestamp and Date store temporal data but come across the wire as strings — representing them as String in Gleam avoids pulling in a datetime library as a hard dependency. Foreign keys are always integer IDs regardless of what they point to, and Boolean maps to Bool rather than Gleam’s bitwise types.
pub fn is_array(col_type: schema_parser.ColumnType) -> Bool
Array columns need different codegen paths — different
import (glimr_decode), different encoder expression
(json.array instead of json.int), different decoder
(glimr_decode.list_of instead of decode.int). The
generator checks this to decide which path to take.
pub fn is_blob(col_type: schema_parser.ColumnType) -> Bool
Blobs go through base64 encoding for JSON output and need a
gleam/bit_array import that other column types don’t. The
generator uses this check to add that import only when the
table actually has a blob column.
pub fn is_enum(col_type: schema_parser.ColumnType) -> Bool
Enum columns get their own Gleam custom type (e.g. type Status { Active | Inactive }) plus converter functions. The
generator needs to know which columns are enums so it can
emit these type definitions alongside the model code.
pub fn json_encoder_expr(
col_type: schema_parser.ColumnType,
accessor: String,
) -> String
Scalars and arrays encode completely differently —
json.int(model.age) vs json.array(model.tags, json.string). The argument order flips and arrays need a
mapping function instead of a direct call. This builds the
right expression for either case, and for nested arrays it
recurses to produce the right nesting of json.array calls.
pub fn json_encoder_fn(
col_type: schema_parser.ColumnType,
) -> String
The schema generator writes JSON encoder functions for each model so developers don’t have to maintain them by hand. Picking the right json.* call per column type here means a Timestamp field gets json.string (ISO format) and a Foreign key gets json.int — getting this wrong would produce JSON that silently breaks API consumers.