1 Star 2 Fork 0

虚月/vload

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
loader.go 3.96 KB
一键复制 编辑 原始数据 按行查看 历史
蔡小光 提交于 2024-12-03 09:34 +08:00 . feat: 初始化项目代码
package vload
import (
"fmt"
"reflect"
)
// AddMapping 添加字段映射和对应的值获取器
func (l *Loader) AddMapping(group string, pairs []Pair, getter interface{}) {
// 设置默认类型
for i := range pairs {
if pairs[i].SourceType == reflect.Invalid {
pairs[i].SourceType = reflect.Int64
}
if pairs[i].TargetType == reflect.Invalid {
pairs[i].TargetType = reflect.String
}
pairs[i].Group = group
}
l.pairs[group] = pairs
l.getters[group] = getter
}
// Load 加载数据
func (l *Loader) Load(data interface{}) error {
val := reflect.ValueOf(data)
if val.Kind() != reflect.Ptr {
return fmt.Errorf("data must be a pointer")
}
val = val.Elem()
// 根据数据类型选择处理方法
switch val.Kind() {
case reflect.Struct:
return l.loadStruct(val)
case reflect.Slice:
return l.loadSlice(val)
default:
return fmt.Errorf("unsupported data type: %v", val.Kind())
}
}
// hasValidPairs 检查结构体是否包含任何有效的字段映射对
func (l *Loader) hasValidPairs(typ reflect.Type) bool {
validPairsByGroup := l.getValidPairs(typ)
for _, pairs := range validPairsByGroup {
if len(pairs) > 0 {
return true
}
}
return false
}
// getValidPairs 获取结构体中有效的字段映射对,按分组返回
func (l *Loader) getValidPairs(typ reflect.Type) map[string][]Pair {
result := make(map[string][]Pair)
for group, pairs := range l.pairs {
var validPairs []Pair
for _, pair := range pairs {
if _, hasSource := typ.FieldByName(pair.SourceField); hasSource {
if _, hasTarget := typ.FieldByName(pair.TargetField); hasTarget {
validPairs = append(validPairs, pair)
}
}
}
if len(validPairs) > 0 {
result[group] = validPairs
}
}
return result
}
// loadSlice 加载切片数据
func (l *Loader) loadSlice(slice reflect.Value) error {
if slice.Len() == 0 {
return nil
}
// 获取切片元素类型
elemType := slice.Type().Elem()
// 如果是指针类型,获取指针指向的类型
if elemType.Kind() == reflect.Ptr {
elemType = elemType.Elem()
}
if elemType.Kind() != reflect.Struct {
return fmt.Errorf("slice element must be struct type or pointer to struct type")
}
// 检查是否有有效的字段映射对
if !l.hasValidPairs(elemType) {
return nil
}
// 获取有效的字段映射对
validPairsByGroup := l.getValidPairs(elemType)
// 收集所有键
keysByGroup := make(map[string]map[interface{}]struct{})
for i := 0; i < slice.Len(); i++ {
elem := slice.Index(i)
// 如果是指针类型,获取指针指向的值
if elem.Kind() == reflect.Ptr {
elem = elem.Elem()
}
l.collectKeys(elem, keysByGroup, validPairsByGroup)
}
// 处理每个分组
for group, keys := range keysByGroup {
// 转换键为列表
var keyList []interface{}
for key := range keys {
keyList = append(keyList, key)
}
getter := l.getters[group]
valueMap, err := callGetter(getter, keyList)
if err != nil {
return err
}
// 填充值
validPairs := validPairsByGroup[group]
for i := 0; i < slice.Len(); i++ {
elem := slice.Index(i)
// 如果是指针类型,获取指针指向的值
if elem.Kind() == reflect.Ptr {
elem = elem.Elem()
}
l.fillValues(elem, valueMap, validPairs)
}
}
return nil
}
// loadStruct 加载单个结构体
func (l *Loader) loadStruct(val reflect.Value) error {
// 检查是否有有效的字段映射对
if !l.hasValidPairs(val.Type()) {
return nil
}
// 获取有效的字段映射对
validPairsByGroup := l.getValidPairs(val.Type())
// 收集所有键
keysByGroup := make(map[string]map[interface{}]struct{})
l.collectKeys(val, keysByGroup, validPairsByGroup)
// 处理每个分组
for group, keys := range keysByGroup {
// 转换键为列表
var keyList []interface{}
for key := range keys {
keyList = append(keyList, key)
}
getter := l.getters[group]
valueMap, err := callGetter(getter, keyList)
if err != nil {
return err
}
l.fillValues(val, valueMap, validPairsByGroup[group])
}
return nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/virtual-moon/vload.git
git@gitee.com:virtual-moon/vload.git
virtual-moon
vload
vload
v1.0.0

搜索帮助