package common import ( "database/sql/driver" "time" "github.com/google/uuid" "gorm.io/gorm" ) type UsernameContextKey string // GUID -> new datatype type GUID uuid.UUID // StringToGUID -> parse string to GUID func StringToGUID(s string) (GUID, error) { id, err := uuid.Parse(s) return GUID(id), err } // String -> String Representation of Binary16 func (guid GUID) String() string { return uuid.UUID(guid).String() } // GormDataType -> sets type to binary(16) func (guid GUID) GormDataType() string { return "binary(16)" } func (guid GUID) MarshalJSON() ([]byte, error) { s := uuid.UUID(guid) str := "\"" + s.String() + "\"" return []byte(str), nil } func (guid *GUID) UnmarshalJSON(by []byte) error { s, err := uuid.ParseBytes(by) *guid = GUID(s) return err } // Scan --> tells GORM how to receive from the database func (guid *GUID) Scan(value interface{}) error { bytes, _ := value.([]byte) parseByte, err := uuid.FromBytes(bytes) *guid = GUID(parseByte) return err } // Value -> tells GORM how to save into the database func (guid GUID) Value() (driver.Value, error) { return uuid.UUID(guid).MarshalBinary() } type BasicFields struct { CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` CreatedByDB GUID `gorm:"column:created_by" json:"-"` CreatedByJSON string `gorm:"-" json:"created_by"` UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` UpdatedByDB GUID `gorm:"column:updated_by" json:"-"` UpdatedByJSON string `gorm:"-" json:"updated_by"` DeletedAtDB gorm.DeletedAt `gorm:"column:deleted_at" json:"-"` DeletedAtJSON *time.Time `gorm:"-" json:"deleted_at,omitempty"` DeletedBy string `gorm:"column:deleted_by" json:"deleted_by,omitempty"` } func (basicFields *BasicFields) BeforeCreate(tx *gorm.DB) error { if userID, ok := tx.Get("userID"); ok { if guid, ok := userID.(GUID); ok { basicFields.CreatedByDB = guid basicFields.UpdatedByDB = guid } } return nil } func (basicFields *BasicFields) AfterCreate(tx *gorm.DB) error { if username, ok := tx.Get("username"); ok { if name, ok := username.(string); ok { basicFields.CreatedByJSON = name basicFields.UpdatedByJSON = name } } return nil } type GUIDPKicPK struct { ID uint64 `gorm:"primaryKey;column:id" json:"id"` BasicFields } type ModelGUIDPK struct { ID GUID `gorm:"primaryKey;column:id" json:"id"` BasicFields } func (guidPK *ModelGUIDPK) BeforeCreate(tx *gorm.DB) error { id, err := uuid.NewRandom() guidPK.ID = GUID(id) if userID, ok := tx.Get("userID"); ok { if guid, ok := userID.(GUID); ok { guidPK.CreatedByDB = guid guidPK.UpdatedByDB = guid } } return err } type ModelHiddenGUIDPK struct { ID GUID `gorm:"primaryKey;column:id" json:"-"` BasicFields } func (guidPK *ModelHiddenGUIDPK) BeforeCreate(tx *gorm.DB) error { id, err := uuid.NewRandom() guidPK.ID = GUID(id) if userID, ok := tx.Get("userID"); ok { if guid, ok := userID.(GUID); ok { guidPK.CreatedByDB = guid guidPK.UpdatedByDB = guid } } return err }