go-pg / pg

Golang ORM with focus on PostgreSQL features and performance
https://pg.uptrace.dev/
BSD 2-Clause "Simplified" License
5.65k stars 401 forks source link

"BeforeUpdate" hook not working for individual column updates #1943

Open Omkarz7 opened 2 years ago

Omkarz7 commented 2 years ago
type User struct {
    ID        int64
    CreatedAt time.Time `sql:"default:now()"`
    UpdatedAt time.Time `sql:"default:now()"`
    Name      string
    Email    string
}

func (m *User) BeforeUpdate(ctx context.Context) (context.Context, error) {
    m.UpdatedAt = timeNow().Round(time.Microsecond)
    return ctx, nil
}

The following two queries don't update the _updatedat column

user := &User{ID:1, Email:"some@email.com"} 
_, err := db.ModelContext(ctx, user).Column("email").Where("id = ?", user.ID).Update()
_, err := db.ModelContext(ctx, user).Set("email = ?",users.Email ).Where("id = ?", user.ID).Update()

The below queries work fine and update the _updatedat column

user := &User{ID:1, Email:"some@email.com"} 
_, err := db.ModelContext(ctx, user)..WherePK().UpdateNotZero()
_, err := db.ModelContext(ctx, user).Where("id = ?", id).Update()

Is this intended behavior where BeforeUpdate hook is only triggered and used when the values are updated using struct? Is it possible to have a update tag which updates the _updatedat column if it exists. Similar to how soft delete works, where we update _deletedat is set to current time if the column exists and we mention the tag in struct.