feat(ToInsert): 支持数组直接传入
This commit is contained in:
parent
09770b07dc
commit
340deecefb
61
mapping.go
61
mapping.go
@ -125,14 +125,71 @@ func (b *Mapper) extractStructData(data ...any) (map[string][]*TableRowMateria,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// normalizeData 对输入数据进行统一处理和规范化
|
||||
// 支持输入为任意数量的参数,参数可以是单个结构体指针或结构体,也可以是结构体切片或指针切片
|
||||
// 处理逻辑包括:
|
||||
// 1. 将切片类型的参数拆开放入一个统一的一维切片中(展平)
|
||||
// 2. 跳过其中的 nil 元素,确保数据有效性
|
||||
// 3. 将所有非指针类型的元素转换为对应的指针类型,方便后续统一处理
|
||||
func (b *Mapper) normalizeData(data ...any) []any {
|
||||
var normalizedData []any
|
||||
|
||||
for _, item := range data {
|
||||
if item == nil {
|
||||
// 跳过nil值,避免后续反射调用panic
|
||||
continue
|
||||
}
|
||||
itemType := reflect.TypeOf(item)
|
||||
if itemType.Kind() == reflect.Slice {
|
||||
// 处理切片类型参数,展平成单个元素
|
||||
sliceValue := reflect.ValueOf(item)
|
||||
for i := 0; i < sliceValue.Len(); i++ {
|
||||
elem := sliceValue.Index(i).Interface()
|
||||
if elem == nil {
|
||||
// 跳过nil元素
|
||||
continue
|
||||
}
|
||||
normalizedData = append(normalizedData, elem)
|
||||
}
|
||||
} else {
|
||||
// 非切片类型直接追加
|
||||
normalizedData = append(normalizedData, item)
|
||||
}
|
||||
}
|
||||
|
||||
// 转换所有元素为指针类型,便于后续一致性处理
|
||||
for i, item := range normalizedData {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
itemType := reflect.TypeOf(item)
|
||||
if itemType.Kind() != reflect.Ptr {
|
||||
// 创建对应类型的指针
|
||||
itemPtr := reflect.New(itemType)
|
||||
// 设置指针指向的值为元素本身
|
||||
itemPtr.Elem().Set(reflect.ValueOf(item))
|
||||
// 替换切片中的元素为指针类型
|
||||
normalizedData[i] = itemPtr.Interface()
|
||||
}
|
||||
}
|
||||
return normalizedData
|
||||
}
|
||||
|
||||
func (b *Mapper) ToInsertSQL(data ...any) (string, error) {
|
||||
// 统一规范化处理输入数据,将切片拆平并转换元素为指针
|
||||
normalizedData := b.normalizeData(data...)
|
||||
|
||||
if len(normalizedData) == 0 {
|
||||
return "", fmt.Errorf("data is empty")
|
||||
}
|
||||
|
||||
// 扫描 struct 类型数据
|
||||
if err := b.scanStruct(data...); err != nil {
|
||||
if err := b.scanStruct(normalizedData...); err != nil {
|
||||
return "", fmt.Errorf("failed to scan struct: %w", err)
|
||||
}
|
||||
|
||||
// 提取 struct 内的信息
|
||||
tableMap, err := b.extractStructData(data...)
|
||||
tableMap, err := b.extractStructData(normalizedData...)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to extract struct data: %w", err)
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ func TestBuilderInsert(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
insertSql, err := tdMapper.ToInsertSQL(data...)
|
||||
insertSql, err := tdMapper.ToInsertSQL(data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -91,12 +91,12 @@ func (u *User) SuperTableName() string {
|
||||
|
||||
func TestSimpleInsert(t *testing.T) {
|
||||
tdMapper := NewMapper()
|
||||
data := []any{
|
||||
&User{Name: "张三", Age: 18},
|
||||
&User{Name: "李四", Age: 20},
|
||||
data := []User{
|
||||
{Name: "张三", Age: 18},
|
||||
{Name: "李四", Age: 20},
|
||||
}
|
||||
|
||||
insertSql, err := tdMapper.ToInsertSQL(data...)
|
||||
insertSql, err := tdMapper.ToInsertSQL(data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -124,15 +124,15 @@ func (s *SuperDev) TableName() string {
|
||||
|
||||
func TestSuperDevInsert(t *testing.T) {
|
||||
var data = []any{
|
||||
&SuperDev{
|
||||
SuperDev{
|
||||
SuperDevTAG: SuperDevTAG{DevId: "SN001", DevType: "模拟设备"},
|
||||
Ts: time.Now(), AppSn: "a0001", Ct: 1.0,
|
||||
},
|
||||
&SuperDev{
|
||||
SuperDev{
|
||||
SuperDevTAG: SuperDevTAG{DevId: "SN001", DevType: "模拟设备"},
|
||||
Ts: time.Now().Add(time.Second), AppSn: "a0002", Ct: 2.0,
|
||||
},
|
||||
&SuperDev{
|
||||
SuperDev{
|
||||
SuperDevTAG: SuperDevTAG{DevId: "SN002", DevType: "模拟设备"},
|
||||
Ts: time.Now(), AppSn: "a0003", Ct: 3.0,
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user