Skip to content

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
Playground
// 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
// )
enespt-br