Skip to content

feat(database/gdb): support Scan into basic types - #4870

Open
hailaz wants to merge 30 commits into
masterfrom
feat/gdbscanbasictype
Open

feat(database/gdb): support Scan into basic types#4870
hailaz wants to merge 30 commits into
masterfrom
feat/gdbscanbasictype

Conversation

@hailaz

@hailaz hailaz commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

概述

Model.Scan 现在支持将单列查询结果扫描到基本类型、基本类型指针、基本类型切片,以及基本类型指针切片。

这补齐了 #3977 中的缺口:此前用户只能绕道 Value() / Array(),而且仍然无法把结果直接扫进 intstringfloat64bool 这类标量。

var name string
err := db.Model("user").Fields("name").Where("id", 1).Scan(&name)

var names []string
err = db.Model("user").Fields("name").Scan(&names)

var total float64
err = db.Model("user").FieldSum("balance").Scan(&total)

行为说明

  • 支持的目标类型:int / uint / float / bool / string 及其定长变体,以及 *T[]T[]*T
  • 现有的结构体 / 结构体切片 Scan 行为保持不变。
  • 结果必须恰好只有一列。调用方应通过 Fields()FieldSum() 这类会产出字段的辅助方法指定列。
  • FieldsEx 仅在过滤后只剩一列时才被接受。
  • 会展开成多列的字段会被拒绝:*a.*,以及 gdb.Raw("name,age")
  • 单列表达式仍然有效,包括 gdb.Raw("name")COUNT(*)COUNT(DISTINCT id, username)
  • 没有匹配行时:
    • 非空基本类型变量(var name string)返回 sql.ErrNoRows
    • 空指针(var namePtr *string)保持 nil,不返回 sql.ErrNoRows
    • 切片保持为空,不返回 sql.ErrNoRows

其他改动

  • 新增 reflection.IsBasicKind,只有切片元素是真正的标量时才会走基本类型路径,避免把 []Record 这类结果误判成标量切片。
  • 保留 gconv 对指针元素的分配逻辑,以便正确填充 []*T

wanghaolong613 and others added 30 commits March 3, 2026 15:13
- Implemented TestScanReflectValueInput to verify gconv functions correctly unwrap reflect.Value types for basic types.
- Added TestScanPointerElementSlice to test scanning into slices of pointers for various basic types, including cross-type conversions.
…sic types

- Refactor isExpandingField to inspect Raw content instead of rejecting
  all Raw types, correctly distinguishing single-column expressions like
  Raw("username") from expanding ones like Raw("name,age")
- Add isExpandingFieldStr to detect top-level commas while ignoring
  commas nested inside function parentheses (e.g. COUNT(DISTINCT a,b))
- Extract validateFieldsExSingleColumn to verify FieldsEx leaves exactly
  one column, with graceful skip when DB is unavailable
- Fix getFieldsFiltered to expand Raw entries with comma-separated field
  lists so they are correctly excluded from the SELECT clause
- Update unit tests to match corrected Raw field behavior
- Add MySQL integration tests for FieldsEx with string, []string,
  variadic args, and gdb.Raw input types
# Conflicts:
#	util/gconv/gconv_z_unit_scan_basic_types_test.go
FieldsEx is an exclusion list and does not declare a single result
column. Accepting it let Scan reuse Value()/Array(), which return
FirstResultColumn before any column-count check and silently drop
the remaining columns.
…gleFieldSpecified

fix(converter): enhance comment for pointer element handling in Scan method
@hailaz hailaz changed the title Feat/gdbscanbasictype feat(database/gdb): support Scan into basic types Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants