refactor: 移除 ScanStruct 中 time.Time 直接存储的特殊处理,同步更新测试精度预期

This commit is contained in:
2026-06-02 17:24:10 +08:00
parent 2a3f0afa6e
commit 1e9a16b693
2 changed files with 6 additions and 17 deletions
+4 -9
View File
@@ -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
View File
@@ -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]
} }