Auto creating/updating time with unix (milli) second (#3213)

* Auto creating/updating time with unix (milli) second

* add test for 'Auto creating/updating time with unix (milli) second'
This commit is contained in:
lninl 2020-07-30 17:39:57 +08:00 committed by GitHub
parent 47a5196734
commit 7bb883b665
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 17 deletions

View File

@ -140,7 +140,7 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
if !updatingValue.CanAddr() || stmt.Dest != stmt.Model { if !updatingValue.CanAddr() || stmt.Dest != stmt.Model {
switch stmt.ReflectValue.Kind() { switch stmt.ReflectValue.Kind() {
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:
var priamryKeyExprs []clause.Expression var primaryKeyExprs []clause.Expression
for i := 0; i < stmt.ReflectValue.Len(); i++ { for i := 0; i < stmt.ReflectValue.Len(); i++ {
var exprs = make([]clause.Expression, len(stmt.Schema.PrimaryFields)) var exprs = make([]clause.Expression, len(stmt.Schema.PrimaryFields))
var notZero bool var notZero bool
@ -150,10 +150,10 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
notZero = notZero || !isZero notZero = notZero || !isZero
} }
if notZero { if notZero {
priamryKeyExprs = append(priamryKeyExprs, clause.And(exprs...)) primaryKeyExprs = append(primaryKeyExprs, clause.And(exprs...))
} }
} }
stmt.AddClause(clause.Where{Exprs: []clause.Expression{clause.Or(priamryKeyExprs...)}}) stmt.AddClause(clause.Where{Exprs: []clause.Expression{clause.Or(primaryKeyExprs...)}})
case reflect.Struct: case reflect.Struct:
for _, field := range stmt.Schema.PrimaryFields { for _, field := range stmt.Schema.PrimaryFields {
if value, isZero := field.ValueOf(stmt.ReflectValue); !isZero { if value, isZero := field.ValueOf(stmt.ReflectValue); !isZero {
@ -202,6 +202,8 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
if field.AutoUpdateTime == schema.UnixNanosecond { if field.AutoUpdateTime == schema.UnixNanosecond {
set = append(set, clause.Assignment{Column: clause.Column{Name: field.DBName}, Value: now.UnixNano()}) set = append(set, clause.Assignment{Column: clause.Column{Name: field.DBName}, Value: now.UnixNano()})
} else if field.AutoUpdateTime == schema.UnixMillisecond {
set = append(set, clause.Assignment{Column: clause.Column{Name: field.DBName}, Value: now.UnixNano() / 1e6})
} else if field.GORMDataType == schema.Time { } else if field.GORMDataType == schema.Time {
set = append(set, clause.Assignment{Column: clause.Column{Name: field.DBName}, Value: now}) set = append(set, clause.Assignment{Column: clause.Column{Name: field.DBName}, Value: now})
} else { } else {
@ -223,6 +225,8 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
if field.AutoUpdateTime > 0 { if field.AutoUpdateTime > 0 {
if field.AutoUpdateTime == schema.UnixNanosecond { if field.AutoUpdateTime == schema.UnixNanosecond {
value = stmt.DB.NowFunc().UnixNano() value = stmt.DB.NowFunc().UnixNano()
} else if field.AutoUpdateTime == schema.UnixMillisecond {
value = stmt.DB.NowFunc().UnixNano() / 1e6
} else if field.GORMDataType == schema.Time { } else if field.GORMDataType == schema.Time {
value = stmt.DB.NowFunc() value = stmt.DB.NowFunc()
} else { } else {

View File

@ -19,8 +19,9 @@ type DataType string
type TimeType int64 type TimeType int64
const ( const (
UnixSecond TimeType = 1 UnixSecond TimeType = 1
UnixNanosecond TimeType = 2 UnixMillisecond TimeType = 2
UnixNanosecond TimeType = 3
) )
const ( const (
@ -233,6 +234,8 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
if v, ok := field.TagSettings["AUTOCREATETIME"]; ok || (field.Name == "CreatedAt" && (field.DataType == Time || field.DataType == Int || field.DataType == Uint)) { if v, ok := field.TagSettings["AUTOCREATETIME"]; ok || (field.Name == "CreatedAt" && (field.DataType == Time || field.DataType == Int || field.DataType == Uint)) {
if strings.ToUpper(v) == "NANO" { if strings.ToUpper(v) == "NANO" {
field.AutoCreateTime = UnixNanosecond field.AutoCreateTime = UnixNanosecond
} else if strings.ToUpper(v) == "MILLI" {
field.AutoCreateTime = UnixMillisecond
} else { } else {
field.AutoCreateTime = UnixSecond field.AutoCreateTime = UnixSecond
} }
@ -241,6 +244,8 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
if v, ok := field.TagSettings["AUTOUPDATETIME"]; ok || (field.Name == "UpdatedAt" && (field.DataType == Time || field.DataType == Int || field.DataType == Uint)) { if v, ok := field.TagSettings["AUTOUPDATETIME"]; ok || (field.Name == "UpdatedAt" && (field.DataType == Time || field.DataType == Int || field.DataType == Uint)) {
if strings.ToUpper(v) == "NANO" { if strings.ToUpper(v) == "NANO" {
field.AutoUpdateTime = UnixNanosecond field.AutoUpdateTime = UnixNanosecond
} else if strings.ToUpper(v) == "MILLI" {
field.AutoUpdateTime = UnixMillisecond
} else { } else {
field.AutoUpdateTime = UnixSecond field.AutoUpdateTime = UnixSecond
} }
@ -551,6 +556,8 @@ func (field *Field) setupValuerAndSetter() {
case time.Time: case time.Time:
if field.AutoCreateTime == UnixNanosecond || field.AutoUpdateTime == UnixNanosecond { if field.AutoCreateTime == UnixNanosecond || field.AutoUpdateTime == UnixNanosecond {
field.ReflectValueOf(value).SetInt(data.UnixNano()) field.ReflectValueOf(value).SetInt(data.UnixNano())
} else if field.AutoCreateTime == UnixMillisecond || field.AutoUpdateTime == UnixMillisecond {
field.ReflectValueOf(value).SetInt(data.UnixNano() / 1e6)
} else { } else {
field.ReflectValueOf(value).SetInt(data.Unix()) field.ReflectValueOf(value).SetInt(data.Unix())
} }
@ -558,6 +565,8 @@ func (field *Field) setupValuerAndSetter() {
if data != nil { if data != nil {
if field.AutoCreateTime == UnixNanosecond || field.AutoUpdateTime == UnixNanosecond { if field.AutoCreateTime == UnixNanosecond || field.AutoUpdateTime == UnixNanosecond {
field.ReflectValueOf(value).SetInt(data.UnixNano()) field.ReflectValueOf(value).SetInt(data.UnixNano())
} else if field.AutoCreateTime == UnixMillisecond || field.AutoUpdateTime == UnixMillisecond {
field.ReflectValueOf(value).SetInt(data.UnixNano() / 1e6)
} else { } else {
field.ReflectValueOf(value).SetInt(data.Unix()) field.ReflectValueOf(value).SetInt(data.Unix())
} }

View File

@ -61,18 +61,20 @@ func TestCustomColumnAndIgnoredFieldClash(t *testing.T) {
func TestCustomizeField(t *testing.T) { func TestCustomizeField(t *testing.T) {
type CustomizeFieldStruct struct { type CustomizeFieldStruct struct {
gorm.Model gorm.Model
Name string Name string
FieldAllowCreate string `gorm:"<-:create"` FieldAllowCreate string `gorm:"<-:create"`
FieldAllowUpdate string `gorm:"<-:update"` FieldAllowUpdate string `gorm:"<-:update"`
FieldAllowSave string `gorm:"<-"` FieldAllowSave string `gorm:"<-"`
FieldAllowSave2 string `gorm:"<-:create,update"` FieldAllowSave2 string `gorm:"<-:create,update"`
FieldAllowSave3 string `gorm:"->:false;<-:create"` FieldAllowSave3 string `gorm:"->:false;<-:create"`
FieldReadonly string `gorm:"->"` FieldReadonly string `gorm:"->"`
FieldIgnore string `gorm:"-"` FieldIgnore string `gorm:"-"`
AutoUnixCreateTime int64 `gorm:"autocreatetime"` AutoUnixCreateTime int64 `gorm:"autocreatetime"`
AutoUnixNanoCreateTime int64 `gorm:"autocreatetime:nano"` AutoUnixMilliCreateTime int64 `gorm:"autocreatetime:milli"`
AutoUnixUpdateTime int64 `gorm:"autoupdatetime"` AutoUnixNanoCreateTime int64 `gorm:"autocreatetime:nano"`
AutoUnixNanoUpdateTime int64 `gorm:"autoupdatetime:nano"` AutoUnixUpdateTime int64 `gorm:"autoupdatetime"`
AutoUnixMilliUpdateTime int64 `gorm:"autoupdatetime:milli"`
AutoUnixNanoUpdateTime int64 `gorm:"autoupdatetime:nano"`
} }
DB.Migrator().DropTable(&CustomizeFieldStruct{}) DB.Migrator().DropTable(&CustomizeFieldStruct{})
@ -118,6 +120,10 @@ func TestCustomizeField(t *testing.T) {
t.Fatalf("invalid create/update unix time: %#v", result) t.Fatalf("invalid create/update unix time: %#v", result)
} }
if result.AutoUnixMilliCreateTime != result.AutoUnixMilliUpdateTime || result.AutoUnixMilliCreateTime == 0 || result.AutoUnixMilliCreateTime/result.AutoUnixCreateTime < 1e3 {
t.Fatalf("invalid create/update unix milli time: %#v", result)
}
if result.AutoUnixNanoCreateTime != result.AutoUnixNanoUpdateTime || result.AutoUnixNanoCreateTime == 0 || result.AutoUnixNanoCreateTime/result.AutoUnixCreateTime < 1e6 { if result.AutoUnixNanoCreateTime != result.AutoUnixNanoUpdateTime || result.AutoUnixNanoCreateTime == 0 || result.AutoUnixNanoCreateTime/result.AutoUnixCreateTime < 1e6 {
t.Fatalf("invalid create/update unix nano time: %#v", result) t.Fatalf("invalid create/update unix nano time: %#v", result)
} }
@ -163,6 +169,8 @@ func TestCustomizeField(t *testing.T) {
createWithDefaultTime := generateStruct("create_with_default_time") createWithDefaultTime := generateStruct("create_with_default_time")
createWithDefaultTime.AutoUnixCreateTime = 100 createWithDefaultTime.AutoUnixCreateTime = 100
createWithDefaultTime.AutoUnixUpdateTime = 100 createWithDefaultTime.AutoUnixUpdateTime = 100
createWithDefaultTime.AutoUnixMilliCreateTime = 100
createWithDefaultTime.AutoUnixMilliUpdateTime = 100
createWithDefaultTime.AutoUnixNanoCreateTime = 100 createWithDefaultTime.AutoUnixNanoCreateTime = 100
createWithDefaultTime.AutoUnixNanoUpdateTime = 100 createWithDefaultTime.AutoUnixNanoUpdateTime = 100
DB.Create(&createWithDefaultTime) DB.Create(&createWithDefaultTime)
@ -174,6 +182,10 @@ func TestCustomizeField(t *testing.T) {
t.Fatalf("invalid create/update unix time: %#v", createWithDefaultTimeResult) t.Fatalf("invalid create/update unix time: %#v", createWithDefaultTimeResult)
} }
if createWithDefaultTimeResult.AutoUnixMilliCreateTime != createWithDefaultTimeResult.AutoUnixMilliUpdateTime || createWithDefaultTimeResult.AutoUnixMilliCreateTime != 100 {
t.Fatalf("invalid create/update unix milli time: %#v", createWithDefaultTimeResult)
}
if createWithDefaultTimeResult.AutoUnixNanoCreateTime != createWithDefaultTimeResult.AutoUnixNanoUpdateTime || createWithDefaultTimeResult.AutoUnixNanoCreateTime != 100 { if createWithDefaultTimeResult.AutoUnixNanoCreateTime != createWithDefaultTimeResult.AutoUnixNanoUpdateTime || createWithDefaultTimeResult.AutoUnixNanoCreateTime != 100 {
t.Fatalf("invalid create/update unix nano time: %#v", createWithDefaultTimeResult) t.Fatalf("invalid create/update unix nano time: %#v", createWithDefaultTimeResult)
} }