Skip to content

Derive: Full DB Table DDL

This derive shows a production-grade pattern: a match on f.type.kind maps Zolo types to SQL column types (including foreign-key references via "ref"), then assembles the full CREATE TABLE DDL and wires it to the type as a create_table() method — all at compile time.

Use @derive_for(DbTable) with a match on f.type.kind to map Zolo types (int, str, ref) to SQL column types including foreign-key references, then wire the result as a create_table() method.

14-test.zolo
Playground
@derive_for(DbTable)
fn derive_db_table(info) -> str {
  let cols = info.fields.map(|f| {
    let nullable = if f.type.is_optional { "NULL" } else { "NOT NULL" }
    let tp = match f.type.kind {
      "int" => "integer",
      "str" => "varchar",
      "ref" => "varchar(16) references {f.type.name.lower()}_table",
      _ => "varchar",
    }

    "{f.name} {tp} {nullable}"
  })

  let body = cols.join(", ")
  let ddl  = "create table {info.name.lower()}_table ({body});"
  return "impl {info.name} \{ fn create_table() -> str \{ return \"{ddl}\" \} \}"
}

@derive(DbTable)
struct Account {
  id: int,
  owner: User,
  balance: int,
}

let a = Account.new(id: 1, owner: "x", balance: 0)
print(a.create_table())
enespt-br