generator.go 8.2 KB
Newer Older
aaronchen2k2k's avatar
aaronchen2k2k 已提交
1 2 3
package gen

import (
aaronchen2k2k's avatar
aaronchen2k2k 已提交
4
	"errors"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
5
	"fmt"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
6
	"github.com/easysoft/zendata/src/model"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
7
	fileUtils "github.com/easysoft/zendata/src/utils/file"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
8 9
	i118Utils "github.com/easysoft/zendata/src/utils/i118"
	logUtils "github.com/easysoft/zendata/src/utils/log"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
10
	stringUtils "github.com/easysoft/zendata/src/utils/string"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
11
	"github.com/easysoft/zendata/src/utils/vari"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
12
	"github.com/fatih/color"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
13
	"github.com/mattn/go-runewidth"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
14
	"strconv"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
15 16 17
	"strings"
)

aaronchen2k2k's avatar
aaronchen2k2k 已提交
18 19 20
func GenerateForDefinition(defaultFile, configFile string, fieldsToExport *[]string,
		total int) (rows [][]string, colIsNumArr []bool, err error) {

aaronchen2k2k's avatar
aaronchen2k2k 已提交
21 22 23 24
	vari.DefaultDir = fileUtils.GetAbsDir(defaultFile)
	vari.ConfigDir = fileUtils.GetAbsDir(configFile)

	vari.Def = LoadConfigDef(defaultFile, configFile, fieldsToExport)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
25 26 27 28
	if len(vari.Def.Fields) == 0 {
		err = errors.New("")
		return
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
29
	vari.Res = LoadResDef(*fieldsToExport)
30

31
	topFieldNameToValuesMap := map[string][]string{}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
32

aaronchen2k2k's avatar
aaronchen2k2k 已提交
33
	// 为每个field生成值列表
aaronchen2k2k's avatar
aaronchen2k2k 已提交
34
	for index, field := range vari.Def.Fields {
35
		if !stringUtils.FindInArr(field.Field, *fieldsToExport) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
36 37
			continue
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
38

39
		values := GenerateForField(&field, total, true)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
40
		vari.Def.Fields[index].Precision = field.Precision
aaronchen2k2k's avatar
aaronchen2k2k 已提交
41

42
		topFieldNameToValuesMap[field.Field] = values
aaronchen2k2k's avatar
aaronchen2k2k 已提交
43
		colIsNumArr = append(colIsNumArr, field.IsNumb)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
44 45
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
46 47 48 49 50
	// 处理数据
	arrOfArr := make([][]string, 0) // 2 dimension arr for child, [ [a,b,c], [1,2,3] ]
	for _, child := range vari.Def.Fields {
		if !stringUtils.FindInArr(child.Field, *fieldsToExport) {
			continue
aaronchen2k2k's avatar
aaronchen2k2k 已提交
51
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
52 53 54

		childValues := topFieldNameToValuesMap[child.Field]
		arrOfArr = append(arrOfArr, childValues)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
55
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
56
	rows = putChildrenToArr(arrOfArr, total)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
57

aaronchen2k2k's avatar
aaronchen2k2k 已提交
58
	return
aaronchen2k2k's avatar
aaronchen2k2k 已提交
59 60
}

61
func GenerateForField(field *model.DefField, total int, withFix bool) (values []string) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
62
	if len(field.Fields) > 0 { // sub fields
63
		arrOfArr := make([][]string, 0) // 2 dimension arr for child, [ [a,b,c], [1,2,3] ]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
64
		for _, child := range field.Fields {
65
			childValues := GenerateForField(&child, total, withFix)
66
			arrOfArr = append(arrOfArr, childValues)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
67 68
		}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
69
		count := total
aaronchen2k2k's avatar
aaronchen2k2k 已提交
70 71 72
		count = getRecordCount(arrOfArr)
		if count > total {
			count = total
aaronchen2k2k's avatar
aaronchen2k2k 已提交
73
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
74 75
		values = combineChildrenValues(arrOfArr, count)
		values = loopFieldValues(field, values, count, true)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
76

aaronchen2k2k's avatar
aaronchen2k2k 已提交
77
	} else if field.From != "" { // refer to res
78

aaronchen2k2k's avatar
aaronchen2k2k 已提交
79 80
		if field.Use != "" { // refer to instance
			groupValues := vari.Res[field.From]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
81 82
			groups := strings.Split(field.Use, ",")
			for _, group := range groups {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
83 84 85 86 87 88 89
				if group == "all" {
					for _, arr := range groupValues { // add all
						values = append(values, arr...)
					}
				} else {
					values = append(values, groupValues[group]...)
				}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
90
			}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
91 92
		} else if field.Select != "" { // refer to excel
			groupValues := vari.Res[field.From]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
93 94
			slct := field.Select
			values = append(values, groupValues[slct]...)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
95 96
		}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
97
		values = loopFieldValues(field, values, total, true)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
98

aaronchen2k2k's avatar
aaronchen2k2k 已提交
99
	} else if field.Config != "" { // refer to config
aaronchen2k2k's avatar
aaronchen2k2k 已提交
100 101
		groupValues := vari.Res[field.Config]
		values = append(values, groupValues["all"]...)
102

aaronchen2k2k's avatar
aaronchen2k2k 已提交
103
		values = loopFieldValues(field, values, total, true)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
104

105
	} else { // leaf field
aaronchen2k2k's avatar
aaronchen2k2k 已提交
106
		values = GenerateFieldValuesForDef(field)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
107 108 109 110
	}

	return values
}
111

aaronchen2k2k's avatar
aaronchen2k2k 已提交
112
func GenerateFieldValuesForDef(field *model.DefField) []string {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
113 114
	values := make([]string, 0)

aaronchen2k2k's avatar
aaronchen2k2k 已提交
115
	fieldWithValues := CreateList(field)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
116

aaronchen2k2k's avatar
aaronchen2k2k 已提交
117 118
	computerLoop(field)
	indexOfRow := 0
aaronchen2k2k's avatar
aaronchen2k2k 已提交
119 120 121
	count := 0
	for {
		// 处理格式、前后缀、loop等
aaronchen2k2k's avatar
aaronchen2k2k 已提交
122
		val := loopFieldValWithFix(field, fieldWithValues, &indexOfRow, true)
123
		values = append(values, val)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
124 125

		count++
aaronchen2k2k's avatar
aaronchen2k2k 已提交
126 127 128
		isRandomAndLoopEnd := (*field).IsLoop && (*field).LoopIndex == (*field).LoopEnd
		isNotRandomAndValOver := !(*field).IsLoop && indexOfRow >= len(fieldWithValues.Values)
		if count >= vari.Total || isRandomAndLoopEnd || isNotRandomAndValOver {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
129 130
			break
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
131 132 133 134 135

		(*field).LoopIndex = (*field).LoopIndex + 1
		if (*field).LoopIndex > (*field).LoopEnd {
			(*field).LoopIndex = (*field).LoopStart
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
136 137 138 139 140
	}

	return values
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
141
func GetFieldValStr(field model.DefField, val interface{}) string {
aaronchen2k2k's avatar
gen int  
aaronchen2k2k 已提交
142
	str := "n/a"
aaronchen2k2k's avatar
format  
aaronchen2k2k 已提交
143
	success := false
144

aaronchen2k2k's avatar
gen int  
aaronchen2k2k 已提交
145 146
	switch val.(type) {
		case int64:
aaronchen2k2k's avatar
format  
aaronchen2k2k 已提交
147 148 149 150 151 152
			if field.Format != "" {
				str, success = stringUtils.FormatStr(field.Format, val.(int64))
			}
			if !success {
				str = strconv.FormatInt(val.(int64), 10)
			}
aaronchen2k2k's avatar
gen int  
aaronchen2k2k 已提交
153 154 155 156 157
		case float64:
			precision := 0
			if field.Precision > 0 {
				precision = field.Precision
			}
aaronchen2k2k's avatar
format  
aaronchen2k2k 已提交
158 159 160 161 162 163
			if field.Format != "" {
				str, success = stringUtils.FormatStr(field.Format, val.(float64))
			}
			if !success {
				str = strconv.FormatFloat(val.(float64), 'f', precision, 64)
			}
aaronchen2k2k's avatar
gen int  
aaronchen2k2k 已提交
164 165
		case byte:
			str = string(val.(byte))
aaronchen2k2k's avatar
format  
aaronchen2k2k 已提交
166 167 168 169 170 171
			if field.Format != "" {
				str, success = stringUtils.FormatStr(field.Format, str)
			}
			if !success {
				str = string(val.(byte))
			}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
172 173
		case string:
			str = val.(string)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
174
			fmt.Sprintf(str)
aaronchen2k2k's avatar
gen int  
aaronchen2k2k 已提交
175 176 177 178
		default:
	}

	return str
aaronchen2k2k's avatar
aaronchen2k2k 已提交
179 180
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
181
func loopFieldValues(field *model.DefField, oldValues []string, total int, withFix bool) (values []string) {
182
	fieldValue := model.FieldWithValues{}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
183 184

	for _, val := range oldValues {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
185
		fieldValue.Values = append(fieldValue.Values, val)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
186 187
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
188
	computerLoop(field)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
189
	indexOfRow := 0
aaronchen2k2k's avatar
aaronchen2k2k 已提交
190 191 192
	count := 0
	for {
		// 处理格式、前后缀、loop等
aaronchen2k2k's avatar
aaronchen2k2k 已提交
193
		str := loopFieldValWithFix(field, fieldValue, &indexOfRow, withFix)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
194 195 196
		values = append(values, str)

		count++
aaronchen2k2k's avatar
aaronchen2k2k 已提交
197 198 199
		isRandomAndLoopEnd := (*field).IsLoop && (*field).LoopIndex == (*field).LoopEnd
		isNotRandomAndValOver := !(*field).IsLoop && indexOfRow >= len(fieldValue.Values)
		if count >= vari.Total || isRandomAndLoopEnd || isNotRandomAndValOver {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
200 201
			break
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
202 203 204 205 206

		(*field).LoopIndex = (*field).LoopIndex + 1
		if (*field).LoopIndex > (*field).LoopEnd {
			(*field).LoopIndex = (*field).LoopStart
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
207 208
	}

209
	return
aaronchen2k2k's avatar
aaronchen2k2k 已提交
210 211
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
212
func loopFieldValWithFix(field *model.DefField, fieldValue model.FieldWithValues,
213
		indexOfRow *int, withFix bool) (loopStr string) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
214 215 216
	prefix := field.Prefix
	postfix := field.Postfix

aaronchen2k2k's avatar
aaronchen2k2k 已提交
217
	for j := 0; j < (*field).LoopIndex; j++ {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
218 219 220 221
		if loopStr != "" {
			loopStr = loopStr + field.Loopfix
		}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
222 223 224 225
		str, err := GenerateFieldVal(*field, fieldValue, indexOfRow)
		if err != nil {
			str = "N/A"
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
226 227 228 229 230
		loopStr = loopStr + str

		*indexOfRow++
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
231
	if withFix && !vari.Trim {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
232 233 234
		loopStr = prefix + loopStr + postfix
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
235
	if field.Width > runewidth.StringWidth(loopStr) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
236 237 238
		loopStr = stringUtils.AddPad(loopStr, *field)
	}

239 240 241
	return
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
242
func GenerateFieldVal(field model.DefField, fieldValue model.FieldWithValues, index *int) (val string, err error) {
243
	// 叶节点
aaronchen2k2k's avatar
aaronchen2k2k 已提交
244 245 246 247 248 249
	if len(fieldValue.Values) == 0 {
		logUtils.PrintToWithColor(i118Utils.I118Prt.Sprintf("fail_to_generate_field", field.Field), color.FgCyan)
		err = errors.New("")
		return
	}

250 251 252 253 254
	idx := *index % len(fieldValue.Values)
	str := fieldValue.Values[idx]
	val = GetFieldValStr(field, str)

	return
aaronchen2k2k's avatar
aaronchen2k2k 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
}

func computerLoop(field *model.DefField) {
	if (*field).LoopIndex != 0 {
		return
	}

	arr := strings.Split(field.Loop, "-")
	(*field).LoopStart, _ = strconv.Atoi(arr[0])
	if len(arr) > 1 {
		field.LoopEnd, _ = strconv.Atoi(arr[1])
	}

	if (*field).LoopStart == 0 {
		(*field).LoopStart = 1
	}
	if (*field).LoopEnd == 0 {
		(*field).LoopEnd = 1
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
275 276 277 278
	if (*field).LoopStart > 0 || (*field).LoopEnd > 0 {
		(*field).IsLoop = false
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
279
	(*field).LoopIndex = (*field).LoopStart
280 281
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
282 283 284 285 286
func putChildrenToArr(arrOfArr [][]string, total int) (values [][]string) {
	indexArr := make([]int, 0)
	if vari.Recursive {
		indexArr = getModArr(arrOfArr)
	}
287

aaronchen2k2k's avatar
aaronchen2k2k 已提交
288
	for i := 0; i < total; i++ {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
289
		strArr := make([]string, 0)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
290 291 292
		for j := 0; j < len(arrOfArr); j++ {
			child := arrOfArr[j]

aaronchen2k2k's avatar
aaronchen2k2k 已提交
293 294 295 296 297 298 299 300 301
			var index int
			if vari.Recursive {
				mod := indexArr[j]
				index = i / mod % len(child)
			} else {
				index = i % len(child)
			}

			strArr = append(strArr, child[index])
302 303
		}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
304 305 306 307 308 309
		values = append(values, strArr)
	}

	return
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
310
func combineChildrenValues(arrOfArr [][]string, total int) (ret []string)  {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
311 312 313 314
	valueArr := putChildrenToArr(arrOfArr, total)

	for _, arr := range valueArr {
		ret = append(ret, strings.Join(arr, ""))
315
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
316
	return
317 318
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
319 320 321 322 323 324 325 326 327
func getRecordCount(arrOfArr [][]string) int {
	count := 1
	for i := 0; i < len(arrOfArr); i++ {
		arr := arrOfArr[i]
		count = len(arr) * count
	}
	return count
}

328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
func getModArr(arrOfArr [][]string) []int {
	indexArr := make([]int, 0)
	for _, _ = range arrOfArr {
		indexArr = append(indexArr, 0)
	}

	for i := 0; i < len(arrOfArr); i++ {
		loop := 1
		for j := i + 1; j < len(arrOfArr); j++ {
			loop = loop * len(arrOfArr[j])
		}

		indexArr[i] = loop
	}

	return indexArr
}