Generating Schemas

    In order to manipulate an existing schema directory we must first load it into a schemast.Context object:

    To print back out our context to a target directory, use schemast.Print:

    1. package main
    2. import (
    3. "log"
    4. "entgo.io/contrib/schemast"
    5. )
    6. func main() {
    7. ctx, err := schemast.Load("./ent/schema")
    8. if err != nil {
    9. log.Fatalf("failed: %v", err)
    10. }
    11. // A no-op since we did not manipulate the Context at all.
    12. if err := schemast.Print("./ent/schema"); err != nil {
    13. log.Fatalf("failed: %v", err)
    14. }
    15. }
    1. package schemast
    2. // Mutator changes a Context.
    3. type Mutator interface {
    4. Mutate(ctx *Context) error
    5. }

    Currently, only a single type of schemast.Mutator is implemented, UpsertSchema:

    To use it:

    1. package main
    2. "log"
    3. "entgo.io/contrib/schemast"
    4. "entgo.io/ent"
    5. "entgo.io/ent/schema/field"
    6. )
    7. func main() {
    8. ctx, err := schemast.Load("./ent/schema")
    9. if err != nil {
    10. log.Fatalf("failed: %v", err)
    11. }
    12. mutations := []schemast.Mutator{
    13. &schemast.UpsertSchema{
    14. Name: "User",
    15. Fields: []ent.Field{
    16. field.String("name"),
    17. },
    18. },
    19. &schemast.UpsertSchema{
    20. Name: "Team",
    21. Fields: []ent.Field{
    22. field.String("name"),
    23. },
    24. },
    25. }
    26. err = schemast.Mutate(ctx, mutations...)
    27. if err := ctx.Print("./ent/schema"); err != nil {
    28. log.Fatalf("failed: %v", err)
    29. }
    30. }
    1. // user.go
    2. package schema
    3. "entgo.io/ent"
    4. "entgo.io/ent/schema"
    5. "entgo.io/ent/schema/field"
    6. type User struct {
    7. ent.Schema
    8. }
    9. func (User) Fields() []ent.Field {
    10. return []ent.Field{field.String("name")}
    11. }
    12. func (User) Edges() []ent.Edge {
    13. return nil
    14. }
    15. func (User) Annotations() []schema.Annotation {
    16. return nil
    17. }

    Edges are defined in ent this way:

    1. edge.To("edge_name", OtherSchema.Type)

    This syntax relies on the fact that the OtherSchema struct already exists when we define the edge so we can refer to its Type method. When we are generating schemas programmatically, obviously we need somehow to describe the edge to the code-generator before the type definitions exist. To do this you can do something like:

    1. type placeholder struct {
    2. ent.Schema
    3. }
    4. func withType(e ent.Edge, typeName string) ent.Edge {
    5. e.Descriptor().Type = typeName
    6. return e
    7. }
    8. func newEdgeTo(edgeName, otherType string) ent.Edge {
    9. // we pass a placeholder type to the edge constructor:
    10. e := edge.To(edgeName, placeholder.Type)
    11. // then we override the other type's name directly on the edge descriptor:
    12. return withType(e, otherType)
    13. }

    schemast is still experimental, APIs are subject to change in the future. In addition, a small portion of the definition API is unsupported at this point in time, to see a full list of unsupported features see the source code.