-
Notifications
You must be signed in to change notification settings - Fork 0
/
csvconfig.go
256 lines (216 loc) · 6.07 KB
/
csvconfig.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
package csvconfig
import (
"encoding/csv"
"fmt"
"io"
"os"
"sort"
"github.com/zxfonline/misc/fileutil"
"github.com/zxfonline/misc/log"
)
var (
//已经加载的文件缓存
_tables map[string]*Table
//文件路径
pathPre string
//文件后缀
filesuffix string
)
type Record struct {
Fields map[string]string
}
type Table struct {
Records []*Record
}
type Query struct {
Key string
Value string
}
//初始化参数
func Init(pathpre, suffix string) {
filesuffix = suffix
if filesuffix == "" {
filesuffix = ".csv"
}
pathPre = pathpre
}
func findFile(table string) (*os.File, error) {
return fileutil.FindFile(fileutil.PathJoin(pathPre, table+filesuffix), os.O_RDONLY, 0)
}
//加载所有配置文件,如果已经加载则覆盖
func Load(_table_list []string) error {
_tables = make(map[string]*Table)
for _, table := range _table_list {
log.Infof("Load csv config: %v", table)
f, err := findFile(table)
if err != nil {
return err
}
defer f.Close()
err = _initTable(table, f)
if err != nil {
return err
}
}
return nil
}
func _initTable(table string, f *os.File) error {
reader := csv.NewReader(f)
title, err := reader.Read()
if err != nil {
return fmt.Errorf("parse csv config:%v ,error:%v", table, err)
}
for idx, val := range title {
title[idx] = val
}
t := Table{Records: make([]*Record, 0)}
for {
line, err := reader.Read()
if err == io.EOF {
break
} else if nil != err {
return fmt.Errorf("parse csv config:%v ,error:%v", table, err)
}
rec := Record{Fields: make(map[string]string)}
for idx, val := range line {
rec.Fields[title[idx]] = val
}
t.Records = append(t.Records, &rec)
}
_tables[table] = &t
return nil
}
func GetString(table string, queryField string, val string, field string) string {
rec := getOne(table, queryField, val)
if rec == nil {
return ""
}
v, ok := rec.Fields[field]
if !ok {
return ""
}
return v
}
func getOne(tableName string, queryField string, val string) *Record {
table, ok := _tables[tableName]
if !ok {
return nil
}
for _, rec := range table.Records {
v, ok := rec.Fields[queryField]
if !ok {
return nil
}
if v == val {
return rec
}
}
return nil
}
func GetLines(table string, querys []*Query) []*Record {
return getLines(table, querys)
}
func GetLine(table string, querys []*Query) *Record {
ret := getLines(table, querys)
if len(ret) > 0 {
return ret[0]
}
return nil
}
func getLines(tableName string, querys []*Query) []*Record {
table, ok := _tables[tableName]
if !ok {
return nil
}
var match bool
lines := make([]*Record, 0)
for _, rec := range table.Records {
match = true
for _, query := range querys {
v, ok := rec.Fields[query.Key]
if !ok {
match = false
break
}
if v != query.Value {
match = false
break
}
}
if match {
lines = append(lines, rec)
}
}
return lines
}
func GetAll(tableName string) []*Record {
table, ok := _tables[tableName]
if !ok {
return nil
}
lines := make([]*Record, len(table.Records))
idx := 0
for _, rec := range table.Records {
lines[idx] = rec
idx++
}
return lines
}
// Int8Slice attaches the methods of Interface to []int8, sorting in increasing order.
type Int8Slice []int8
func (p Int8Slice) Len() int { return len(p) }
func (p Int8Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Int8Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Sort is a convenience method.
func (p Int8Slice) Sort() { sort.Sort(p) }
// Ints8 sorts a slice of int8 in increasing order.
func Ints8(a []int8) { sort.Sort(Int8Slice(a)) }
// Int16Slice attaches the methods of Interface to []int16, sorting in increasing order.
type Int16Slice []int16
func (p Int16Slice) Len() int { return len(p) }
func (p Int16Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Int16Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Sort is a convenience method.
func (p Int16Slice) Sort() { sort.Sort(p) }
// Ints32 sorts a slice of int16 in increasing order.
func Ints16(a []int16) { sort.Sort(Int16Slice(a)) }
// Int32Slice attaches the methods of Interface to []int32, sorting in increasing order.
type Int32Slice []int32
func (p Int32Slice) Len() int { return len(p) }
func (p Int32Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Int32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Sort is a convenience method.
func (p Int32Slice) Sort() { sort.Sort(p) }
// Ints32 sorts a slice of int32 in increasing order.
func Ints32(a []int32) { sort.Sort(Int32Slice(a)) }
// Int64Slice attaches the methods of Interface to []int64, sorting in increasing order.
type Int64Slice []int64
func (p Int64Slice) Len() int { return len(p) }
func (p Int64Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Sort is a convenience method.
func (p Int64Slice) Sort() { sort.Sort(p) }
// Ints64 sorts a slice of int64 in increasing order.
func Ints64(a []int64) { sort.Sort(Int64Slice(a)) }
// Float32Slice attaches the methods of Interface to []float32, sorting in increasing order.
type Float32Slice []float32
func (p Float32Slice) Len() int { return len(p) }
func (p Float32Slice) Less(i, j int) bool { return p[i] < p[j] || isNaN32(p[i]) && !isNaN32(p[j]) }
func (p Float32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// isNaN32 is a copy of math.IsNaN to avoid a dependency on the math package.
func isNaN32(f float32) bool {
return f != f
}
// Sort is a convenience method.
func (p Float32Slice) Sort() { sort.Sort(p) }
// Float64Slice attaches the methods of Interface to []float64, sorting in increasing order.
type Float64Slice []float64
func (p Float64Slice) Len() int { return len(p) }
func (p Float64Slice) Less(i, j int) bool { return p[i] < p[j] || isNaN64(p[i]) && !isNaN64(p[j]) }
func (p Float64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// isNaN64 is a copy of math.IsNaN to avoid a dependency on the math package.
func isNaN64(f float64) bool {
return f != f
}
// Sort is a convenience method.
func (p Float64Slice) Sort() { sort.Sort(p) }