Is there a way to make gorm send database specific values for created_at, updated_at and deleted_at fields?

Viewed 182

I am writing on Go and using gorm to deal with Postgres database. I have one instance of Postgres DB, and several instances of my app running simultaneously. It is possible they will unsynchronized in time with each other. It will lead to some problems with my business logic because I need to precisely track changes.

I see a possible solution in using now() instead of the exact time 2022-02-09 17:39:47.785 in database transactions, but I don't know how to do it with gorm. Of course, I can update it later with a separate transaction, or even write a raw SQL query and send it via gorm, but it will add unwanted complexity to my code.

Here is an exampe

package main

import (
    "log"

    "gorm.io/driver/postgres"
    "gorm.io/gorm"
    "gorm.io/gorm/logger"
)

type Data struct {
    gorm.Model
    Value string
}

func main() {
    // to init test db in docker run
    // $docker run --rm -e POSTGRES_HOST_AUTH_METHOD=trust --name pg -p 5432:5432 postgres

    db, err := dbClient()
    errHandle(err)

    err = db.AutoMigrate(&Data{})
    errHandle(err)

    data := &Data{Value: "some value"}

    // add new
    err = db.Create(&data).Error
    errHandle(err)

    data.Value = "some changes"

    // update
    err = db.Omit("created_at").Save(&data).Error
    errHandle(err)

    // soft delete
    err = db.Delete(&data).Error
    errHandle(err)
}

func errHandle(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func dbClient() (*gorm.DB, error) {
    newLogger := logger.Default.LogMode(logger.Info)
    c := &gorm.Config{
        Logger: newLogger,
    }
    d := postgres.Open("dbname=postgres host=localhost user=postgres")
    return gorm.Open(d, c)
}

If you run it you will see this output

INSERT INTO "data" ("created_at","updated_at","deleted_at","value") VALUES ('2022-02-09 18:22:44.728','2022-02-09 18:22:44.728',NULL,'some value') RETURNING "id";

UPDATE "data" SET "updated_at"='2022-02-09 18:22:44.742',"deleted_at"=NULL,"value"='some changes' WHERE "id" = 1;

UPDATE "data" SET "deleted_at"='2022-02-09 18:22:44.75' WHERE "data"."id" = 1 AND "data"."deleted_at" IS NULL;

I want it to look like that

INSERT INTO "data" ("created_at","updated_at","deleted_at","value") VALUES (now(),now(),NULL,'some value') RETURNING "id";

UPDATE "data" SET "updated_at"=now(),"deleted_at"=NULL,"value"='some changes' WHERE "id" = 1;

UPDATE "data" SET "deleted_at"=now() WHERE "data"."id" = 1 AND "data"."deleted_at" IS NULL;
0 Answers
Related