Search code examples
gounix-timestampgo-gorm

gorm how to declare a unix timestamp mills field that is not auto updated


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?


Solution

  • 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