Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ issues:
- staticcheck
- path: entc/gen/graph.go
linters:
- gocritic
- gocritic
3 changes: 0 additions & 3 deletions dialect/sql/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,6 @@ const (

// ConstName returns the constant name of a reference option. It's used by entc for printing the constant name in templates.
func (r ReferenceOption) ConstName() string {
if r == NoAction {
return ""
}
return strings.ReplaceAll(strings.Title(strings.ToLower(string(r))), " ", "")
}

Expand Down
6 changes: 6 additions & 0 deletions doc/md/schema-edges.md
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,12 @@ func (Card) Edges() []ent.Edge {

If the example above, a card entity cannot be created without its owner.

:::info
Note that, starting with [v0.10](https://github.com/ent/ent/releases/tag/v0.10.0), foreign key columns are created
as `NOT NULL` in the database for required edges that are not [self-reference](#o2m-same-type). In order to migrate
existing foreign key columns, use the [Atlas Migration](migrate.md#atlas-integration) option.
:::

## StorageKey

By default, Ent configures edge storage-keys by the edge-owner (the schema that holds the `edge.To`), and not the by
Expand Down
25 changes: 19 additions & 6 deletions entc/gen/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,15 +456,20 @@ func (g *Graph) Tables() (all []*schema.Table, err error) {
}
switch e.Rel.Type {
case O2O, O2M:
// The "owner" is the table that owns the relation (we set the foreign-key on)
// and "ref" is the referenced table.
// The "owner" is the table that owns the relation (we set
// the foreign-key on) and "ref" is the referenced table.
owner, ref := tables[e.Rel.Table], tables[n.Table()]
pk := ref.PrimaryKey[0]
column := &schema.Column{Name: e.Rel.Column(), Size: pk.Size, Type: pk.Type, Unique: e.Rel.Type == O2O, SchemaType: pk.SchemaType, Nullable: true}
// If it's not a circular reference (self-referencing table),
// and the inverse edge is required, make it non-nullable.
if n != e.Type && e.Ref != nil && !e.Ref.Optional {
column.Nullable = false
}
mayAddColumn(owner, column)
owner.AddForeignKey(&schema.ForeignKey{
RefTable: ref,
OnDelete: deleteAction(e),
OnDelete: deleteAction(e, column),
Columns: []*schema.Column{column},
RefColumns: []*schema.Column{ref.PrimaryKey[0]},
Symbol: fkSymbol(e, owner, ref),
Expand All @@ -473,10 +478,15 @@ func (g *Graph) Tables() (all []*schema.Table, err error) {
ref, owner := tables[e.Type.Table()], tables[e.Rel.Table]
pk := ref.PrimaryKey[0]
column := &schema.Column{Name: e.Rel.Column(), Size: pk.Size, Type: pk.Type, SchemaType: pk.SchemaType, Nullable: true}
// If it's not a circular reference (self-referencing table),
// and the edge is non-optional (required), make it non-nullable.
if n != e.Type && !e.Optional {
column.Nullable = false
}
mayAddColumn(owner, column)
owner.AddForeignKey(&schema.ForeignKey{
RefTable: ref,
OnDelete: deleteAction(e),
OnDelete: deleteAction(e, column),
Columns: []*schema.Column{column},
RefColumns: []*schema.Column{ref.PrimaryKey[0]},
Symbol: fkSymbol(e, owner, ref),
Expand Down Expand Up @@ -563,8 +573,11 @@ func fkSymbols(e *Edge, c1, c2 *schema.Column) (string, string) {
}

// deleteAction returns the referential action for DELETE operations of the given edge.
func deleteAction(e *Edge) schema.ReferenceOption {
action := schema.SetNull
func deleteAction(e *Edge, c *schema.Column) schema.ReferenceOption {
action := schema.NoAction
if c.Nullable {
action = schema.SetNull
}
if ant := e.EntSQL(); ant != nil && ant.OnDelete != "" {
action = schema.ReferenceOption(ant.OnDelete)
}
Expand Down
2 changes: 1 addition & 1 deletion entc/integration/cascadelete/ent/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions entc/integration/edgefield/ent/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions entc/integration/ent/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 4 additions & 8 deletions entc/integration/migrate/entv2/car_create.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 28 additions & 16 deletions entc/integration/migrate/entv2/car_update.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions entc/integration/migrate/entv2/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions entc/integration/migrate/entv2/schema/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (User) Indexes() []ent.Index {
// this index on MySQL.
index.Fields("description").
Annotations(entsql.Prefix(100)),
// deleting old indexes (name, address),
// Deleting old indexes (name, address),
// and defining a new one.
index.Fields("phone", "age").
Unique(),
Expand All @@ -135,7 +135,10 @@ func (Car) Edges() []ent.Edge {
return []ent.Edge{
edge.From("owner", User.Type).
Ref("car").
Unique(),
Unique().
// Make a M20 edge from nullable to required.
// Requires column and foreign-key migration.
Required(),
}
}

Expand Down
10 changes: 6 additions & 4 deletions entc/integration/migrate/migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,14 @@ func TestSQLite(t *testing.T) {
)

SanityV2(t, drv.Dialect(), client)
idRange(t, client.Car.Create().SaveX(ctx).ID, 0, 1<<32)
u := client.User.Create().SetAge(1).SetName("x").SetNickname("x'").SetPhone("y").SaveX(ctx)
idRange(t, client.Car.Create().SetOwner(u).SaveX(ctx).ID, 0, 1<<32)
idRange(t, client.Conversion.Create().SaveX(ctx).ID, 1<<32-1, 2<<32)
idRange(t, client.CustomType.Create().SaveX(ctx).ID, 2<<32-1, 3<<32)
idRange(t, client.Group.Create().SaveX(ctx).ID, 3<<32-1, 4<<32)
idRange(t, client.Media.Create().SaveX(ctx).ID, 4<<32-1, 5<<32)
idRange(t, client.Pet.Create().SaveX(ctx).ID, 5<<32-1, 6<<32)
idRange(t, client.User.Create().SetAge(1).SetName("x").SetNickname("x'").SetPhone("y").SaveX(ctx).ID, 6<<32-1, 7<<32)
idRange(t, u.ID, 6<<32-1, 7<<32)

// Override the default behavior of LIKE in SQLite.
// https://www.sqlite.org/pragma.html#pragma_case_sensitive_like
Expand Down Expand Up @@ -163,11 +164,12 @@ func V1ToV2(t *testing.T, dialect string, clientv1 *entv1.Client, clientv2 *entv
require.NoError(t, clientv2.Schema.Create(ctx, migratev2.WithGlobalUniqueID(true), schema.WithAtlas(true)), "should not create additional resources on multiple runs")
SanityV2(t, dialect, clientv2)

idRange(t, clientv2.Car.Create().SaveX(ctx).ID, 0, 1<<32)
u := clientv2.User.Create().SetAge(1).SetName("foo").SetNickname("nick_foo").SetPhone("phone").SaveX(ctx)
idRange(t, clientv2.Car.Create().SetOwner(u).SaveX(ctx).ID, 0, 1<<32)
idRange(t, clientv2.Conversion.Create().SaveX(ctx).ID, 1<<32-1, 2<<32)
// Since "users" created in the migration of v1, it will occupy the range of 1<<32-1 ... 2<<32-1,
// even though they are ordered differently in the migration of v2 (groups, pets, users).
idRange(t, clientv2.User.Create().SetAge(1).SetName("foo").SetNickname("nick_foo").SetPhone("phone").SaveX(ctx).ID, 3<<32-1, 4<<32)
idRange(t, u.ID, 3<<32-1, 4<<32)
idRange(t, clientv2.Group.Create().SaveX(ctx).ID, 4<<32-1, 5<<32)
idRange(t, clientv2.Media.Create().SaveX(ctx).ID, 5<<32-1, 6<<32)
idRange(t, clientv2.Pet.Create().SaveX(ctx).ID, 6<<32-1, 7<<32)
Expand Down
4 changes: 2 additions & 2 deletions examples/o2o2types/ent/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions examples/privacytenant/ent/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.