Implementing Custom Generators¶
pGenie's code generation is fully open and extensible. Anyone can implement a generator for a new target language, framework, or output format.
Overview¶
A generator is a Dhall program that receives a structured description of your project and returns a list of output files. Generators are referenced by URL in project1.pgn.yaml, so they can be hosted anywhere (GitHub, a personal server, etc.).
The Generator Interface¶
Every generator must be a Dhall expression of the type provided by the pGenie SDK (Sdk.module). The SDK is available as a Dhall package from the pGenie generator dependencies.
The minimal structure of a generator entry point (Gen.dhall):
let Deps = ./Deps/package.dhall
let Sdk = Deps.Sdk
in Sdk.module { major = 1, minor = 0 } ./Config.dhall ./compile.dhall
Where:
{ major = 1, minor = 0 }declares which version of the pGenie generator SDK this generator targets../Config.dhalldefines the schema of any user-supplied configuration (use{} : Typefor no configuration)../compile.dhallis the main compilation function that receives the project model and returns a list of generated files.
The Compilation Function¶
compile.dhall receives the full project model and returns a list of file paths and contents:
\(project : Sdk.ProjectModel) ->
[ { path = "src/Queries.hs"
, content = generateHaskellModule project
}
]
The Sdk.ProjectModel type contains:
space- the project's namespacename- the project's nameversion- the project's versionqueries- a list of query descriptors, each containing the query name, parameters, and result columns with their full type informationschema- type declarations (enumerations, composite types) from the schema
Example: The hasql Generator¶
The official haskell.gen generator is a good reference implementation. Its structure:
gen/
├── Gen.dhall ← entry point
├── Config.dhall ← configuration schema (empty)
├── compile.dhall ← main compilation function
├── Deps/ ← SDK and shared utilities
├── Interpreters/ ← type mappers (Postgres → Haskell)
└── Templates/ ← Haskell code templates
Browse the source at github.com/pgenie-io/haskell.gen.
Distributing Your Generator¶
- Host your generator files at a stable URL (e.g. a GitHub repository with tagged releases).
- Tag each release (e.g.
v1.0.0) so users can pin the URL. You can also reference a specific commit hash instead of a tag — both are equally reproducible, but a named tag is usually more convenient for users. -
Users reference your generator in their
project1.pgn.yaml:
Tips¶
- Use Dhall's type system: define explicit types for your templates and intermediate data structures. Dhall's type checker will catch mistakes early.
- Keep templates small: break large templates into composable functions. Dhall's import system makes this straightforward.
- Test with ready-made fixtures: the pgenie/gen-sdk repository contains ready-made Dhall test fixtures that exercise enumerations, composite types, arrays, and various query patterns. Reuse these fixtures to test your generator without needing to set up your own project from scratch.