entc/gen: make generated client to implement the ent.Mutator interface (#3161)

This commit is contained in:
Ariel Mashraki
2022-12-09 21:18:25 +02:00
committed by GitHub
parent 3f4916ff8b
commit d0c5afa705
85 changed files with 3522 additions and 22 deletions

View File

@@ -29,6 +29,8 @@ type Card struct {
CreatedAt time.Time `json:"created_at,omitempty"`
// InHook is a mandatory field that is set by the hook.
InHook string `json:"in_hook,omitempty"`
// ExpiredAt holds the value of the "expired_at" field.
ExpiredAt time.Time `json:"expired_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the CardQuery when eager-loading is set.
Edges CardEdges `json:"edges"`
@@ -66,7 +68,7 @@ func (*Card) scanValues(columns []string) ([]any, error) {
values[i] = new(sql.NullInt64)
case card.FieldNumber, card.FieldName, card.FieldInHook:
values[i] = new(sql.NullString)
case card.FieldCreatedAt:
case card.FieldCreatedAt, card.FieldExpiredAt:
values[i] = new(sql.NullTime)
case card.ForeignKeys[0]: // user_cards
values[i] = new(sql.NullInt64)
@@ -115,6 +117,12 @@ func (c *Card) assignValues(columns []string, values []any) error {
} else if value.Valid {
c.InHook = value.String
}
case card.FieldExpiredAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field expired_at", values[i])
} else if value.Valid {
c.ExpiredAt = value.Time
}
case card.ForeignKeys[0]:
if value, ok := values[i].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for edge-field user_cards", value)
@@ -166,6 +174,9 @@ func (c *Card) String() string {
builder.WriteString(", ")
builder.WriteString("in_hook=")
builder.WriteString(c.InHook)
builder.WriteString(", ")
builder.WriteString("expired_at=")
builder.WriteString(c.ExpiredAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}

View File

@@ -25,6 +25,8 @@ const (
FieldCreatedAt = "created_at"
// FieldInHook holds the string denoting the in_hook field in the database.
FieldInHook = "in_hook"
// FieldExpiredAt holds the string denoting the expired_at field in the database.
FieldExpiredAt = "expired_at"
// EdgeOwner holds the string denoting the owner edge name in mutations.
EdgeOwner = "owner"
// Table holds the table name of the card in the database.
@@ -45,6 +47,7 @@ var Columns = []string{
FieldName,
FieldCreatedAt,
FieldInHook,
FieldExpiredAt,
}
// ForeignKeys holds the SQL foreign-keys that are owned by the "cards"

View File

@@ -113,6 +113,13 @@ func InHook(v string) predicate.Card {
})
}
// ExpiredAt applies equality check predicate on the "expired_at" field. It's identical to ExpiredAtEQ.
func ExpiredAt(v time.Time) predicate.Card {
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldExpiredAt), v))
})
}
// NumberEQ applies the EQ predicate on the "number" field.
func NumberEQ(v string) predicate.Card {
return predicate.Card(func(s *sql.Selector) {
@@ -488,6 +495,84 @@ func InHookContainsFold(v string) predicate.Card {
})
}
// ExpiredAtEQ applies the EQ predicate on the "expired_at" field.
func ExpiredAtEQ(v time.Time) predicate.Card {
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldExpiredAt), v))
})
}
// ExpiredAtNEQ applies the NEQ predicate on the "expired_at" field.
func ExpiredAtNEQ(v time.Time) predicate.Card {
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldExpiredAt), v))
})
}
// ExpiredAtIn applies the In predicate on the "expired_at" field.
func ExpiredAtIn(vs ...time.Time) predicate.Card {
v := make([]any, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.In(s.C(FieldExpiredAt), v...))
})
}
// ExpiredAtNotIn applies the NotIn predicate on the "expired_at" field.
func ExpiredAtNotIn(vs ...time.Time) predicate.Card {
v := make([]any, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.NotIn(s.C(FieldExpiredAt), v...))
})
}
// ExpiredAtGT applies the GT predicate on the "expired_at" field.
func ExpiredAtGT(v time.Time) predicate.Card {
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldExpiredAt), v))
})
}
// ExpiredAtGTE applies the GTE predicate on the "expired_at" field.
func ExpiredAtGTE(v time.Time) predicate.Card {
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldExpiredAt), v))
})
}
// ExpiredAtLT applies the LT predicate on the "expired_at" field.
func ExpiredAtLT(v time.Time) predicate.Card {
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldExpiredAt), v))
})
}
// ExpiredAtLTE applies the LTE predicate on the "expired_at" field.
func ExpiredAtLTE(v time.Time) predicate.Card {
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldExpiredAt), v))
})
}
// ExpiredAtIsNil applies the IsNil predicate on the "expired_at" field.
func ExpiredAtIsNil() predicate.Card {
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.IsNull(s.C(FieldExpiredAt)))
})
}
// ExpiredAtNotNil applies the NotNil predicate on the "expired_at" field.
func ExpiredAtNotNil() predicate.Card {
return predicate.Card(func(s *sql.Selector) {
s.Where(sql.NotNull(s.C(FieldExpiredAt)))
})
}
// HasOwner applies the HasEdge predicate on the "owner" edge.
func HasOwner() predicate.Card {
return predicate.Card(func(s *sql.Selector) {

View File

@@ -73,6 +73,20 @@ func (cc *CardCreate) SetInHook(s string) *CardCreate {
return cc
}
// SetExpiredAt sets the "expired_at" field.
func (cc *CardCreate) SetExpiredAt(t time.Time) *CardCreate {
cc.mutation.SetExpiredAt(t)
return cc
}
// SetNillableExpiredAt sets the "expired_at" field if the given value is not nil.
func (cc *CardCreate) SetNillableExpiredAt(t *time.Time) *CardCreate {
if t != nil {
cc.SetExpiredAt(*t)
}
return cc
}
// SetOwnerID sets the "owner" edge to the User entity by ID.
func (cc *CardCreate) SetOwnerID(id int) *CardCreate {
cc.mutation.SetOwnerID(id)
@@ -244,6 +258,10 @@ func (cc *CardCreate) createSpec() (*Card, *sqlgraph.CreateSpec) {
_spec.SetField(card.FieldInHook, field.TypeString, value)
_node.InHook = value
}
if value, ok := cc.mutation.ExpiredAt(); ok {
_spec.SetField(card.FieldExpiredAt, field.TypeTime, value)
_node.ExpiredAt = value
}
if nodes := cc.mutation.OwnerIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,

View File

@@ -73,6 +73,26 @@ func (cu *CardUpdate) SetInHook(s string) *CardUpdate {
return cu
}
// SetExpiredAt sets the "expired_at" field.
func (cu *CardUpdate) SetExpiredAt(t time.Time) *CardUpdate {
cu.mutation.SetExpiredAt(t)
return cu
}
// SetNillableExpiredAt sets the "expired_at" field if the given value is not nil.
func (cu *CardUpdate) SetNillableExpiredAt(t *time.Time) *CardUpdate {
if t != nil {
cu.SetExpiredAt(*t)
}
return cu
}
// ClearExpiredAt clears the value of the "expired_at" field.
func (cu *CardUpdate) ClearExpiredAt() *CardUpdate {
cu.mutation.ClearExpiredAt()
return cu
}
// SetOwnerID sets the "owner" edge to the User entity by ID.
func (cu *CardUpdate) SetOwnerID(id int) *CardUpdate {
cu.mutation.SetOwnerID(id)
@@ -187,6 +207,12 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) {
if value, ok := cu.mutation.InHook(); ok {
_spec.SetField(card.FieldInHook, field.TypeString, value)
}
if value, ok := cu.mutation.ExpiredAt(); ok {
_spec.SetField(card.FieldExpiredAt, field.TypeTime, value)
}
if cu.mutation.ExpiredAtCleared() {
_spec.ClearField(card.FieldExpiredAt, field.TypeTime)
}
if cu.mutation.OwnerCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
@@ -281,6 +307,26 @@ func (cuo *CardUpdateOne) SetInHook(s string) *CardUpdateOne {
return cuo
}
// SetExpiredAt sets the "expired_at" field.
func (cuo *CardUpdateOne) SetExpiredAt(t time.Time) *CardUpdateOne {
cuo.mutation.SetExpiredAt(t)
return cuo
}
// SetNillableExpiredAt sets the "expired_at" field if the given value is not nil.
func (cuo *CardUpdateOne) SetNillableExpiredAt(t *time.Time) *CardUpdateOne {
if t != nil {
cuo.SetExpiredAt(*t)
}
return cuo
}
// ClearExpiredAt clears the value of the "expired_at" field.
func (cuo *CardUpdateOne) ClearExpiredAt() *CardUpdateOne {
cuo.mutation.ClearExpiredAt()
return cuo
}
// SetOwnerID sets the "owner" edge to the User entity by ID.
func (cuo *CardUpdateOne) SetOwnerID(id int) *CardUpdateOne {
cuo.mutation.SetOwnerID(id)
@@ -425,6 +471,12 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (_node *Card, err error)
if value, ok := cuo.mutation.InHook(); ok {
_spec.SetField(card.FieldInHook, field.TypeString, value)
}
if value, ok := cuo.mutation.ExpiredAt(); ok {
_spec.SetField(card.FieldExpiredAt, field.TypeTime, value)
}
if cuo.mutation.ExpiredAtCleared() {
_spec.ClearField(card.FieldExpiredAt, field.TypeTime)
}
if cuo.mutation.OwnerCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,

View File

@@ -134,6 +134,18 @@ func (c *Client) Use(hooks ...Hook) {
c.User.Use(hooks...)
}
// Mutate implements the ent.Mutator interface.
func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
switch m := m.(type) {
case *CardMutation:
return c.Card.mutate(ctx, m)
case *UserMutation:
return c.User.mutate(ctx, m)
default:
return nil, fmt.Errorf("ent: unknown mutation type %T", m)
}
}
// CardClient is a client for the Card schema.
type CardClient struct {
config
@@ -241,6 +253,21 @@ func (c *CardClient) Hooks() []Hook {
return append(hooks[:len(hooks):len(hooks)], card.Hooks[:]...)
}
func (c *CardClient) mutate(ctx context.Context, m *CardMutation) (Value, error) {
switch m.Op() {
case OpCreate:
return (&CardCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdate:
return (&CardUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdateOne:
return (&CardUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpDelete, OpDeleteOne:
return (&CardDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
default:
return nil, fmt.Errorf("ent: unknown Card mutation op: %q", m.Op())
}
}
// UserClient is a client for the User schema.
type UserClient struct {
config
@@ -379,3 +406,18 @@ func (c *UserClient) Hooks() []Hook {
hooks := c.hooks.User
return append(hooks[:len(hooks):len(hooks)], user.Hooks[:]...)
}
func (c *UserClient) mutate(ctx context.Context, m *UserMutation) (Value, error) {
switch m.Op() {
case OpCreate:
return (&UserCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdate:
return (&UserUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdateOne:
return (&UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpDelete, OpDeleteOne:
return (&UserDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
default:
return nil, fmt.Errorf("ent: unknown User mutation op: %q", m.Op())
}
}

View File

@@ -10,4 +10,4 @@
// Package internal holds a loadable version of the latest schema.
package internal
const Schema = `{"Schema":"entgo.io/ent/entc/integration/hooks/ent/schema","Package":"entgo.io/ent/entc/integration/hooks/ent","Schemas":[{"name":"Card","config":{"Table":""},"edges":[{"name":"owner","type":"User","ref_name":"cards","unique":true,"inverse":true}],"fields":[{"name":"number","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"default":true,"default_value":"unknown","default_kind":24,"immutable":true,"validators":1,"position":{"Index":0,"MixedIn":false,"MixinIndex":0}},{"name":"name","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"position":{"Index":1,"MixedIn":false,"MixinIndex":0},"comment":"Exact name written on card"},{"name":"created_at","type":{"Type":2,"Ident":"","PkgPath":"time","PkgName":"","Nillable":false,"RType":null},"default":true,"default_kind":19,"position":{"Index":2,"MixedIn":false,"MixinIndex":0}},{"name":"in_hook","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"position":{"Index":3,"MixedIn":false,"MixinIndex":0},"comment":"InHook is a mandatory field that is set by the hook."}],"hooks":[{"Index":0,"MixedIn":true,"MixinIndex":0},{"Index":0,"MixedIn":false,"MixinIndex":0},{"Index":1,"MixedIn":false,"MixinIndex":0}]},{"name":"User","config":{"Table":""},"edges":[{"name":"cards","type":"Card"},{"name":"friends","type":"User"},{"name":"best_friend","type":"User","unique":true}],"fields":[{"name":"version","type":{"Type":12,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"default":true,"default_value":0,"default_kind":2,"position":{"Index":0,"MixedIn":true,"MixinIndex":0}},{"name":"name","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"position":{"Index":0,"MixedIn":false,"MixinIndex":0}},{"name":"worth","type":{"Type":17,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"position":{"Index":1,"MixedIn":false,"MixinIndex":0}},{"name":"password","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"position":{"Index":2,"MixedIn":false,"MixinIndex":0},"sensitive":true}],"hooks":[{"Index":0,"MixedIn":true,"MixinIndex":0},{"Index":0,"MixedIn":false,"MixinIndex":0}]}],"Features":["schema/snapshot"]}`
const Schema = `{"Schema":"entgo.io/ent/entc/integration/hooks/ent/schema","Package":"entgo.io/ent/entc/integration/hooks/ent","Schemas":[{"name":"Card","config":{"Table":""},"edges":[{"name":"owner","type":"User","ref_name":"cards","unique":true,"inverse":true}],"fields":[{"name":"number","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"default":true,"default_value":"unknown","default_kind":24,"immutable":true,"validators":1,"position":{"Index":0,"MixedIn":false,"MixinIndex":0}},{"name":"name","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"position":{"Index":1,"MixedIn":false,"MixinIndex":0},"comment":"Exact name written on card"},{"name":"created_at","type":{"Type":2,"Ident":"","PkgPath":"time","PkgName":"","Nillable":false,"RType":null},"default":true,"default_kind":19,"position":{"Index":2,"MixedIn":false,"MixinIndex":0}},{"name":"in_hook","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"position":{"Index":3,"MixedIn":false,"MixinIndex":0},"comment":"InHook is a mandatory field that is set by the hook."},{"name":"expired_at","type":{"Type":2,"Ident":"","PkgPath":"time","PkgName":"","Nillable":false,"RType":null},"optional":true,"position":{"Index":4,"MixedIn":false,"MixinIndex":0}}],"hooks":[{"Index":0,"MixedIn":true,"MixinIndex":0},{"Index":0,"MixedIn":false,"MixinIndex":0},{"Index":1,"MixedIn":false,"MixinIndex":0}]},{"name":"User","config":{"Table":""},"edges":[{"name":"cards","type":"Card"},{"name":"friends","type":"User"},{"name":"best_friend","type":"User","unique":true}],"fields":[{"name":"version","type":{"Type":12,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"default":true,"default_value":0,"default_kind":2,"position":{"Index":0,"MixedIn":true,"MixinIndex":0}},{"name":"name","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"position":{"Index":0,"MixedIn":false,"MixinIndex":0}},{"name":"worth","type":{"Type":17,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"position":{"Index":1,"MixedIn":false,"MixinIndex":0}},{"name":"password","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"position":{"Index":2,"MixedIn":false,"MixinIndex":0},"sensitive":true}],"hooks":[{"Index":0,"MixedIn":true,"MixinIndex":0},{"Index":0,"MixedIn":false,"MixinIndex":0}]}],"Features":["schema/snapshot"]}`

View File

@@ -19,6 +19,7 @@ var (
{Name: "name", Type: field.TypeString, Nullable: true},
{Name: "created_at", Type: field.TypeTime},
{Name: "in_hook", Type: field.TypeString},
{Name: "expired_at", Type: field.TypeTime, Nullable: true},
{Name: "user_cards", Type: field.TypeInt, Nullable: true},
}
// CardsTable holds the schema information for the "cards" table.
@@ -29,7 +30,7 @@ var (
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "cards_users_cards",
Columns: []*schema.Column{CardsColumns[5]},
Columns: []*schema.Column{CardsColumns[6]},
RefColumns: []*schema.Column{UsersColumns[0]},
OnDelete: schema.SetNull,
},

View File

@@ -43,6 +43,7 @@ type CardMutation struct {
name *string
created_at *time.Time
in_hook *string
expired_at *time.Time
clearedFields map[string]struct{}
owner *int
clearedowner bool
@@ -306,6 +307,55 @@ func (m *CardMutation) ResetInHook() {
m.in_hook = nil
}
// SetExpiredAt sets the "expired_at" field.
func (m *CardMutation) SetExpiredAt(t time.Time) {
m.expired_at = &t
}
// ExpiredAt returns the value of the "expired_at" field in the mutation.
func (m *CardMutation) ExpiredAt() (r time.Time, exists bool) {
v := m.expired_at
if v == nil {
return
}
return *v, true
}
// OldExpiredAt returns the old "expired_at" field's value of the Card entity.
// If the Card 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 the database query fails.
func (m *CardMutation) OldExpiredAt(ctx context.Context) (v time.Time, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldExpiredAt is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldExpiredAt requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldExpiredAt: %w", err)
}
return oldValue.ExpiredAt, nil
}
// ClearExpiredAt clears the value of the "expired_at" field.
func (m *CardMutation) ClearExpiredAt() {
m.expired_at = nil
m.clearedFields[card.FieldExpiredAt] = struct{}{}
}
// ExpiredAtCleared returns if the "expired_at" field was cleared in this mutation.
func (m *CardMutation) ExpiredAtCleared() bool {
_, ok := m.clearedFields[card.FieldExpiredAt]
return ok
}
// ResetExpiredAt resets all changes to the "expired_at" field.
func (m *CardMutation) ResetExpiredAt() {
m.expired_at = nil
delete(m.clearedFields, card.FieldExpiredAt)
}
// SetOwnerID sets the "owner" edge to the User entity by id.
func (m *CardMutation) SetOwnerID(id int) {
m.owner = &id
@@ -355,6 +405,11 @@ func (m *CardMutation) Op() Op {
return m.op
}
// SetOp allows setting the mutation operation.
func (m *CardMutation) SetOp(op Op) {
m.op = op
}
// Type returns the node type of this mutation (Card).
func (m *CardMutation) Type() string {
return m.typ
@@ -364,7 +419,7 @@ func (m *CardMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *CardMutation) Fields() []string {
fields := make([]string, 0, 4)
fields := make([]string, 0, 5)
if m.number != nil {
fields = append(fields, card.FieldNumber)
}
@@ -377,6 +432,9 @@ func (m *CardMutation) Fields() []string {
if m.in_hook != nil {
fields = append(fields, card.FieldInHook)
}
if m.expired_at != nil {
fields = append(fields, card.FieldExpiredAt)
}
return fields
}
@@ -393,6 +451,8 @@ func (m *CardMutation) Field(name string) (ent.Value, bool) {
return m.CreatedAt()
case card.FieldInHook:
return m.InHook()
case card.FieldExpiredAt:
return m.ExpiredAt()
}
return nil, false
}
@@ -410,6 +470,8 @@ func (m *CardMutation) OldField(ctx context.Context, name string) (ent.Value, er
return m.OldCreatedAt(ctx)
case card.FieldInHook:
return m.OldInHook(ctx)
case card.FieldExpiredAt:
return m.OldExpiredAt(ctx)
}
return nil, fmt.Errorf("unknown Card field %s", name)
}
@@ -447,6 +509,13 @@ func (m *CardMutation) SetField(name string, value ent.Value) error {
}
m.SetInHook(v)
return nil
case card.FieldExpiredAt:
v, ok := value.(time.Time)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetExpiredAt(v)
return nil
}
return fmt.Errorf("unknown Card field %s", name)
}
@@ -480,6 +549,9 @@ func (m *CardMutation) ClearedFields() []string {
if m.FieldCleared(card.FieldName) {
fields = append(fields, card.FieldName)
}
if m.FieldCleared(card.FieldExpiredAt) {
fields = append(fields, card.FieldExpiredAt)
}
return fields
}
@@ -497,6 +569,9 @@ func (m *CardMutation) ClearField(name string) error {
case card.FieldName:
m.ClearName()
return nil
case card.FieldExpiredAt:
m.ClearExpiredAt()
return nil
}
return fmt.Errorf("unknown Card nullable field %s", name)
}
@@ -517,6 +592,9 @@ func (m *CardMutation) ResetField(name string) error {
case card.FieldInHook:
m.ResetInHook()
return nil
case card.FieldExpiredAt:
m.ResetExpiredAt()
return nil
}
return fmt.Errorf("unknown Card field %s", name)
}
@@ -1087,6 +1165,11 @@ func (m *UserMutation) Op() Op {
return m.op
}
// SetOp allows setting the mutation operation.
func (m *UserMutation) SetOp(op Op) {
m.op = op
}
// Type returns the node type of this mutation (User).
func (m *UserMutation) Type() string {
return m.typ

View File

@@ -18,7 +18,7 @@ import (
"entgo.io/ent/schema/mixin"
)
// RejectUpdate rejects all update operations
// RejectUpdate rejects ~all update operations
// that are not on a specific entity.
type RejectUpdate struct {
mixin.Schema
@@ -26,7 +26,11 @@ type RejectUpdate struct {
func (RejectUpdate) Hooks() []ent.Hook {
return []ent.Hook{
hook.Reject(ent.OpUpdate),
hook.If(
hook.Reject(ent.OpUpdate),
// Accept only updates that contains the "expired_at" field.
hook.Not(hook.HasFields(card.FieldExpiredAt)),
),
}
}
@@ -84,6 +88,8 @@ func (Card) Fields() []ent.Field {
Default(time.Now),
field.String("in_hook").
Comment("InHook is a mandatory field that is set by the hook."),
field.Time("expired_at").
Optional(),
}
}

View File

@@ -9,6 +9,7 @@ import (
"fmt"
"sort"
"testing"
"time"
"entgo.io/ent/entc/integration/hooks/ent"
"entgo.io/ent/entc/integration/hooks/ent/card"
@@ -105,6 +106,48 @@ func TestMutationClient(t *testing.T) {
require.Equal(t, a8m.Name, crd.Name)
}
func TestMutatorClient(t *testing.T) {
ctx := context.Background()
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()
client.Use(
hook.On(
func(next ent.Mutator) ent.Mutator {
return hook.CardFunc(func(ctx context.Context, m *ent.CardMutation) (ent.Value, error) {
op := ent.OpUpdate
if _, exists := m.ID(); exists && m.Op().Is(ent.OpDeleteOne) {
op = ent.OpUpdateOne
}
// Change the operation to update.
m.SetOp(op)
// Record when card was expired.
m.SetExpiredAt(time.Now())
// Ensure card was not expired before.
m.Where(card.ExpiredAtIsNil())
return m.Client().Mutate(ctx, m)
})
},
ent.OpDelete|ent.OpDeleteOne,
),
)
c1 := client.Card.Create().SetNumber("1234").SaveX(ctx)
client.Card.DeleteOne(c1).ExecX(ctx)
expired := client.Card.Query().OnlyX(ctx)
require.False(t, expired.ExpiredAt.IsZero())
client.Card.Create().SetNumber("4567").ExecX(ctx)
client.Card.Create().SetNumber("7890").ExecX(ctx)
client.Card.Delete().Where(card.Number("4567")).ExecX(ctx)
cards := client.Card.Query().Order(ent.Asc(card.FieldNumber)).AllX(ctx)
require.Len(t, cards, 3)
require.True(t, cards[0].ExpiredAt.Equal(expired.ExpiredAt), "expired field should not be updated")
require.False(t, cards[1].ExpiredAt.IsZero())
require.True(t, cards[2].ExpiredAt.IsZero())
client.Card.Delete().ExecX(ctx)
require.False(t, client.Card.Query().Where(card.ExpiredAtIsNil()).ExistX(ctx))
}
func TestMutationTx(t *testing.T) {
ctx := context.Background()
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1", enttest.WithMigrateOptions(migrate.WithGlobalUniqueID(true)))