ent/field: add update_default option time field

Reviewed By: alexsn

Differential Revision: D17070907

fbshipit-source-id: 63c9ce75c58e524044c38f9461cb04e8e45c8017
This commit is contained in:
Ariel Mashraki
2019-08-27 06:53:44 -07:00
committed by Facebook Github Bot
parent bd07c86b60
commit 772b8a33f8
30 changed files with 376 additions and 100 deletions

View File

@@ -21,6 +21,8 @@ type Card struct {
Number string `json:"number,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
}
// FromRows scans the sql response data into Card.
@@ -29,18 +31,21 @@ func (c *Card) FromRows(rows *sql.Rows) error {
ID int
Number sql.NullString
CreatedAt sql.NullTime
UpdatedAt sql.NullTime
}
// the order here should be the same as in the `card.Columns`.
if err := rows.Scan(
&vc.ID,
&vc.Number,
&vc.CreatedAt,
&vc.UpdatedAt,
); err != nil {
return err
}
c.ID = strconv.Itoa(vc.ID)
c.Number = vc.Number.String
c.CreatedAt = vc.CreatedAt.Time
c.UpdatedAt = vc.UpdatedAt.Time
return nil
}
@@ -54,6 +59,7 @@ func (c *Card) FromResponse(res *gremlin.Response) error {
ID string `json:"id,omitempty"`
Number string `json:"number,omitempty"`
CreatedAt int64 `json:"created_at,omitempty"`
UpdatedAt int64 `json:"updated_at,omitempty"`
}
if err := vmap.Decode(&vc); err != nil {
return err
@@ -61,6 +67,7 @@ func (c *Card) FromResponse(res *gremlin.Response) error {
c.ID = vc.ID
c.Number = vc.Number
c.CreatedAt = time.Unix(vc.CreatedAt, 0)
c.UpdatedAt = time.Unix(vc.UpdatedAt, 0)
return nil
}
@@ -94,6 +101,7 @@ func (c *Card) String() string {
buf.WriteString(fmt.Sprintf("id=%v", c.ID))
buf.WriteString(fmt.Sprintf(", number=%v", c.Number))
buf.WriteString(fmt.Sprintf(", created_at=%v", c.CreatedAt))
buf.WriteString(fmt.Sprintf(", updated_at=%v", c.UpdatedAt))
buf.WriteString(")")
return buf.String()
}
@@ -129,6 +137,7 @@ func (c *Cards) FromResponse(res *gremlin.Response) error {
ID string `json:"id,omitempty"`
Number string `json:"number,omitempty"`
CreatedAt int64 `json:"created_at,omitempty"`
UpdatedAt int64 `json:"updated_at,omitempty"`
}
if err := vmap.Decode(&vc); err != nil {
return err
@@ -137,7 +146,8 @@ func (c *Cards) FromResponse(res *gremlin.Response) error {
*c = append(*c, &Card{
ID: v.ID,
Number: v.Number,
CreatedAt: time.Unix(v.CreatedAt, 0),
CreatedAt: time.Unix(0, v.CreatedAt),
UpdatedAt: time.Unix(0, v.UpdatedAt),
})
}
return nil

View File

@@ -17,6 +17,8 @@ const (
FieldNumber = "number"
// FieldCreatedAt holds the string denoting the created_at vertex property in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at vertex property in the database.
FieldUpdatedAt = "updated_at"
// Table holds the table name of the card in the database.
Table = "cards"
@@ -37,6 +39,7 @@ var Columns = []string{
FieldID,
FieldNumber,
FieldCreatedAt,
FieldUpdatedAt,
}
var (
@@ -47,6 +50,12 @@ var (
NumberValidator = descNumber.Validators[0].(func(string) error)
// descCreatedAt is the schema descriptor for created_at field.
descCreatedAt = fields[1].Descriptor()
// DefaultCreatedAt holds the default value for the created_at field.
// DefaultCreatedAt holds the default value on creation for the created_at field.
DefaultCreatedAt = descCreatedAt.Default.(func() time.Time)
// descUpdatedAt is the schema descriptor for updated_at field.
descUpdatedAt = fields[2].Descriptor()
// DefaultUpdatedAt holds the default value on creation for the updated_at field.
DefaultUpdatedAt = descUpdatedAt.Default.(func() time.Time)
// UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
UpdateDefaultUpdatedAt = descUpdatedAt.UpdateDefault.(func() time.Time)
)

View File

@@ -181,6 +181,18 @@ func CreatedAt(v time.Time) predicate.Card {
)
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v time.Time) predicate.Card {
return predicate.CardPerDialect(
func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
},
func(t *dsl.Traversal) {
t.Has(Label, FieldUpdatedAt, p.EQ(v))
},
)
}
// NumberEQ applies the EQ predicate on the "number" field.
func NumberEQ(v string) predicate.Card {
return predicate.CardPerDialect(
@@ -449,6 +461,122 @@ func CreatedAtNotIn(vs ...time.Time) predicate.Card {
)
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v time.Time) predicate.Card {
return predicate.CardPerDialect(
func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
},
func(t *dsl.Traversal) {
t.Has(Label, FieldUpdatedAt, p.EQ(v))
},
)
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v time.Time) predicate.Card {
return predicate.CardPerDialect(
func(s *sql.Selector) {
s.Where(sql.NEQ(s.C(FieldUpdatedAt), v))
},
func(t *dsl.Traversal) {
t.Has(Label, FieldUpdatedAt, p.NEQ(v))
},
)
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v time.Time) predicate.Card {
return predicate.CardPerDialect(
func(s *sql.Selector) {
s.Where(sql.GT(s.C(FieldUpdatedAt), v))
},
func(t *dsl.Traversal) {
t.Has(Label, FieldUpdatedAt, p.GT(v))
},
)
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v time.Time) predicate.Card {
return predicate.CardPerDialect(
func(s *sql.Selector) {
s.Where(sql.GTE(s.C(FieldUpdatedAt), v))
},
func(t *dsl.Traversal) {
t.Has(Label, FieldUpdatedAt, p.GTE(v))
},
)
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v time.Time) predicate.Card {
return predicate.CardPerDialect(
func(s *sql.Selector) {
s.Where(sql.LT(s.C(FieldUpdatedAt), v))
},
func(t *dsl.Traversal) {
t.Has(Label, FieldUpdatedAt, p.LT(v))
},
)
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v time.Time) predicate.Card {
return predicate.CardPerDialect(
func(s *sql.Selector) {
s.Where(sql.LTE(s.C(FieldUpdatedAt), v))
},
func(t *dsl.Traversal) {
t.Has(Label, FieldUpdatedAt, p.LTE(v))
},
)
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...time.Time) predicate.Card {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.CardPerDialect(
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(vs) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.In(s.C(FieldUpdatedAt), v...))
},
func(t *dsl.Traversal) {
t.Has(Label, FieldUpdatedAt, p.Within(v...))
},
)
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...time.Time) predicate.Card {
v := make([]interface{}, len(vs))
for i := range v {
v[i] = vs[i]
}
return predicate.CardPerDialect(
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(vs) == 0 {
s.Where(sql.False())
return
}
s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...))
},
func(t *dsl.Traversal) {
t.Has(Label, FieldUpdatedAt, p.Without(v...))
},
)
}
// HasOwner applies the HasEdge predicate on the "owner" edge.
func HasOwner() predicate.Card {
return predicate.CardPerDialect(

View File

@@ -26,6 +26,7 @@ type CardCreate struct {
config
number *string
created_at *time.Time
updated_at *time.Time
owner map[string]struct{}
}
@@ -49,6 +50,20 @@ func (cc *CardCreate) SetNillableCreatedAt(t *time.Time) *CardCreate {
return cc
}
// SetUpdatedAt sets the updated_at field.
func (cc *CardCreate) SetUpdatedAt(t time.Time) *CardCreate {
cc.updated_at = &t
return cc
}
// SetNillableUpdatedAt sets the updated_at field if the given value is not nil.
func (cc *CardCreate) SetNillableUpdatedAt(t *time.Time) *CardCreate {
if t != nil {
cc.SetUpdatedAt(*t)
}
return cc
}
// SetOwnerID sets the owner edge to User by id.
func (cc *CardCreate) SetOwnerID(id string) *CardCreate {
if cc.owner == nil {
@@ -83,6 +98,10 @@ func (cc *CardCreate) Save(ctx context.Context) (*Card, error) {
v := card.DefaultCreatedAt()
cc.created_at = &v
}
if cc.updated_at == nil {
v := card.DefaultUpdatedAt()
cc.updated_at = &v
}
if len(cc.owner) > 1 {
return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"")
}
@@ -123,6 +142,10 @@ func (cc *CardCreate) sqlSave(ctx context.Context) (*Card, error) {
builder.Set(card.FieldCreatedAt, *cc.created_at)
c.CreatedAt = *cc.created_at
}
if cc.updated_at != nil {
builder.Set(card.FieldUpdatedAt, *cc.updated_at)
c.UpdatedAt = *cc.updated_at
}
query, args := builder.Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
@@ -187,6 +210,9 @@ func (cc *CardCreate) gremlin() *dsl.Traversal {
if cc.created_at != nil {
v.Property(dsl.Single, card.FieldCreatedAt, *cc.created_at)
}
if cc.updated_at != nil {
v.Property(dsl.Single, card.FieldUpdatedAt, *cc.updated_at)
}
for id := range cc.owner {
v.AddE(user.CardLabel).From(g.V(id)).InV()
constraints = append(constraints, &constraint{

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"strconv"
"time"
"github.com/facebookincubator/ent/entc/integration/ent/card"
"github.com/facebookincubator/ent/entc/integration/ent/predicate"
@@ -24,7 +25,9 @@ import (
// CardUpdate is the builder for updating Card entities.
type CardUpdate struct {
config
number *string
number *string
updated_at *time.Time
owner map[string]struct{}
clearedOwner bool
predicates []predicate.Card
@@ -77,6 +80,10 @@ func (cu *CardUpdate) Save(ctx context.Context) (int, error) {
return 0, fmt.Errorf("ent: validator failed for field \"number\": %v", err)
}
}
if cu.updated_at == nil {
v := card.UpdateDefaultUpdatedAt()
cu.updated_at = &v
}
if len(cu.owner) > 1 {
return 0, errors.New("ent: multiple assignments on a unique edge \"owner\"")
}
@@ -148,6 +155,10 @@ func (cu *CardUpdate) sqlSave(ctx context.Context) (n int, err error) {
update = true
builder.Set(card.FieldNumber, *cu.number)
}
if cu.updated_at != nil {
update = true
builder.Set(card.FieldUpdatedAt, *cu.updated_at)
}
if update {
query, args := builder.Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
@@ -222,6 +233,9 @@ func (cu *CardUpdate) gremlin() *dsl.Traversal {
if cu.number != nil {
v.Property(dsl.Single, card.FieldNumber, *cu.number)
}
if cu.updated_at != nil {
v.Property(dsl.Single, card.FieldUpdatedAt, *cu.updated_at)
}
if cu.clearedOwner {
tr := rv.Clone().InE(user.CardLabel).Drop().Iterate()
trs = append(trs, tr)
@@ -251,8 +265,10 @@ func (cu *CardUpdate) gremlin() *dsl.Traversal {
// CardUpdateOne is the builder for updating a single Card entity.
type CardUpdateOne struct {
config
id string
number *string
id string
number *string
updated_at *time.Time
owner map[string]struct{}
clearedOwner bool
}
@@ -298,6 +314,10 @@ func (cuo *CardUpdateOne) Save(ctx context.Context) (*Card, error) {
return nil, fmt.Errorf("ent: validator failed for field \"number\": %v", err)
}
}
if cuo.updated_at == nil {
v := card.UpdateDefaultUpdatedAt()
cuo.updated_at = &v
}
if len(cuo.owner) > 1 {
return nil, errors.New("ent: multiple assignments on a unique edge \"owner\"")
}
@@ -373,6 +393,11 @@ func (cuo *CardUpdateOne) sqlSave(ctx context.Context) (c *Card, err error) {
builder.Set(card.FieldNumber, *cuo.number)
c.Number = *cuo.number
}
if cuo.updated_at != nil {
update = true
builder.Set(card.FieldUpdatedAt, *cuo.updated_at)
c.UpdatedAt = *cuo.updated_at
}
if update {
query, args := builder.Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
@@ -448,6 +473,9 @@ func (cuo *CardUpdateOne) gremlin(id string) *dsl.Traversal {
if cuo.number != nil {
v.Property(dsl.Single, card.FieldNumber, *cuo.number)
}
if cuo.updated_at != nil {
v.Property(dsl.Single, card.FieldUpdatedAt, *cuo.updated_at)
}
if cuo.clearedOwner {
tr := rv.Clone().InE(user.CardLabel).Drop().Iterate()
trs = append(trs, tr)

View File

@@ -34,6 +34,7 @@ func ExampleCard() {
Create().
SetNumber("string").
SetCreatedAt(time.Now()).
SetUpdatedAt(time.Now()).
SaveX(ctx)
log.Println("card created:", c)
@@ -342,6 +343,7 @@ func ExampleUser() {
Create().
SetNumber("string").
SetCreatedAt(time.Now()).
SetUpdatedAt(time.Now()).
SaveX(ctx)
log.Println("card created:", c0)
pe1 := client.Pet.

View File

@@ -56,7 +56,7 @@ var (
fields = schema.File{}.Fields()
// descSize is the schema descriptor for size field.
descSize = fields[0].Descriptor()
// DefaultSize holds the default value for the size field.
// DefaultSize holds the default value on creation for the size field.
DefaultSize = descSize.Default.(int)
// SizeValidator is a validator for the "size" field. It is called by the builders before save.
SizeValidator = descSize.Validators[0].(func(int) error)

View File

@@ -184,7 +184,7 @@ func (gr *Groups) FromResponse(res *gremlin.Response) error {
*gr = append(*gr, &Group{
ID: v.ID,
Active: v.Active,
Expire: time.Unix(v.Expire, 0),
Expire: time.Unix(0, v.Expire),
Type: v.Type,
MaxUsers: v.MaxUsers,
Name: v.Name,

View File

@@ -81,7 +81,7 @@ var (
fields = schema.Group{}.Fields()
// descActive is the schema descriptor for active field.
descActive = fields[0].Descriptor()
// DefaultActive holds the default value for the active field.
// DefaultActive holds the default value on creation for the active field.
DefaultActive = descActive.Default.(bool)
// descType is the schema descriptor for type field.
descType = fields[2].Descriptor()
@@ -89,7 +89,7 @@ var (
TypeValidator = descType.Validators[0].(func(string) error)
// descMaxUsers is the schema descriptor for max_users field.
descMaxUsers = fields[3].Descriptor()
// DefaultMaxUsers holds the default value for the max_users field.
// DefaultMaxUsers holds the default value on creation for the max_users field.
DefaultMaxUsers = descMaxUsers.Default.(int)
// MaxUsersValidator is a validator for the "max_users" field. It is called by the builders before save.
MaxUsersValidator = descMaxUsers.Validators[0].(func(int) error)

View File

@@ -41,6 +41,6 @@ var (
fields = schema.GroupInfo{}.Fields()
// descMaxUsers is the schema descriptor for max_users field.
descMaxUsers = fields[1].Descriptor()
// DefaultMaxUsers holds the default value for the max_users field.
// DefaultMaxUsers holds the default value on creation for the max_users field.
DefaultMaxUsers = descMaxUsers.Default.(int)
)

View File

@@ -17,6 +17,7 @@ var (
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "number", Type: field.TypeString},
{Name: "created_at", Type: field.TypeTime},
{Name: "updated_at", Type: field.TypeTime},
{Name: "owner_id", Type: field.TypeInt, Unique: true, Nullable: true},
}
// CardsTable holds the schema information for the "cards" table.
@@ -27,7 +28,7 @@ var (
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "cards_users_card",
Columns: []*schema.Column{CardsColumns[3]},
Columns: []*schema.Column{CardsColumns[4]},
RefColumns: []*schema.Column{UsersColumns[0]},
OnDelete: schema.SetNull,

View File

@@ -25,6 +25,10 @@ func (Card) Fields() []ent.Field {
field.Time("created_at").
Default(time.Now).
Immutable(),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now).
Immutable(),
}
}

View File

@@ -129,6 +129,6 @@ var (
fields = schema.User{}.Fields()
// descLast is the schema descriptor for last field.
descLast = fields[2].Descriptor()
// DefaultLast holds the default value for the last field.
// DefaultLast holds the default value on creation for the last field.
DefaultLast = descLast.Default.(string)
)

View File

@@ -1861,6 +1861,12 @@ func DefaultValue(t *testing.T, client *ent.Client) {
ctx := context.Background()
c1 := client.Card.Create().SetNumber("102030").SaveX(ctx)
require.False(t, c1.CreatedAt.IsZero())
require.False(t, c1.UpdatedAt.IsZero())
require.Equal(t, c1.UpdatedAt.Unix(), c1.CreatedAt.Unix())
c1 = c1.Update().SetNumber("302010").SaveX(ctx)
require.False(t, c1.CreatedAt.IsZero())
require.False(t, c1.UpdatedAt.IsZero())
require.NotEqual(t, c1.UpdatedAt.UnixNano(), c1.CreatedAt.UnixNano())
}
func ImmutableValue(t *testing.T, client *ent.Client) {

View File

@@ -40,10 +40,10 @@ var (
fields = schema.User{}.Fields()
// descBuffer is the schema descriptor for buffer field.
descBuffer = fields[3].Descriptor()
// DefaultBuffer holds the default value for the buffer field.
// DefaultBuffer holds the default value on creation for the buffer field.
DefaultBuffer = descBuffer.Default.([]byte)
// descTitle is the schema descriptor for title field.
descTitle = fields[4].Descriptor()
// DefaultTitle holds the default value for the title field.
// DefaultTitle holds the default value on creation for the title field.
DefaultTitle = descTitle.Default.(string)
)