Allianaab2m/aya/gen does not have a README file

    AttrError

    pub(all) suberror AttrError {
    Malformed(raw~ : String, reason~ : String)
    } derive(
    Debug
    )

    EntityError

    pub(all) suberror EntityError {
    NotARecord(type_name~ : String)
    MissingTable(type_name~ : String)
    DuplicatePrimaryKey(type_name~ : String)
    InvalidArg(type_name~ : String, key~ : String, value~ : String)
    UnknownIndexColumn(type_name~ : String, column~ : String)
    EmptyIndex(type_name~ : String)
    ReservedArg(type_name~ : String, key~ : String, use_instead~ : String)
    } derive(
    Debug
    )

    impl Show for EntityError

    GenError

    pub(all) suberror GenError {
    ParseFailed(name~ : String, diagnostics~ : Int)
    } derive(
    Debug
    )

    Attr

    pub struct Attr {
    name : String
    args : Map[String, String]
    } derive(Eq,
    Debug
    )

    A #aya.* attribute recovered from source text.

    moonbitlang/parser hands us attributes with raw filled in but parsed left as None for user-defined namespaces, so we read raw ourselves. Attribute::name() drops the namespace (#aya.id and #morm.id both report "id"), which is not good enough to tell our attributes apart.

    Attr::arg

    fn Attr::arg(self : Attr, key : String) -> String?

    Look up an optional string argument.

    EntitySpec

    pub struct EntitySpec {
    type_name : String
    table : String
    tbl : String
    cols_name : String
    fields : Array[FieldSpec]
    indexes : Array[IndexSpec]
    } derive(Eq,
    Debug
    )

    A struct carrying #aya.table, lowered into everything the emitter needs.

    This describes the row type: the flat shape of one database row. A domain type is a separate thing that the programmer maps to and from.

    FieldSpec

    pub struct FieldSpec {
    name : String
    ty : String
    column : String
    is_primary : Bool
    nullable : Bool
    sql_type : String?
    default_sql : String?
    unique : Bool
    autoincrement : Bool
    references : RefSpec?
    } derive(Eq,
    Debug
    )

    One column of an entity, in the order it was declared.

    Declaration order is load-bearing: it fixes both the projection order and the positional decoder, which is exactly the pairing a hand-written Selection can get wrong.

    IndexSpec

    pub struct IndexSpec {
    name : String
    columns : Array[String]
    unique : Bool
    } derive(Eq,
    Debug
    )

    A secondary index declared on the entity with #aya.index(...).

    RefSpec

    pub struct RefSpec {
    table : String
    column : String
    on_delete : String?
    on_update : String?
    } derive(Eq,
    Debug
    )

    A foreign key declared on a column, e.g. #aya.column(references="accounts.id", on_delete="cascade").

    collect_entities

    Collect every #aya.table declaration in a parsed file.

    Declarations without the attribute are skipped, so an entity file may hold ordinary MoonBit code alongside entities.

    emit_entity

    fn emit_entity(spec : EntitySpec) -> String

    Emit the four declarations that make one entity usable as a table.

    emit_file

    fn emit_file(specs : Array[EntitySpec]) -> String

    Emit a complete generated file for a set of entities.

    entities_of

    fn entities_of(source : String, name? : String) -> Array[EntitySpec] raise

    Parse a source file and lower every #aya.table in it.

    The shared front half of both generators: the column-handle emitter and the DDL emitter must see the same entities, or the code and the schema drift.

    generate

    fn generate(source : String, name? : String) -> String raise

    Parse an entity source file and produce its generated companion.

    String in, string out: file IO stays in the CLI so the whole pipeline is testable without touching the filesystem.

    parse_attr

    fn parse_attr(raw : String) -> Attr? raise AttrError

    Parse one raw attribute such as #aya.entity(table="users", alias="u").

    Returns None when the attribute belongs to another namespace, so callers can ignore #deprecated, #morm.entity, and friends without special cases.

    render_type

    fn render_type(t :
    Type
    ) -> String

    Render a parsed type back to MoonBit source text.

    The emitter needs the type twice, once inside Column[_] and once as the entity field type, so the round trip has to be faithful for the types aya can actually store.