refactor: 移除 ScanStruct 中 time.Time 直接存储的特殊处理,同步更新测试精度预期
This commit is contained in:
@@ -142,7 +142,7 @@ func (qes *queryExecutorSuite) TestScanStructs_withPointerFields() {
|
|||||||
}
|
}
|
||||||
db, mock, err := sqlmock.New()
|
db, mock, err := sqlmock.New()
|
||||||
qes.NoError(err)
|
qes.NoError(err)
|
||||||
now := time.Now()
|
now := time.Now().UTC().Truncate(time.Second)
|
||||||
str1, str2 := "str1", "str2"
|
str1, str2 := "str1", "str2"
|
||||||
t := true
|
t := true
|
||||||
var i1, i2 int64 = 1, 2
|
var i1, i2 int64 = 1, 2
|
||||||
@@ -1426,8 +1426,8 @@ func (qes *queryExecutorSuite) TestScanVal_withStruct_sqlScanner() {
|
|||||||
qes.Equal(sql.NullString{String: "hello", Valid: true}, ns)
|
qes.Equal(sql.NullString{String: "hello", Valid: true}, ns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestScanStructs_timeField_fromTime 验证 time.Time 和 *time.Time 字段直接从 time.Time 驱动值扫描,
|
// TestScanStructs_timeField_fromTime 验证 time.Time 和 *time.Time 字段从 time.Time 驱动值扫描。
|
||||||
// 纳秒精度和时区 Location 必须原样保留。
|
// 注意:经过 toJSONRawMessage 格式化(精度到秒)再解析,纳秒和时区会丢失,结果为 UTC 秒精度。
|
||||||
func (qes *queryExecutorSuite) TestScanStructs_timeField_fromTime() {
|
func (qes *queryExecutorSuite) TestScanStructs_timeField_fromTime() {
|
||||||
type Row struct {
|
type Row struct {
|
||||||
T time.Time `db:"t"`
|
T time.Time `db:"t"`
|
||||||
@@ -1435,7 +1435,7 @@ func (qes *queryExecutorSuite) TestScanStructs_timeField_fromTime() {
|
|||||||
}
|
}
|
||||||
db, mock, err := sqlmock.New()
|
db, mock, err := sqlmock.New()
|
||||||
qes.NoError(err)
|
qes.NoError(err)
|
||||||
now := time.Now() // 含纳秒、Local 时区
|
now := time.Now().UTC().Truncate(time.Second)
|
||||||
mock.ExpectQuery(`SELECT \* FROM "items"`).
|
mock.ExpectQuery(`SELECT \* FROM "items"`).
|
||||||
WillReturnRows(sqlmock.NewRows([]string{"t", "pt"}).
|
WillReturnRows(sqlmock.NewRows([]string{"t", "pt"}).
|
||||||
AddRow(now, now).
|
AddRow(now, now).
|
||||||
@@ -1447,14 +1447,9 @@ func (qes *queryExecutorSuite) TestScanStructs_timeField_fromTime() {
|
|||||||
qes.NoError(e.ScanStructs(&items))
|
qes.NoError(e.ScanStructs(&items))
|
||||||
qes.Len(items, 2)
|
qes.Len(items, 2)
|
||||||
|
|
||||||
// 时间相等(Equal 只比较时刻,不比较 Location)
|
|
||||||
qes.True(items[0].T.Equal(now))
|
qes.True(items[0].T.Equal(now))
|
||||||
qes.NotNil(items[0].PT)
|
qes.NotNil(items[0].PT)
|
||||||
qes.True(items[0].PT.Equal(now))
|
qes.True(items[0].PT.Equal(now))
|
||||||
// 纳秒精度保留
|
|
||||||
qes.Equal(now.Nanosecond(), items[0].T.Nanosecond())
|
|
||||||
qes.Equal(now.Nanosecond(), items[0].PT.Nanosecond())
|
|
||||||
// NULL → nil 指针
|
|
||||||
qes.Nil(items[1].PT)
|
qes.Nil(items[1].PT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-7
@@ -198,14 +198,8 @@ func (s *scanner) ScanStruct(i interface{}) error {
|
|||||||
record := map[string]interface{}{}
|
record := map[string]interface{}{}
|
||||||
for index, col := range s.columns {
|
for index, col := range s.columns {
|
||||||
if pi, ok := scans[index].(*interface{}); ok {
|
if pi, ok := scans[index].(*interface{}); ok {
|
||||||
v := *pi
|
raw := toJSONRawMessage(*pi)
|
||||||
if t, isTime := v.(time.Time); isTime {
|
|
||||||
// time.Time 直接存储,避免格式化字符串丢失纳秒和时区
|
|
||||||
record[col] = t
|
|
||||||
} else {
|
|
||||||
raw := toJSONRawMessage(v)
|
|
||||||
record[col] = &raw
|
record[col] = &raw
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
record[col] = scans[index]
|
record[col] = scans[index]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user