///|
/// `Hero` written without annotations, the way a model is declared by hand: the
/// columns, a decoder over the typed accessors, and the projection an INSERT binds.
/// The annotated model must render and bind exactly as this one does.
let hand_heroes : @moonorm.Model[Hero] = @moonorm.Model::new(
"heroes",
[
@moonorm.column("id", BigIntType, primary_key=true, autoincrement=true),
@moonorm.column("name", TextType, nullable=false),
@moonorm.column("secret_name", TextType, nullable=false, unique=true),
@moonorm.column("age", IntType, checks=["age >= 0", "age < 1000"]),
@moonorm.column("power", RealType, nullable=false, default="0"),
@moonorm.column(
"team_id",
BigIntType,
references=("teams", "id"),
on_delete="SET NULL",
),
@moonorm.column("email", TextType, nullable=false),
],
r => {
id: if r.is_null(0) {
None
} else {
Some(r.int64(0))
},
name: r.text(1),
secret: r.text(2),
age: if r.is_null(3) {
None
} else {
Some(r.int(3))
},
power: r.double(4),
team_id: if r.is_null(5) {
None
} else {
Some(r.int64(5))
},
email: Email(r.text(6)),
visits: 0,
},
h => {
let out : Array[(String, @moonorm.Value)] = []
if h.id is Some(id) {
out.push(("id", @moondb.Int64(id)))
}
let Email(email) = h.email
out.push(("name", @moondb.Text(h.name)))
out.push(("secret_name", @moondb.Text(h.secret)))
out.push(
(
"age",
match h.age {
Some(a) => @moondb.Int(a)
None => @moondb.Null
},
),
)
out.push(("power", @moondb.Double(h.power)))
out.push(
(
"team_id",
match h.team_id {
Some(t) => @moondb.Int64(t)
None => @moondb.Null
},
),
)
out.push(("email", @moondb.Text(email)))
out
},
indexes=[@moonorm.index(["power"]), @moonorm.index(["name", "age"])],
)
///|
/// The two relations, written out.
let hand_team : @moonorm.Relation[Hero, Team] = @moonorm.belongs_to(
Team::model(),
"id",
h => h.team_id,
)
///|
let hand_roster : @moonorm.Relation[Team, Hero] = @moonorm.has_many(
hand_heroes,
"team_id",
t => t.id,
)