ORM: Generate CREATE TABLE
Combining typeinfo field iteration with decorator data and type-kind mapping,
a single comptime block can emit a fully correct CREATE TABLE DDL statement
for any struct — optional fields become nullable columns, @column renames them,
and integer fields map to INTEGER. No runtime cost, no reflection library.
Walk typeinfo(Account).fields at compile time, apply @column renames, map type.kind to SQL types, and emit a complete CREATE TABLE DDL string with NOT NULL constraints.
05-orm-table.zolo
// Use case 2 — ORM / DATABASE
//
// Generate a `CREATE TABLE` statement from a type, at compile time.
// `@column("...")` decorators (surfaced as data by `typeinfo`) rename columns;
// the field `type.kind` maps to a SQL column type; non-optional fields become
// `NOT NULL`. This is the seed of a compile-time ORM — zero runtime cost.
struct Account {
@column("account_id")
id: int,
@column("display_name")
name: str,
nickname: str?,
}
let ddl = comptime {
var s = "CREATE TABLE Account (\n"
var first = true
for f in typeinfo(Account).fields {
if first == false { s = s + ",\n" }
// column name: the @column decorator value, or the field name
var col = f.name
if f.decorators.len() > 0 { col = f.decorators[0].args[0] }
// type.kind -> SQL type
var sqltype = "TEXT"
if f.type.kind == "int" { sqltype = "INTEGER" }
if f.type.kind == "bool" { sqltype = "BOOLEAN" }
s = s + " " + col + " " + sqltype
if f.optional == false { s = s + " NOT NULL" }
first = false
}
s = s + "\n)"
s
}
print(ddl)
// expected:
// CREATE TABLE Account (
// account_id INTEGER NOT NULL,
// display_name TEXT NOT NULL,
// nickname TEXT
// )