-
Notifications
You must be signed in to change notification settings - Fork 10
/
result_struct.go
76 lines (69 loc) · 2.3 KB
/
result_struct.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package osm
import (
"fmt"
"reflect"
)
func resultStruct(logPrefix string, o *osmBase, id, sql string, sqlParams []interface{}, container interface{}) (int64, error) {
pointValue := reflect.ValueOf(container)
if pointValue.Kind() != reflect.Ptr {
return 0, fmt.Errorf("sql '%s' error : struct类型Query,查询结果类型应为struct的指针,而您传入的并不是指针", id)
}
value := reflect.Indirect(pointValue)
valueElem := value
isStructPtr := value.Kind() == reflect.Ptr
if isStructPtr {
valueElem = reflect.New(value.Type().Elem()).Elem()
}
if valueElem.Kind() != reflect.Struct {
return 0, fmt.Errorf("sql '%s' error : struct类型Query,查询结果类型应为struct的指针,而您传入的并不是struct", id)
}
rows, err := o.db.Query(sql, sqlParams...)
if err != nil {
return 0, fmt.Errorf("sql '%s' error : %s", id, err.Error())
}
defer rows.Close()
if rows.Next() {
columns, err := rows.Columns()
if err != nil {
return 0, fmt.Errorf("sql '%s' error : %s", id, err.Error())
}
columnsCount := len(columns)
elementTypes := make([]reflect.Type, columnsCount)
isPtrs := make([]bool, columnsCount)
values := make([]reflect.Value, columnsCount)
structType := valueElem.Type()
allFieldNameTypeMap := map[string]*reflect.Type{} // struct每个成员的名字,不一定与sql中的列对应
getStructFieldMap(structType, allFieldNameTypeMap)
for i, col := range columns {
filedName, t := findFiled(allFieldNameTypeMap, col)
if filedName != "" && t != nil {
f := valueElem.FieldByName(filedName)
elementTypes[i] = f.Type()
isPtrs[i] = elementTypes[i].Kind() == reflect.Ptr
values[i] = f
} else {
a := ""
elementTypes[i] = reflect.TypeOf(a)
values[i] = reflect.ValueOf(&a).Elem()
}
}
err = o.scanRow(logPrefix, rows, isPtrs, elementTypes, values)
if err != nil {
return 0, fmt.Errorf("sql '%s' error : %s", id, err.Error())
}
if isStructPtr {
value.Set(valueElem.Addr())
}
}
return 1, nil
}
func getStructFieldMap(t reflect.Type, m map[string]*reflect.Type) {
for i := 0; i < t.NumField(); i++ {
t := t.Field(i)
if t.Anonymous && t.Type.Kind() == reflect.Struct {
getStructFieldMap(t.Type, m)
continue
}
m[t.Name] = &(t.Type)
}
}