package tdmap import ( "fmt" "reflect" ) func scan(data interface{}) (*StructMate, error) { // 获取结构体的类型 t, v := getReflectTypeAndValue(data) // 确保是结构体类型 if t.Kind() != reflect.Struct { return nil, fmt.Errorf("input data is not a struct") } // 获取包路径和类型名称 uniqueTypeName := getUniqueTypeName(t) // 初始化结果结构体 sr := StructMate{ UniqueTypeName: uniqueTypeName, DBName2IndexCache: make(map[string][]int, t.NumField()), Field2IndexCache: make(map[string][]int, t.NumField()), Filed2DBNameCache: make(map[string]string, t.NumField()), DBAnnotatedNames: make([]string, 0, t.NumField()), TaggedFieldNames: make([]string, 0, t.NumField()), SuperTableName: "", } //timeType := reflect.TypeOf(time.Time{}) // 遍历结构体的字段 for i := 0; i < t.NumField(); i++ { field := t.Field(i) fieldValue := v.Field(i) if field.Anonymous { if field.Type.Kind() == reflect.Ptr { if fieldValue.IsNil() { // 如果指针是 nil,创建一个该类型的零值实例 zeroValue := reflect.Zero(field.Type.Elem()) fieldValue = zeroValue } else { fieldValue = fieldValue.Elem() } } if !fieldValue.CanInterface() { continue } subResult, err := scan(fieldValue.Interface()) if err != nil { return nil, err } for k, v := range subResult.DBName2IndexCache { sr.DBName2IndexCache[k] = append(sr.DBName2IndexCache[k], i) sr.DBName2IndexCache[k] = append(sr.DBName2IndexCache[k], v...) } for k, v := range subResult.Field2IndexCache { sr.Field2IndexCache[k] = append(sr.Field2IndexCache[k], i) sr.Field2IndexCache[k] = append(sr.Field2IndexCache[k], v...) } for k, v := range subResult.Filed2DBNameCache { sr.Filed2DBNameCache[k] = v } sr.DBAnnotatedNames = append(sr.DBAnnotatedNames, subResult.DBAnnotatedNames...) sr.TaggedFieldNames = append(sr.TaggedFieldNames, subResult.TaggedFieldNames...) continue } // 检查字段是否有db注解 columnName := field.Tag.Get("db") if columnName == "-" || columnName == "" { continue } sr.Field2IndexCache[field.Name] = append(sr.Field2IndexCache[field.Name], i) sr.DBName2IndexCache[columnName] = append(sr.DBName2IndexCache[columnName], i) sr.Filed2DBNameCache[field.Name] = columnName // 检查字段是否有taos注解 if field.Tag.Get("taos") == "tag" { sr.TaggedFieldNames = append(sr.TaggedFieldNames, field.Name) } else { sr.DBAnnotatedNames = append(sr.DBAnnotatedNames, field.Name) } } sr.SuperTableName = callSuperTableName(data) return &sr, nil } // 获取包路径和类型名称 func getUniqueTypeName(t reflect.Type) string { pkgPath := t.PkgPath() typeName := t.Name() uniqueTypeName := fmt.Sprintf("%s.%s", pkgPath, typeName) return uniqueTypeName } func getReflectTypeAndValue(data any) (reflect.Type, reflect.Value) { t := reflect.TypeOf(data) v := reflect.ValueOf(data) // 处理结构体和结构体指针 for t.Kind() == reflect.Ptr { t = t.Elem() v = v.Elem() } return t, v } func callSuperTableName(obj any) string { v := reflect.ValueOf(obj) if v.Kind() == reflect.Struct { return "" } // 检查是否可以调用 SuperTableName 方法 superTableNameMethod := v.MethodByName("SuperTableName") if !superTableNameMethod.IsValid() { return "" } // 调用 SuperTableName 方法 results := superTableNameMethod.Call(nil) if len(results) == 1 && results[0].Kind() == reflect.String { return results[0].String() } return "" }