mirror of
https://gitee.com/johng/gf.git
synced 2024-11-29 18:57:44 +08:00
feat(database/gdb): add time
field type for value converting for/from field (#3712)
This commit is contained in:
parent
baea1c7a7a
commit
bb9a3b83eb
@ -99,7 +99,7 @@ func generateStructFieldDefinition(
|
||||
}
|
||||
localTypeNameStr = string(localTypeName)
|
||||
switch localTypeName {
|
||||
case gdb.LocalTypeDate, gdb.LocalTypeDatetime:
|
||||
case gdb.LocalTypeDate, gdb.LocalTypeTime, gdb.LocalTypeDatetime:
|
||||
if in.StdTime {
|
||||
localTypeNameStr = "time.Time"
|
||||
} else {
|
||||
|
@ -104,6 +104,7 @@ func Test_DB_Insert(t *testing.T) {
|
||||
"password": "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname": "T1",
|
||||
"create_time": gtime.Now().String(),
|
||||
"create_date": gtime.Date(),
|
||||
})
|
||||
t.AssertNil(err)
|
||||
|
||||
@ -114,6 +115,7 @@ func Test_DB_Insert(t *testing.T) {
|
||||
"password": "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname": "name_2",
|
||||
"create_time": gtime.Now().String(),
|
||||
"create_date": gtime.Date(),
|
||||
})
|
||||
t.AssertNil(err)
|
||||
n, _ := result.RowsAffected()
|
||||
@ -121,19 +123,22 @@ func Test_DB_Insert(t *testing.T) {
|
||||
|
||||
// struct
|
||||
type User struct {
|
||||
Id int `gconv:"id"`
|
||||
Passport string `json:"passport"`
|
||||
Password string `gconv:"password"`
|
||||
Nickname string `gconv:"nickname"`
|
||||
CreateTime string `json:"create_time"`
|
||||
Id int `gconv:"id"`
|
||||
Passport string `json:"passport"`
|
||||
Password string `gconv:"password"`
|
||||
Nickname string `gconv:"nickname"`
|
||||
CreateTime string `json:"create_time"`
|
||||
CreateDate *gtime.Time `json:"create_date"`
|
||||
}
|
||||
timeStr := gtime.New("2024-10-01 12:01:01").String()
|
||||
gTime := gtime.New("2024-10-01 12:01:01")
|
||||
timeStr, dateStr := gTime.String(), "2024-10-01 00:00:00"
|
||||
result, err = db.Insert(ctx, table, User{
|
||||
Id: 3,
|
||||
Passport: "user_3",
|
||||
Password: "25d55ad283aa400af464c76d713c07ad",
|
||||
Nickname: "name_3",
|
||||
CreateTime: timeStr,
|
||||
CreateDate: gTime,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
n, _ = result.RowsAffected()
|
||||
@ -147,15 +152,18 @@ func Test_DB_Insert(t *testing.T) {
|
||||
t.Assert(one["password"].String(), "25d55ad283aa400af464c76d713c07ad")
|
||||
t.Assert(one["nickname"].String(), "name_3")
|
||||
t.Assert(one["create_time"].GTime().String(), timeStr)
|
||||
t.Assert(one["create_date"].GTime().String(), dateStr)
|
||||
|
||||
// *struct
|
||||
timeStr = gtime.New("2024-10-01 12:01:01").String()
|
||||
gTime = gtime.New("2024-10-01 12:01:01")
|
||||
timeStr, dateStr = gTime.String(), "2024-10-01 00:00:00"
|
||||
result, err = db.Insert(ctx, table, &User{
|
||||
Id: 4,
|
||||
Passport: "t4",
|
||||
Password: "25d55ad283aa400af464c76d713c07ad",
|
||||
Nickname: "name_4",
|
||||
CreateTime: timeStr,
|
||||
CreateDate: gTime,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
n, _ = result.RowsAffected()
|
||||
@ -168,9 +176,11 @@ func Test_DB_Insert(t *testing.T) {
|
||||
t.Assert(one["password"].String(), "25d55ad283aa400af464c76d713c07ad")
|
||||
t.Assert(one["nickname"].String(), "name_4")
|
||||
t.Assert(one["create_time"].GTime().String(), timeStr)
|
||||
t.Assert(one["create_date"].GTime().String(), dateStr)
|
||||
|
||||
// batch with Insert
|
||||
timeStr = gtime.New("2024-10-01 12:01:01").String()
|
||||
gTime = gtime.New("2024-10-01 12:01:01")
|
||||
timeStr, dateStr = gTime.String(), "2024-10-01 00:00:00"
|
||||
r, err := db.Insert(ctx, table, g.Slice{
|
||||
g.Map{
|
||||
"id": 200,
|
||||
@ -178,6 +188,7 @@ func Test_DB_Insert(t *testing.T) {
|
||||
"password": "25d55ad283aa400af464c76d71qw07ad",
|
||||
"nickname": "T200",
|
||||
"create_time": timeStr,
|
||||
"create_date": gTime,
|
||||
},
|
||||
g.Map{
|
||||
"id": 300,
|
||||
@ -185,6 +196,7 @@ func Test_DB_Insert(t *testing.T) {
|
||||
"password": "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname": "T300",
|
||||
"create_time": timeStr,
|
||||
"create_date": gTime,
|
||||
},
|
||||
})
|
||||
t.AssertNil(err)
|
||||
@ -198,6 +210,7 @@ func Test_DB_Insert(t *testing.T) {
|
||||
t.Assert(one["password"].String(), "25d55ad283aa400af464c76d71qw07ad")
|
||||
t.Assert(one["nickname"].String(), "T200")
|
||||
t.Assert(one["create_time"].GTime().String(), timeStr)
|
||||
t.Assert(one["create_date"].GTime().String(), dateStr)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1644,7 +1657,7 @@ func Test_Core_ClearTableFields(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
fields, err := db.TableFields(ctx, table)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(fields), 5)
|
||||
t.Assert(len(fields), 6)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
err := db.GetCore().ClearTableFields(ctx, table)
|
||||
|
@ -129,6 +129,7 @@ func createTableWithDb(db gdb.DB, table ...string) (name string) {
|
||||
password char(32) NULL,
|
||||
nickname varchar(45) NULL,
|
||||
create_time timestamp(6) NULL,
|
||||
create_date date NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
`, name,
|
||||
|
@ -1063,7 +1063,7 @@ func Test_Issue2552_ClearTableFieldsAll(t *testing.T) {
|
||||
ctx = context.Background()
|
||||
sqlArray, err = gdb.CatchSQL(ctx, func(ctx context.Context) error {
|
||||
one, err := db.Model(table).Ctx(ctx).One()
|
||||
t.Assert(len(one), 5)
|
||||
t.Assert(len(one), 6)
|
||||
return err
|
||||
})
|
||||
t.AssertNil(err)
|
||||
@ -1078,7 +1078,7 @@ func Test_Issue2552_ClearTableFieldsAll(t *testing.T) {
|
||||
ctx = context.Background()
|
||||
sqlArray, err = gdb.CatchSQL(ctx, func(ctx context.Context) error {
|
||||
one, err := db.Model(table).Ctx(ctx).One()
|
||||
t.Assert(len(one), 4)
|
||||
t.Assert(len(one), 5)
|
||||
return err
|
||||
})
|
||||
t.AssertNil(err)
|
||||
@ -1109,7 +1109,7 @@ func Test_Issue2552_ClearTableFields(t *testing.T) {
|
||||
ctx = context.Background()
|
||||
sqlArray, err = gdb.CatchSQL(ctx, func(ctx context.Context) error {
|
||||
one, err := db.Model(table).Ctx(ctx).One()
|
||||
t.Assert(len(one), 5)
|
||||
t.Assert(len(one), 6)
|
||||
return err
|
||||
})
|
||||
t.AssertNil(err)
|
||||
@ -1124,7 +1124,7 @@ func Test_Issue2552_ClearTableFields(t *testing.T) {
|
||||
ctx = context.Background()
|
||||
sqlArray, err = gdb.CatchSQL(ctx, func(ctx context.Context) error {
|
||||
one, err := db.Model(table).Ctx(ctx).One()
|
||||
t.Assert(len(one), 4)
|
||||
t.Assert(len(one), 5)
|
||||
return err
|
||||
})
|
||||
t.AssertNil(err)
|
||||
|
@ -2335,7 +2335,7 @@ func Test_Model_FieldsEx(t *testing.T) {
|
||||
r, err := db.Model(table).FieldsEx("create_time, id").Where("id in (?)", g.Slice{1, 2}).Order("id asc").All()
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(r), 2)
|
||||
t.Assert(len(r[0]), 3)
|
||||
t.Assert(len(r[0]), 4)
|
||||
t.Assert(r[0]["id"], "")
|
||||
t.Assert(r[0]["passport"], "user_1")
|
||||
t.Assert(r[0]["password"], "pass_1")
|
||||
@ -2982,7 +2982,7 @@ func Test_Model_FieldsEx_AutoMapping(t *testing.T) {
|
||||
"CreateTime": 1,
|
||||
}).Where("id", 2).One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(one), 2)
|
||||
t.Assert(len(one), 3)
|
||||
t.Assert(one["id"], 2)
|
||||
t.Assert(one["nickname"], "name_2")
|
||||
})
|
||||
@ -2999,7 +2999,7 @@ func Test_Model_FieldsEx_AutoMapping(t *testing.T) {
|
||||
CreateTime: 0,
|
||||
}).Where("id", 2).One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(one), 2)
|
||||
t.Assert(len(one), 3)
|
||||
t.Assert(one["id"], 2)
|
||||
t.Assert(one["nickname"], "name_2")
|
||||
})
|
||||
@ -3157,8 +3157,8 @@ func Test_TimeZoneInsert(t *testing.T) {
|
||||
gtest.AssertNil(err)
|
||||
|
||||
CreateTime := "2020-11-22 12:23:45"
|
||||
UpdateTime := "2020-11-22 13:23:45"
|
||||
DeleteTime := "2020-11-22 14:23:45"
|
||||
UpdateTime := "2020-11-22 13:23:46"
|
||||
DeleteTime := "2020-11-22 14:23:47"
|
||||
type User struct {
|
||||
Id int `json:"id"`
|
||||
CreatedAt *gtime.Time `json:"created_at"`
|
||||
@ -3176,13 +3176,14 @@ func Test_TimeZoneInsert(t *testing.T) {
|
||||
}
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
_, _ = db.Model(tableName).Unscoped().Insert(u)
|
||||
_, err = db.Model(tableName).Unscoped().Insert(u)
|
||||
t.AssertNil(err)
|
||||
userEntity := &User{}
|
||||
err := db.Model(tableName).Where("id", 1).Unscoped().Scan(&userEntity)
|
||||
err = db.Model(tableName).Where("id", 1).Unscoped().Scan(&userEntity)
|
||||
t.AssertNil(err)
|
||||
t.Assert(userEntity.CreatedAt.String(), "2020-11-22 11:23:45")
|
||||
t.Assert(userEntity.UpdatedAt.String(), "2020-11-22 12:23:45")
|
||||
t.Assert(gtime.NewFromTime(userEntity.DeletedAt).String(), "2020-11-22 13:23:45")
|
||||
t.Assert(userEntity.UpdatedAt.String(), "2020-11-22 12:23:46")
|
||||
t.Assert(gtime.NewFromTime(userEntity.DeletedAt).String(), "2020-11-22 13:23:47")
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -446,6 +446,7 @@ type LocalType string
|
||||
const (
|
||||
LocalTypeUndefined LocalType = ""
|
||||
LocalTypeString LocalType = "string"
|
||||
LocalTypeTime LocalType = "time"
|
||||
LocalTypeDate LocalType = "date"
|
||||
LocalTypeDatetime LocalType = "datetime"
|
||||
LocalTypeInt LocalType = "int"
|
||||
@ -492,6 +493,7 @@ const (
|
||||
fieldTypeBool = "bool"
|
||||
fieldTypeBit = "bit"
|
||||
fieldTypeDate = "date"
|
||||
fieldTypeTime = "time"
|
||||
fieldTypeDatetime = "datetime"
|
||||
fieldTypeTimestamp = "timestamp"
|
||||
fieldTypeTimestampz = "timestamptz"
|
||||
|
@ -83,6 +83,10 @@ func (c *Core) ConvertValueForField(ctx context.Context, fieldType string, field
|
||||
err error
|
||||
convertedValue = fieldValue
|
||||
)
|
||||
switch fieldValue.(type) {
|
||||
case time.Time, *time.Time, gtime.Time, *gtime.Time:
|
||||
goto Default
|
||||
}
|
||||
// If `value` implements interface `driver.Valuer`, it then uses the interface for value converting.
|
||||
if valuer, ok := fieldValue.(driver.Valuer); ok {
|
||||
if convertedValue, err = valuer.Value(); err != nil {
|
||||
@ -90,6 +94,7 @@ func (c *Core) ConvertValueForField(ctx context.Context, fieldType string, field
|
||||
}
|
||||
return convertedValue, nil
|
||||
}
|
||||
Default:
|
||||
// Default value converting.
|
||||
var (
|
||||
rvValue = reflect.ValueOf(fieldValue)
|
||||
@ -100,6 +105,9 @@ func (c *Core) ConvertValueForField(ctx context.Context, fieldType string, field
|
||||
rvKind = rvValue.Kind()
|
||||
}
|
||||
switch rvKind {
|
||||
case reflect.Invalid:
|
||||
convertedValue = nil
|
||||
|
||||
case reflect.Slice, reflect.Array, reflect.Map:
|
||||
// It should ignore the bytes type.
|
||||
if _, ok := fieldValue.([]byte); !ok {
|
||||
@ -109,7 +117,6 @@ func (c *Core) ConvertValueForField(ctx context.Context, fieldType string, field
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
switch r := fieldValue.(type) {
|
||||
// If the time is zero, it then updates it to nil,
|
||||
@ -117,11 +124,28 @@ func (c *Core) ConvertValueForField(ctx context.Context, fieldType string, field
|
||||
case time.Time:
|
||||
if r.IsZero() {
|
||||
convertedValue = nil
|
||||
} else if fieldType == fieldTypeDate {
|
||||
convertedValue = r.Format("2006-01-02")
|
||||
} else if fieldType == fieldTypeTime {
|
||||
convertedValue = r.Format("15:04:05")
|
||||
}
|
||||
|
||||
case *time.Time:
|
||||
if r == nil {
|
||||
// Nothing to do.
|
||||
} else if fieldType == fieldTypeDate {
|
||||
convertedValue = r.Format("2006-01-02")
|
||||
} else if fieldType == fieldTypeTime {
|
||||
convertedValue = r.Format("15:04:05")
|
||||
}
|
||||
|
||||
case gtime.Time:
|
||||
if r.IsZero() {
|
||||
convertedValue = nil
|
||||
} else if fieldType == fieldTypeDate {
|
||||
convertedValue = r.Layout("2006-01-02")
|
||||
} else if fieldType == fieldTypeTime {
|
||||
convertedValue = r.Layout("15:04:05")
|
||||
} else {
|
||||
convertedValue = r.Time
|
||||
}
|
||||
@ -129,13 +153,14 @@ func (c *Core) ConvertValueForField(ctx context.Context, fieldType string, field
|
||||
case *gtime.Time:
|
||||
if r.IsZero() {
|
||||
convertedValue = nil
|
||||
} else if fieldType == fieldTypeDate {
|
||||
convertedValue = r.Layout("2006-01-02")
|
||||
} else if fieldType == fieldTypeTime {
|
||||
convertedValue = r.Layout("15:04:05")
|
||||
} else {
|
||||
convertedValue = r.Time
|
||||
}
|
||||
|
||||
case *time.Time:
|
||||
// Nothing to do.
|
||||
|
||||
case Counter, *Counter:
|
||||
// Nothing to do.
|
||||
|
||||
@ -157,6 +182,7 @@ func (c *Core) ConvertValueForField(ctx context.Context, fieldType string, field
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return convertedValue, nil
|
||||
}
|
||||
|
||||
@ -247,6 +273,10 @@ func (c *Core) CheckLocalTypeForField(ctx context.Context, fieldType string, fie
|
||||
fieldTypeDate:
|
||||
return LocalTypeDate, nil
|
||||
|
||||
case
|
||||
fieldTypeTime:
|
||||
return LocalTypeTime, nil
|
||||
|
||||
case
|
||||
fieldTypeDatetime,
|
||||
fieldTypeTimestamp,
|
||||
@ -353,13 +383,19 @@ func (c *Core) ConvertValueForLocal(
|
||||
return gconv.Bool(fieldValue), nil
|
||||
|
||||
case LocalTypeDate:
|
||||
// Date without time.
|
||||
if t, ok := fieldValue.(time.Time); ok {
|
||||
return gtime.NewFromTime(t).Format("Y-m-d"), nil
|
||||
}
|
||||
t, _ := gtime.StrToTime(gconv.String(fieldValue))
|
||||
return t.Format("Y-m-d"), nil
|
||||
|
||||
case LocalTypeTime:
|
||||
if t, ok := fieldValue.(time.Time); ok {
|
||||
return gtime.NewFromTime(t).Format("H:i:s"), nil
|
||||
}
|
||||
t, _ := gtime.StrToTime(gconv.String(fieldValue))
|
||||
return t.Format("H:i:s"), nil
|
||||
|
||||
case LocalTypeDatetime:
|
||||
if t, ok := fieldValue.(time.Time); ok {
|
||||
return gtime.NewFromTime(t), nil
|
||||
|
@ -339,7 +339,7 @@ func (m *softTimeMaintainer) getConditionByFieldNameAndTypeForSoftDeleting(
|
||||
switch m.softTimeOption.SoftTimeType {
|
||||
case SoftTimeTypeAuto:
|
||||
switch fieldType {
|
||||
case LocalTypeDate, LocalTypeDatetime:
|
||||
case LocalTypeDate, LocalTypeTime, LocalTypeDatetime:
|
||||
return fmt.Sprintf(`%s IS NULL`, quotedFieldName)
|
||||
case LocalTypeInt, LocalTypeUint, LocalTypeInt64, LocalTypeUint64, LocalTypeBool:
|
||||
return fmt.Sprintf(`%s=0`, quotedFieldName)
|
||||
@ -368,7 +368,7 @@ func (m *softTimeMaintainer) GetValueByFieldTypeForCreateOrUpdate(
|
||||
var value any
|
||||
if isDeletedField {
|
||||
switch fieldType {
|
||||
case LocalTypeDate, LocalTypeDatetime:
|
||||
case LocalTypeDate, LocalTypeTime, LocalTypeDatetime:
|
||||
value = nil
|
||||
default:
|
||||
value = 0
|
||||
@ -378,7 +378,7 @@ func (m *softTimeMaintainer) GetValueByFieldTypeForCreateOrUpdate(
|
||||
switch m.softTimeOption.SoftTimeType {
|
||||
case SoftTimeTypeAuto:
|
||||
switch fieldType {
|
||||
case LocalTypeDate, LocalTypeDatetime:
|
||||
case LocalTypeDate, LocalTypeTime, LocalTypeDatetime:
|
||||
value = gtime.Now()
|
||||
case LocalTypeInt, LocalTypeUint, LocalTypeInt64, LocalTypeUint64:
|
||||
value = gtime.Timestamp()
|
||||
|
Loading…
Reference in New Issue
Block a user