1

We have a timestamp field in a database table, it should only be updated when a business event occurs, not upon create / every update.

There are examples of auto update at https://stackoverflow.com/a/60941397/41284 as well as in the gorm official documentation at https://gorm.io/docs/models.html#Creating-x2F-Updating-Time-x2F-Unix-Milli-x2F-Nano-Seconds-Tracking but I couldn't find a way to just declare a timestamp field with storage in unix epoch time upto milliseconds. I can of course just declare it as an int64 and then attempt to populate the right value manually.

Any other options that are more convenient / automated?

1 Answer 1

1

As I well know, you can create a custom type that embeds time.Time and overrides its Scan and Value methods to handle the conversion between the database representation (int64) and the Go representation (time.Time).

Here's how you can define a custom type for your Unix timestamp field:

import (
    "database/sql/driver"
    "time"
)

// Define custom type to represent Unix timestamp in milliseconds
type UnixTimestamp struct {
    time.Time
}

// Scan converts the database field to UnixTimestamp type
func (u *UnixTimestamp) Scan(value interface{}) error {
    if value == nil {
        return nil
    }
    unixTime := value.(int64) / 1000 // value is in ms
    u.Time = time.Unix(unixTime, 0)
    return nil
}

// Value converts UnixTimestamp type to a value that can be stored in the database
func (u UnixTimestamp) Value() (driver.Value, error) {
    if u.IsZero() {
        return nil, nil
    }
    return u.UnixNano() / int64(time.Millisecond), nil
}

Then, in your GORM model, you can use this custom type for your timestamp field:

type YourModel struct {
    ID        uint         `gorm:"primaryKey"`
    Timestamp UnixTimestamp
    // ...
}

gorm will automatically handle the conversion data whenever you query or save records

Sorry my poor english, I hope this will help

Not the answer you're looking for? Browse other questions tagged or ask your own question.