From cedeef653a50c76fbe4445f76e4bd831fa98fe6a Mon Sep 17 00:00:00 2001 From: Ariel Mashraki <7413593+a8m@users.noreply.github.com> Date: Sun, 5 Jul 2020 22:22:50 +0300 Subject: [PATCH] dialect/sql/schema: accept convert from string2enum and enum2stirng (#587) --- dialect/sql/schema/schema.go | 3 + .../migrate/entv1/migrate/schema.go | 5 +- entc/integration/migrate/entv1/mutation.go | 76 +++++++++- entc/integration/migrate/entv1/schema/user.go | 2 + entc/integration/migrate/entv1/user.go | 12 +- entc/integration/migrate/entv1/user/user.go | 3 + entc/integration/migrate/entv1/user/where.go | 132 ++++++++++++++++++ entc/integration/migrate/entv1/user_create.go | 22 +++ entc/integration/migrate/entv1/user_update.go | 66 +++++++++ .../migrate/entv2/migrate/schema.go | 1 + entc/integration/migrate/entv2/mutation.go | 76 +++++++++- entc/integration/migrate/entv2/schema/user.go | 4 + entc/integration/migrate/entv2/user.go | 10 ++ entc/integration/migrate/entv2/user/user.go | 26 ++++ entc/integration/migrate/entv2/user/where.go | 62 ++++++++ entc/integration/migrate/entv2/user_create.go | 27 ++++ entc/integration/migrate/entv2/user_update.go | 76 ++++++++++ 17 files changed, 598 insertions(+), 5 deletions(-) diff --git a/dialect/sql/schema/schema.go b/dialect/sql/schema/schema.go index 8feb4ea50..b71a82042 100644 --- a/dialect/sql/schema/schema.go +++ b/dialect/sql/schema/schema.go @@ -171,6 +171,9 @@ func (c *Column) ConvertibleTo(d *Column) bool { case c.UintType() && d.IntType(): // uintX can not be converted to intY, when X > Y. return c.Type-field.TypeUint8 <= d.Type-field.TypeInt8 + case c.Type == field.TypeString && d.Type == field.TypeEnum || + c.Type == field.TypeEnum && d.Type == field.TypeString: + return true } return c.FloatType() && d.FloatType() } diff --git a/entc/integration/migrate/entv1/migrate/schema.go b/entc/integration/migrate/entv1/migrate/schema.go index e5a8925ec..b5fba3301 100644 --- a/entc/integration/migrate/entv1/migrate/schema.go +++ b/entc/integration/migrate/entv1/migrate/schema.go @@ -42,6 +42,7 @@ var ( {Name: "renamed", Type: field.TypeString, Nullable: true}, {Name: "blob", Type: field.TypeBytes, Nullable: true, Size: 255}, {Name: "state", Type: field.TypeEnum, Nullable: true, Enums: []string{"logged_in", "logged_out"}}, + {Name: "status", Type: field.TypeString, Nullable: true}, {Name: "user_children", Type: field.TypeInt, Nullable: true}, {Name: "user_spouse", Type: field.TypeInt, Unique: true, Nullable: true}, } @@ -53,14 +54,14 @@ var ( ForeignKeys: []*schema.ForeignKey{ { Symbol: "users_users_children", - Columns: []*schema.Column{UsersColumns[8]}, + Columns: []*schema.Column{UsersColumns[9]}, RefColumns: []*schema.Column{UsersColumns[0]}, OnDelete: schema.SetNull, }, { Symbol: "users_users_spouse", - Columns: []*schema.Column{UsersColumns[9]}, + Columns: []*schema.Column{UsersColumns[10]}, RefColumns: []*schema.Column{UsersColumns[0]}, OnDelete: schema.SetNull, diff --git a/entc/integration/migrate/entv1/mutation.go b/entc/integration/migrate/entv1/mutation.go index a7356b1dc..4b324ab50 100644 --- a/entc/integration/migrate/entv1/mutation.go +++ b/entc/integration/migrate/entv1/mutation.go @@ -344,6 +344,7 @@ type UserMutation struct { renamed *string blob *[]byte state *user.State + status *string clearedFields map[string]struct{} parent *int clearedparent bool @@ -773,6 +774,56 @@ func (m *UserMutation) ResetState() { delete(m.clearedFields, user.FieldState) } +// SetStatus sets the status field. +func (m *UserMutation) SetStatus(s string) { + m.status = &s +} + +// Status returns the status value in the mutation. +func (m *UserMutation) Status() (r string, exists bool) { + v := m.status + if v == nil { + return + } + return *v, true +} + +// OldStatus returns the old status value of the User. +// If the User object wasn't provided to the builder, the object is fetched +// from the database. +// An error is returned if the mutation operation is not UpdateOne, or database query fails. +func (m *UserMutation) OldStatus(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldStatus is allowed only on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldStatus requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldStatus: %w", err) + } + return oldValue.Status, nil +} + +// ClearStatus clears the value of status. +func (m *UserMutation) ClearStatus() { + m.status = nil + m.clearedFields[user.FieldStatus] = struct{}{} +} + +// StatusCleared returns if the field status was cleared in this mutation. +func (m *UserMutation) StatusCleared() bool { + _, ok := m.clearedFields[user.FieldStatus] + return ok +} + +// ResetStatus reset all changes of the "status" field. +func (m *UserMutation) ResetStatus() { + m.status = nil + delete(m.clearedFields, user.FieldStatus) +} + // SetParentID sets the parent edge to User by id. func (m *UserMutation) SetParentID(id int) { m.parent = &id @@ -946,7 +997,7 @@ func (m *UserMutation) Type() string { // this mutation. Note that, in order to get all numeric // fields that were in/decremented, call AddedFields(). func (m *UserMutation) Fields() []string { - fields := make([]string, 0, 7) + fields := make([]string, 0, 8) if m.age != nil { fields = append(fields, user.FieldAge) } @@ -968,6 +1019,9 @@ func (m *UserMutation) Fields() []string { if m.state != nil { fields = append(fields, user.FieldState) } + if m.status != nil { + fields = append(fields, user.FieldStatus) + } return fields } @@ -990,6 +1044,8 @@ func (m *UserMutation) Field(name string) (ent.Value, bool) { return m.Blob() case user.FieldState: return m.State() + case user.FieldStatus: + return m.Status() } return nil, false } @@ -1013,6 +1069,8 @@ func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, er return m.OldBlob(ctx) case user.FieldState: return m.OldState(ctx) + case user.FieldStatus: + return m.OldStatus(ctx) } return nil, fmt.Errorf("unknown User field %s", name) } @@ -1071,6 +1129,13 @@ func (m *UserMutation) SetField(name string, value ent.Value) error { } m.SetState(v) return nil + case user.FieldStatus: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetStatus(v) + return nil } return fmt.Errorf("unknown User field %s", name) } @@ -1128,6 +1193,9 @@ func (m *UserMutation) ClearedFields() []string { if m.FieldCleared(user.FieldState) { fields = append(fields, user.FieldState) } + if m.FieldCleared(user.FieldStatus) { + fields = append(fields, user.FieldStatus) + } return fields } @@ -1154,6 +1222,9 @@ func (m *UserMutation) ClearField(name string) error { case user.FieldState: m.ClearState() return nil + case user.FieldStatus: + m.ClearStatus() + return nil } return fmt.Errorf("unknown User nullable field %s", name) } @@ -1184,6 +1255,9 @@ func (m *UserMutation) ResetField(name string) error { case user.FieldState: m.ResetState() return nil + case user.FieldStatus: + m.ResetStatus() + return nil } return fmt.Errorf("unknown User field %s", name) } diff --git a/entc/integration/migrate/entv1/schema/user.go b/entc/integration/migrate/entv1/schema/user.go index 1c28ab23a..f975b9a72 100644 --- a/entc/integration/migrate/entv1/schema/user.go +++ b/entc/integration/migrate/entv1/schema/user.go @@ -36,6 +36,8 @@ func (User) Fields() []ent.Field { field.Enum("state"). Optional(). Values("logged_in", "logged_out"), + field.String("status"). + Optional(), } } diff --git a/entc/integration/migrate/entv1/user.go b/entc/integration/migrate/entv1/user.go index 6914d9055..cfbb54bb3 100644 --- a/entc/integration/migrate/entv1/user.go +++ b/entc/integration/migrate/entv1/user.go @@ -34,6 +34,8 @@ type User struct { Blob []byte `json:"blob,omitempty"` // State holds the value of the "state" field. State user.State `json:"state,omitempty"` + // Status holds the value of the "status" field. + Status string `json:"status,omitempty"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the UserQuery when eager-loading is set. Edges UserEdges `json:"edges"` @@ -118,6 +120,7 @@ func (*User) scanValues() []interface{} { &sql.NullString{}, // renamed &[]byte{}, // blob &sql.NullString{}, // state + &sql.NullString{}, // status } } @@ -176,7 +179,12 @@ func (u *User) assignValues(values ...interface{}) error { } else if value.Valid { u.State = user.State(value.String) } - values = values[7:] + if value, ok := values[7].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field status", values[7]) + } else if value.Valid { + u.Status = value.String + } + values = values[8:] if len(values) == len(user.ForeignKeys) { if value, ok := values[0].(*sql.NullInt64); !ok { return fmt.Errorf("unexpected type %T for edge-field user_children", value) @@ -251,6 +259,8 @@ func (u *User) String() string { builder.WriteString(fmt.Sprintf("%v", u.Blob)) builder.WriteString(", state=") builder.WriteString(fmt.Sprintf("%v", u.State)) + builder.WriteString(", status=") + builder.WriteString(u.Status) builder.WriteByte(')') return builder.String() } diff --git a/entc/integration/migrate/entv1/user/user.go b/entc/integration/migrate/entv1/user/user.go index e3157bd83..83c39a2b3 100644 --- a/entc/integration/migrate/entv1/user/user.go +++ b/entc/integration/migrate/entv1/user/user.go @@ -29,6 +29,8 @@ const ( FieldBlob = "blob" // FieldState holds the string denoting the state field in the database. FieldState = "state" + // FieldStatus holds the string denoting the status field in the database. + FieldStatus = "status" // EdgeParent holds the string denoting the parent edge name in mutations. EdgeParent = "parent" @@ -72,6 +74,7 @@ var Columns = []string{ FieldRenamed, FieldBlob, FieldState, + FieldStatus, } // ForeignKeys holds the SQL foreign-keys that are owned by the User type. diff --git a/entc/integration/migrate/entv1/user/where.go b/entc/integration/migrate/entv1/user/where.go index 772126090..8675b9596 100644 --- a/entc/integration/migrate/entv1/user/where.go +++ b/entc/integration/migrate/entv1/user/where.go @@ -137,6 +137,13 @@ func Blob(v []byte) predicate.User { }) } +// Status applies equality check predicate on the "status" field. It's identical to StatusEQ. +func Status(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldStatus), v)) + }) +} + // AgeEQ applies the EQ predicate on the "age" field. func AgeEQ(v int32) predicate.User { return predicate.User(func(s *sql.Selector) { @@ -837,6 +844,131 @@ func StateNotNil() predicate.User { }) } +// StatusEQ applies the EQ predicate on the "status" field. +func StatusEQ(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldStatus), v)) + }) +} + +// StatusNEQ applies the NEQ predicate on the "status" field. +func StatusNEQ(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldStatus), v)) + }) +} + +// StatusIn applies the In predicate on the "status" field. +func StatusIn(vs ...string) predicate.User { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.User(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldStatus), v...)) + }) +} + +// StatusNotIn applies the NotIn predicate on the "status" field. +func StatusNotIn(vs ...string) predicate.User { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.User(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldStatus), v...)) + }) +} + +// StatusGT applies the GT predicate on the "status" field. +func StatusGT(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldStatus), v)) + }) +} + +// StatusGTE applies the GTE predicate on the "status" field. +func StatusGTE(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldStatus), v)) + }) +} + +// StatusLT applies the LT predicate on the "status" field. +func StatusLT(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldStatus), v)) + }) +} + +// StatusLTE applies the LTE predicate on the "status" field. +func StatusLTE(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldStatus), v)) + }) +} + +// StatusContains applies the Contains predicate on the "status" field. +func StatusContains(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.Contains(s.C(FieldStatus), v)) + }) +} + +// StatusHasPrefix applies the HasPrefix predicate on the "status" field. +func StatusHasPrefix(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.HasPrefix(s.C(FieldStatus), v)) + }) +} + +// StatusHasSuffix applies the HasSuffix predicate on the "status" field. +func StatusHasSuffix(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.HasSuffix(s.C(FieldStatus), v)) + }) +} + +// StatusIsNil applies the IsNil predicate on the "status" field. +func StatusIsNil() predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.IsNull(s.C(FieldStatus))) + }) +} + +// StatusNotNil applies the NotNil predicate on the "status" field. +func StatusNotNil() predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.NotNull(s.C(FieldStatus))) + }) +} + +// StatusEqualFold applies the EqualFold predicate on the "status" field. +func StatusEqualFold(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.EqualFold(s.C(FieldStatus), v)) + }) +} + +// StatusContainsFold applies the ContainsFold predicate on the "status" field. +func StatusContainsFold(v string) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.ContainsFold(s.C(FieldStatus), v)) + }) +} + // HasParent applies the HasEdge predicate on the "parent" edge. func HasParent() predicate.User { return predicate.User(func(s *sql.Selector) { diff --git a/entc/integration/migrate/entv1/user_create.go b/entc/integration/migrate/entv1/user_create.go index 55eb6e140..e0cc2f464 100644 --- a/entc/integration/migrate/entv1/user_create.go +++ b/entc/integration/migrate/entv1/user_create.go @@ -90,6 +90,20 @@ func (uc *UserCreate) SetNillableState(u *user.State) *UserCreate { return uc } +// SetStatus sets the status field. +func (uc *UserCreate) SetStatus(s string) *UserCreate { + uc.mutation.SetStatus(s) + return uc +} + +// SetNillableStatus sets the status field if the given value is not nil. +func (uc *UserCreate) SetNillableStatus(s *string) *UserCreate { + if s != nil { + uc.SetStatus(*s) + } + return uc +} + // SetID sets the id field. func (uc *UserCreate) SetID(i int) *UserCreate { uc.mutation.SetID(i) @@ -301,6 +315,14 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }) u.State = value } + if value, ok := uc.mutation.Status(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: user.FieldStatus, + }) + u.Status = value + } if nodes := uc.mutation.ParentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, diff --git a/entc/integration/migrate/entv1/user_update.go b/entc/integration/migrate/entv1/user_update.go index 20bfb30ec..77e368f89 100644 --- a/entc/integration/migrate/entv1/user_update.go +++ b/entc/integration/migrate/entv1/user_update.go @@ -129,6 +129,26 @@ func (uu *UserUpdate) ClearState() *UserUpdate { return uu } +// SetStatus sets the status field. +func (uu *UserUpdate) SetStatus(s string) *UserUpdate { + uu.mutation.SetStatus(s) + return uu +} + +// SetNillableStatus sets the status field if the given value is not nil. +func (uu *UserUpdate) SetNillableStatus(s *string) *UserUpdate { + if s != nil { + uu.SetStatus(*s) + } + return uu +} + +// ClearStatus clears the value of status. +func (uu *UserUpdate) ClearStatus() *UserUpdate { + uu.mutation.ClearStatus() + return uu +} + // SetParentID sets the parent edge to User by id. func (uu *UserUpdate) SetParentID(id int) *UserUpdate { uu.mutation.SetParentID(id) @@ -399,6 +419,19 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { Column: user.FieldState, }) } + if value, ok := uu.mutation.Status(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: user.FieldStatus, + }) + } + if uu.mutation.StatusCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Column: user.FieldStatus, + }) + } if uu.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, @@ -657,6 +690,26 @@ func (uuo *UserUpdateOne) ClearState() *UserUpdateOne { return uuo } +// SetStatus sets the status field. +func (uuo *UserUpdateOne) SetStatus(s string) *UserUpdateOne { + uuo.mutation.SetStatus(s) + return uuo +} + +// SetNillableStatus sets the status field if the given value is not nil. +func (uuo *UserUpdateOne) SetNillableStatus(s *string) *UserUpdateOne { + if s != nil { + uuo.SetStatus(*s) + } + return uuo +} + +// ClearStatus clears the value of status. +func (uuo *UserUpdateOne) ClearStatus() *UserUpdateOne { + uuo.mutation.ClearStatus() + return uuo +} + // SetParentID sets the parent edge to User by id. func (uuo *UserUpdateOne) SetParentID(id int) *UserUpdateOne { uuo.mutation.SetParentID(id) @@ -925,6 +978,19 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Column: user.FieldState, }) } + if value, ok := uuo.mutation.Status(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Value: value, + Column: user.FieldStatus, + }) + } + if uuo.mutation.StatusCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeString, + Column: user.FieldStatus, + }) + } if uuo.mutation.ParentCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, diff --git a/entc/integration/migrate/entv2/migrate/schema.go b/entc/integration/migrate/entv2/migrate/schema.go index 788beb777..05789a161 100644 --- a/entc/integration/migrate/entv2/migrate/schema.go +++ b/entc/integration/migrate/entv2/migrate/schema.go @@ -75,6 +75,7 @@ var ( {Name: "renamed", Type: field.TypeString, Nullable: true}, {Name: "blob", Type: field.TypeBytes, Nullable: true, Size: 1000}, {Name: "state", Type: field.TypeEnum, Nullable: true, Enums: []string{"logged_in", "logged_out", "online"}}, + {Name: "status", Type: field.TypeEnum, Nullable: true, Enums: []string{"done", "pending"}}, } // UsersTable holds the schema information for the "users" table. UsersTable = &schema.Table{ diff --git a/entc/integration/migrate/entv2/mutation.go b/entc/integration/migrate/entv2/mutation.go index cfa7b7874..de91f75ab 100644 --- a/entc/integration/migrate/entv2/mutation.go +++ b/entc/integration/migrate/entv2/mutation.go @@ -878,6 +878,7 @@ type UserMutation struct { new_name *string blob *[]byte state *user.State + status *user.Status clearedFields map[string]struct{} car map[int]struct{} removedcar map[int]struct{} @@ -1379,6 +1380,56 @@ func (m *UserMutation) ResetState() { delete(m.clearedFields, user.FieldState) } +// SetStatus sets the status field. +func (m *UserMutation) SetStatus(u user.Status) { + m.status = &u +} + +// Status returns the status value in the mutation. +func (m *UserMutation) Status() (r user.Status, exists bool) { + v := m.status + if v == nil { + return + } + return *v, true +} + +// OldStatus returns the old status value of the User. +// If the User object wasn't provided to the builder, the object is fetched +// from the database. +// An error is returned if the mutation operation is not UpdateOne, or database query fails. +func (m *UserMutation) OldStatus(ctx context.Context) (v user.Status, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldStatus is allowed only on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldStatus requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldStatus: %w", err) + } + return oldValue.Status, nil +} + +// ClearStatus clears the value of status. +func (m *UserMutation) ClearStatus() { + m.status = nil + m.clearedFields[user.FieldStatus] = struct{}{} +} + +// StatusCleared returns if the field status was cleared in this mutation. +func (m *UserMutation) StatusCleared() bool { + _, ok := m.clearedFields[user.FieldStatus] + return ok +} + +// ResetStatus reset all changes of the "status" field. +func (m *UserMutation) ResetStatus() { + m.status = nil + delete(m.clearedFields, user.FieldStatus) +} + // AddCarIDs adds the car edge to Car by ids. func (m *UserMutation) AddCarIDs(ids ...int) { if m.car == nil { @@ -1516,7 +1567,7 @@ func (m *UserMutation) Type() string { // this mutation. Note that, in order to get all numeric // fields that were in/decremented, call AddedFields(). func (m *UserMutation) Fields() []string { - fields := make([]string, 0, 9) + fields := make([]string, 0, 10) if m.age != nil { fields = append(fields, user.FieldAge) } @@ -1544,6 +1595,9 @@ func (m *UserMutation) Fields() []string { if m.state != nil { fields = append(fields, user.FieldState) } + if m.status != nil { + fields = append(fields, user.FieldStatus) + } return fields } @@ -1570,6 +1624,8 @@ func (m *UserMutation) Field(name string) (ent.Value, bool) { return m.Blob() case user.FieldState: return m.State() + case user.FieldStatus: + return m.Status() } return nil, false } @@ -1597,6 +1653,8 @@ func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, er return m.OldBlob(ctx) case user.FieldState: return m.OldState(ctx) + case user.FieldStatus: + return m.OldStatus(ctx) } return nil, fmt.Errorf("unknown User field %s", name) } @@ -1669,6 +1727,13 @@ func (m *UserMutation) SetField(name string, value ent.Value) error { } m.SetState(v) return nil + case user.FieldStatus: + v, ok := value.(user.Status) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetStatus(v) + return nil } return fmt.Errorf("unknown User field %s", name) } @@ -1726,6 +1791,9 @@ func (m *UserMutation) ClearedFields() []string { if m.FieldCleared(user.FieldState) { fields = append(fields, user.FieldState) } + if m.FieldCleared(user.FieldStatus) { + fields = append(fields, user.FieldStatus) + } return fields } @@ -1752,6 +1820,9 @@ func (m *UserMutation) ClearField(name string) error { case user.FieldState: m.ClearState() return nil + case user.FieldStatus: + m.ClearStatus() + return nil } return fmt.Errorf("unknown User nullable field %s", name) } @@ -1788,6 +1859,9 @@ func (m *UserMutation) ResetField(name string) error { case user.FieldState: m.ResetState() return nil + case user.FieldStatus: + m.ResetStatus() + return nil } return fmt.Errorf("unknown User field %s", name) } diff --git a/entc/integration/migrate/entv2/schema/user.go b/entc/integration/migrate/entv2/schema/user.go index a2c210139..4b59b2709 100644 --- a/entc/integration/migrate/entv2/schema/user.go +++ b/entc/integration/migrate/entv2/schema/user.go @@ -50,6 +50,10 @@ func (User) Fields() []ent.Field { field.Enum("state"). Optional(). Values("logged_in", "logged_out", "online"), + // convert string to enum. + field.Enum("status"). + Optional(). + Values("done", "pending"), // deleting the `address` column. } } diff --git a/entc/integration/migrate/entv2/user.go b/entc/integration/migrate/entv2/user.go index 118f59c3f..e2c7835e8 100644 --- a/entc/integration/migrate/entv2/user.go +++ b/entc/integration/migrate/entv2/user.go @@ -38,6 +38,8 @@ type User struct { Blob []byte `json:"blob,omitempty"` // State holds the value of the "state" field. State user.State `json:"state,omitempty"` + // Status holds the value of the "status" field. + Status user.Status `json:"status,omitempty"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the UserQuery when eager-loading is set. Edges UserEdges `json:"edges"` @@ -101,6 +103,7 @@ func (*User) scanValues() []interface{} { &sql.NullString{}, // new_name &[]byte{}, // blob &sql.NullString{}, // state + &sql.NullString{}, // status } } @@ -161,6 +164,11 @@ func (u *User) assignValues(values ...interface{}) error { } else if value.Valid { u.State = user.State(value.String) } + if value, ok := values[9].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field status", values[9]) + } else if value.Valid { + u.Status = user.Status(value.String) + } return nil } @@ -220,6 +228,8 @@ func (u *User) String() string { builder.WriteString(fmt.Sprintf("%v", u.Blob)) builder.WriteString(", state=") builder.WriteString(fmt.Sprintf("%v", u.State)) + builder.WriteString(", status=") + builder.WriteString(fmt.Sprintf("%v", u.Status)) builder.WriteByte(')') return builder.String() } diff --git a/entc/integration/migrate/entv2/user/user.go b/entc/integration/migrate/entv2/user/user.go index 44403cf2e..c3a3fb3f9 100644 --- a/entc/integration/migrate/entv2/user/user.go +++ b/entc/integration/migrate/entv2/user/user.go @@ -33,6 +33,8 @@ const ( FieldBlob = "blob" // FieldState holds the string denoting the state field in the database. FieldState = "state" + // FieldStatus holds the string denoting the status field in the database. + FieldStatus = "status" // EdgeCar holds the string denoting the car edge name in mutations. EdgeCar = "car" @@ -73,6 +75,7 @@ var Columns = []string{ FieldNewName, FieldBlob, FieldState, + FieldStatus, } var ( @@ -111,3 +114,26 @@ func StateValidator(s State) error { return fmt.Errorf("user: invalid enum value for state field: %q", s) } } + +// Status defines the type for the status enum field. +type Status string + +// Status values. +const ( + StatusDone Status = "done" + StatusPending Status = "pending" +) + +func (s Status) String() string { + return string(s) +} + +// StatusValidator is a validator for the "s" field enum values. It is called by the builders before save. +func StatusValidator(s Status) error { + switch s { + case StatusDone, StatusPending: + return nil + default: + return fmt.Errorf("user: invalid enum value for status field: %q", s) + } +} diff --git a/entc/integration/migrate/entv2/user/where.go b/entc/integration/migrate/entv2/user/where.go index f86bb86e1..14af9c6fb 100644 --- a/entc/integration/migrate/entv2/user/where.go +++ b/entc/integration/migrate/entv2/user/where.go @@ -1038,6 +1038,68 @@ func StateNotNil() predicate.User { }) } +// StatusEQ applies the EQ predicate on the "status" field. +func StatusEQ(v Status) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldStatus), v)) + }) +} + +// StatusNEQ applies the NEQ predicate on the "status" field. +func StatusNEQ(v Status) predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldStatus), v)) + }) +} + +// StatusIn applies the In predicate on the "status" field. +func StatusIn(vs ...Status) predicate.User { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.User(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldStatus), v...)) + }) +} + +// StatusNotIn applies the NotIn predicate on the "status" field. +func StatusNotIn(vs ...Status) predicate.User { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.User(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldStatus), v...)) + }) +} + +// StatusIsNil applies the IsNil predicate on the "status" field. +func StatusIsNil() predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.IsNull(s.C(FieldStatus))) + }) +} + +// StatusNotNil applies the NotNil predicate on the "status" field. +func StatusNotNil() predicate.User { + return predicate.User(func(s *sql.Selector) { + s.Where(sql.NotNull(s.C(FieldStatus))) + }) +} + // HasCar applies the HasEdge predicate on the "car" edge. func HasCar() predicate.User { return predicate.User(func(s *sql.Selector) { diff --git a/entc/integration/migrate/entv2/user_create.go b/entc/integration/migrate/entv2/user_create.go index e6e25b53e..d1fcfa744 100644 --- a/entc/integration/migrate/entv2/user_create.go +++ b/entc/integration/migrate/entv2/user_create.go @@ -111,6 +111,20 @@ func (uc *UserCreate) SetNillableState(u *user.State) *UserCreate { return uc } +// SetStatus sets the status field. +func (uc *UserCreate) SetStatus(u user.Status) *UserCreate { + uc.mutation.SetStatus(u) + return uc +} + +// SetNillableStatus sets the status field if the given value is not nil. +func (uc *UserCreate) SetNillableStatus(u *user.Status) *UserCreate { + if u != nil { + uc.SetStatus(*u) + } + return uc +} + // SetID sets the id field. func (uc *UserCreate) SetID(i int) *UserCreate { uc.mutation.SetID(i) @@ -195,6 +209,11 @@ func (uc *UserCreate) Save(ctx context.Context) (*User, error) { return nil, &ValidationError{Name: "state", err: fmt.Errorf("entv2: validator failed for field \"state\": %w", err)} } } + if v, ok := uc.mutation.Status(); ok { + if err := user.StatusValidator(v); err != nil { + return nil, &ValidationError{Name: "status", err: fmt.Errorf("entv2: validator failed for field \"status\": %w", err)} + } + } var ( err error node *User @@ -318,6 +337,14 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { }) u.State = value } + if value, ok := uc.mutation.Status(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeEnum, + Value: value, + Column: user.FieldStatus, + }) + u.Status = value + } if nodes := uc.mutation.CarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, diff --git a/entc/integration/migrate/entv2/user_update.go b/entc/integration/migrate/entv2/user_update.go index 2e004b081..9b4e12e1e 100644 --- a/entc/integration/migrate/entv2/user_update.go +++ b/entc/integration/migrate/entv2/user_update.go @@ -150,6 +150,26 @@ func (uu *UserUpdate) ClearState() *UserUpdate { return uu } +// SetStatus sets the status field. +func (uu *UserUpdate) SetStatus(u user.Status) *UserUpdate { + uu.mutation.SetStatus(u) + return uu +} + +// SetNillableStatus sets the status field if the given value is not nil. +func (uu *UserUpdate) SetNillableStatus(u *user.Status) *UserUpdate { + if u != nil { + uu.SetStatus(*u) + } + return uu +} + +// ClearStatus clears the value of status. +func (uu *UserUpdate) ClearStatus() *UserUpdate { + uu.mutation.ClearStatus() + return uu +} + // AddCarIDs adds the car edge to Car by ids. func (uu *UserUpdate) AddCarIDs(ids ...int) *UserUpdate { uu.mutation.AddCarIDs(ids...) @@ -247,6 +267,11 @@ func (uu *UserUpdate) Save(ctx context.Context) (int, error) { return 0, &ValidationError{Name: "state", err: fmt.Errorf("entv2: validator failed for field \"state\": %w", err)} } } + if v, ok := uu.mutation.Status(); ok { + if err := user.StatusValidator(v); err != nil { + return 0, &ValidationError{Name: "status", err: fmt.Errorf("entv2: validator failed for field \"status\": %w", err)} + } + } var ( err error @@ -409,6 +434,19 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { Column: user.FieldState, }) } + if value, ok := uu.mutation.Status(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeEnum, + Value: value, + Column: user.FieldStatus, + }) + } + if uu.mutation.StatusCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeEnum, + Column: user.FieldStatus, + }) + } if nodes := uu.mutation.RemovedCarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, @@ -655,6 +693,26 @@ func (uuo *UserUpdateOne) ClearState() *UserUpdateOne { return uuo } +// SetStatus sets the status field. +func (uuo *UserUpdateOne) SetStatus(u user.Status) *UserUpdateOne { + uuo.mutation.SetStatus(u) + return uuo +} + +// SetNillableStatus sets the status field if the given value is not nil. +func (uuo *UserUpdateOne) SetNillableStatus(u *user.Status) *UserUpdateOne { + if u != nil { + uuo.SetStatus(*u) + } + return uuo +} + +// ClearStatus clears the value of status. +func (uuo *UserUpdateOne) ClearStatus() *UserUpdateOne { + uuo.mutation.ClearStatus() + return uuo +} + // AddCarIDs adds the car edge to Car by ids. func (uuo *UserUpdateOne) AddCarIDs(ids ...int) *UserUpdateOne { uuo.mutation.AddCarIDs(ids...) @@ -752,6 +810,11 @@ func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { return nil, &ValidationError{Name: "state", err: fmt.Errorf("entv2: validator failed for field \"state\": %w", err)} } } + if v, ok := uuo.mutation.Status(); ok { + if err := user.StatusValidator(v); err != nil { + return nil, &ValidationError{Name: "status", err: fmt.Errorf("entv2: validator failed for field \"status\": %w", err)} + } + } var ( err error @@ -912,6 +975,19 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { Column: user.FieldState, }) } + if value, ok := uuo.mutation.Status(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeEnum, + Value: value, + Column: user.FieldStatus, + }) + } + if uuo.mutation.StatusCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeEnum, + Column: user.FieldStatus, + }) + } if nodes := uuo.mutation.RemovedCarIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M,