forked from magiclvzs/antnet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config_csv.go
147 lines (128 loc) · 3.64 KB
/
config_csv.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package antnet
import (
"encoding/csv"
"os"
"reflect"
"strings"
)
type GenConfigObj struct {
GenObjFun func() interface{}
ParseObjFun map[reflect.Kind]func(fieldv reflect.Value, data, path string) error
}
var csvParseMap = map[reflect.Kind]func(fieldv reflect.Value, data, path string) error{}
func SetCSVParseFunc(kind reflect.Kind, fun func(fieldv reflect.Value, data, path string) error) {
csvParseMap[kind] = fun
}
func GetCSVParseFunc(kind reflect.Kind) func(fieldv reflect.Value, data, path string) error {
return csvParseMap[kind]
}
func setValue(fieldv reflect.Value, item, data, path string, line int, f *GenConfigObj) error {
pm := csvParseMap
if f.ParseObjFun != nil {
pm = f.ParseObjFun
}
if fun, ok := pm[fieldv.Kind()]; ok {
err := fun(fieldv, data, path)
if err != nil {
LogError("csv read error path:%v line:%v err:%v field:%v", path, line, err, item)
}
return err
} else {
v, err := ParseBaseKind(fieldv.Kind(), data)
if err != nil {
LogError("csv read error path:%v line:%v err:%v field:%v", path, line, err, item)
return err
}
fieldv.Set(reflect.ValueOf(v))
}
return nil
}
/*
path 文件路径
nindex key值行号,从1开始
dataBegin 数据开始行号,从1开始
f 对象产生器 json:"-" tag字段会被跳过
*/
func ReadConfigFromCSV(path string, nindex int, dataBegin int, f *GenConfigObj) (error, []interface{}) {
csv_nimap := map[string]int{}
nimap := map[string]int{}
var dataObj []interface{}
fi, err := os.Open(path)
if err != nil {
return err, nil
}
csvdata, err := csv.NewReader(fi).ReadAll()
if err != nil {
return err, nil
}
dataCount := len(csvdata) - dataBegin + 1
dataObj = make([]interface{}, 0, dataCount)
for index, name := range csvdata[nindex-1] {
if name == "" {
continue
}
bname := []byte(name)
bname[0] = byte(int(bname[0]) & ^32)
csv_nimap[string(bname)] = index
}
typ := reflect.ValueOf(f.GenObjFun()).Elem().Type()
for i := 0; i < typ.NumField(); i++ {
fieldt := typ.FieldByIndex([]int{i})
name := fieldt.Name
if v, ok := csv_nimap[name]; ok {
nimap[name] = v
} else if fieldt.Tag.Get("json") != "-" {
LogError("config index not found path:%s name:%s", path, name)
return ErrCSVParse, nil
}
}
for i := dataBegin - 1; i < len(csvdata); i++ {
obj := f.GenObjFun()
objv := reflect.ValueOf(obj)
obje := objv.Elem()
for k, v := range nimap {
switch obje.FieldByName(k).Kind() {
case reflect.Ptr:
err = setValue(obje.FieldByName(k).Elem(), k, strings.TrimSpace(csvdata[i][v]), path, i+1, f)
if err != nil {
return err, nil
}
default:
err = setValue(obje.FieldByName(k), k, strings.TrimSpace(csvdata[i][v]), path, i+1, f)
if err != nil {
return err, nil
}
}
}
dataObj = append(dataObj, obj)
}
return nil, dataObj
}
/*读取csv字段+值,竖着处理
[in] path 文件路径
[in] keyIndex 需要读取的字段列号
[in] valueIndex 需要读取的字段数据列号
[in] dataBegin 从哪一行开始输出
*/
func ReadConfigFromCSVLie(path string, keyIndex int, valueIndex int, dataBegin int, f *GenConfigObj) (error, interface{}) {
fi, err := os.Open(path)
if err != nil {
return err, nil
}
csvdata, err := csv.NewReader(fi).ReadAll()
if err != nil {
return err, nil
}
obj := f.GenObjFun()
robj := reflect.Indirect(reflect.ValueOf(obj))
for i := dataBegin - 1; i < len(csvdata); i++ {
name := csvdata[i][keyIndex-1]
bname := []byte(name)
bname[0] = byte(int(bname[0]) & ^32)
err = setValue(robj.FieldByName(string(bname)), string(bname), strings.TrimSpace(csvdata[i][valueIndex-1]), path, i+1, f)
if err != nil {
return err, nil
}
}
return nil, obj
}