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

import (
aaronchen2k2k's avatar
aaronchen2k2k 已提交
4
	"fmt"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
5 6
	"github.com/easysoft/zendata/src/model"
	constant "github.com/easysoft/zendata/src/utils/const"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
7
	fileUtils "github.com/easysoft/zendata/src/utils/file"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
8
	stringUtils "github.com/easysoft/zendata/src/utils/string"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
9
	"github.com/easysoft/zendata/src/utils/vari"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
10
	"github.com/mattn/go-runewidth"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
11
	"strconv"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
12 13 14
	"strings"
)

aaronchen2k2k's avatar
aaronchen2k2k 已提交
15
func GenerateForDefinition(defaultFile, configFile string, fieldsToExport *[]string, total int) ([][]string, []bool) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
16 17 18 19 20
	vari.DefaultDir = fileUtils.GetAbsDir(defaultFile)
	vari.ConfigDir = fileUtils.GetAbsDir(configFile)

	vari.Def = LoadConfigDef(defaultFile, configFile, fieldsToExport)
	vari.Res = LoadResDef(*fieldsToExport)
21

aaronchen2k2k's avatar
aaronchen2k2k 已提交
22 23
	fieldNameToValues := map[string][]string{}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
24 25
	colTypes := make([]bool, 0)

aaronchen2k2k's avatar
aaronchen2k2k 已提交
26
	// 为每个field生成值列表
aaronchen2k2k's avatar
aaronchen2k2k 已提交
27
	for index, field := range vari.Def.Fields {
28
		if !stringUtils.FindInArr(field.Field, *fieldsToExport) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
29 30
			continue
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
31

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

aaronchen2k2k's avatar
aaronchen2k2k 已提交
35
		fieldNameToValues[field.Field] = values
aaronchen2k2k's avatar
aaronchen2k2k 已提交
36
		colTypes = append(colTypes, field.IsNumb)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
37 38
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
39
	// 生成指定数量行的数据
aaronchen2k2k's avatar
aaronchen2k2k 已提交
40 41
	rows := make([][]string, 0)
	for i := 0; i < total; i++ {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
42
		for _, field := range vari.Def.Fields {
43
			if !stringUtils.FindInArr(field.Field, *fieldsToExport) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
44 45
				continue
			}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
46

aaronchen2k2k's avatar
aaronchen2k2k 已提交
47
			values := fieldNameToValues[field.Field]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
48
			fieldVal := values[i % len(values)]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
49
			if len(rows) == i { rows = append(rows, make([]string, 0)) }
aaronchen2k2k's avatar
aaronchen2k2k 已提交
50
			rows[i] = append(rows[i], fieldVal)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
51
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
52
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
53

aaronchen2k2k's avatar
aaronchen2k2k 已提交
54
	return rows, colTypes
aaronchen2k2k's avatar
aaronchen2k2k 已提交
55 56
}

57
func GenerateForField(field *model.DefField, total int, withFix bool) []string {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
58 59
	values := make([]string, 0)

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

67
		connectChildrenToSingleStr(arrOfArr, total, &values)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
68
		values = LoopSubFields(field, values, total, true)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
69

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

aaronchen2k2k's avatar
aaronchen2k2k 已提交
72
		if field.Use != "" { // refer to instance
73 74 75 76
			if field.Use == "privateIP" {
				fmt.Println("")
			}

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

94
		values = LoopSubFields(field, values, total, true)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
95

aaronchen2k2k's avatar
aaronchen2k2k 已提交
96 97 98
	} else if field.Config != "" { // refer to another define
		groupValues := vari.Res[field.Config]
		values = append(values, groupValues["all"]...)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
99
	} else { // basic field
aaronchen2k2k's avatar
aaronchen2k2k 已提交
100
		values = GenerateFieldItemsFromDefinition(field)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
101 102 103 104
	}

	return values
}
105

aaronchen2k2k's avatar
aaronchen2k2k 已提交
106
func GenerateFieldItemsFromDefinition(field *model.DefField) []string {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
107
	//if field.Loop == "" {field.Loop = "1"}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
108

aaronchen2k2k's avatar
aaronchen2k2k 已提交
109 110
	values := make([]string, 0)

aaronchen2k2k's avatar
aaronchen2k2k 已提交
111
	fieldValue := GenerateList(field)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
112 113 114 115 116

	index := 0
	count := 0
	for {
		// 处理格式、前后缀、loop等
aaronchen2k2k's avatar
aaronchen2k2k 已提交
117
		str := GenerateFieldValWithFix(field, fieldValue, &index, true)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
118 119 120
		values = append(values, str)

		count++
aaronchen2k2k's avatar
aaronchen2k2k 已提交
121
		if count >= constant.Total {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
122 123 124 125 126 127 128
			break
		}
	}

	return values
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
129
func GenerateFieldVal(field model.DefField, fieldValue model.FieldValue, index *int) string {
130
	str := ""
131

aaronchen2k2k's avatar
aaronchen2k2k 已提交
132 133
	// 叶节点
	idx := *index % len(fieldValue.Values)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
134
	val := fieldValue.Values[idx]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
135
	str = GetFieldValStr(field, val)
136

aaronchen2k2k's avatar
aaronchen2k2k 已提交
137
	return str
138 139
}

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

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

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

180
func LoopSubFields(field *model.DefField, oldValues []string, total int, withFix bool) []string {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
181
	//if field.Loop == "" {field.Loop = "1"}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
182 183 184 185 186

	values := make([]string, 0)
	fieldValue := model.FieldValue{}

	for _, val := range oldValues {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
187
		fieldValue.Values = append(fieldValue.Values, val)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
188 189 190 191 192 193
	}

	index := 0
	count := 0
	for {
		// 处理格式、前后缀、loop等
aaronchen2k2k's avatar
aaronchen2k2k 已提交
194
		str := GenerateFieldValWithFix(field, fieldValue, &index, withFix)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
195 196 197 198 199 200 201 202 203 204 205
		values = append(values, str)

		count++
		if count >= total {
			break
		}
	}

	return values
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
206
func GenerateFieldValWithFix(field *model.DefField, fieldValue model.FieldValue, indexOfRow *int, withFix bool) string {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
207 208 209
	prefix := field.Prefix
	postfix := field.Postfix

aaronchen2k2k's avatar
aaronchen2k2k 已提交
210
	computerLoop(field)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
211
	loopStr := ""
aaronchen2k2k's avatar
aaronchen2k2k 已提交
212
	for j := 0; j < (*field).LoopIndex; j++ {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
213 214 215 216
		if loopStr != "" {
			loopStr = loopStr + field.Loopfix
		}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
217
		str := GenerateFieldVal(*field, fieldValue, indexOfRow)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
218 219 220 221 222
		loopStr = loopStr + str

		*indexOfRow++
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
223
	if withFix && !vari.Trim {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
224 225 226
		loopStr = prefix + loopStr + postfix
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
227
	if field.Width > runewidth.StringWidth(loopStr) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
228 229 230 231 232 233
		loopStr = stringUtils.AddPad(loopStr, *field)
	}

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

aaronchen2k2k's avatar
aaronchen2k2k 已提交
236
	return loopStr
aaronchen2k2k's avatar
aaronchen2k2k 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
}

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
	}

	(*field).LoopIndex = (*field).LoopStart
258 259 260 261 262
}

func connectChildrenToSingleStr(arrOfArr [][]string, total int, values *[]string) {
	indexArr := getModArr(arrOfArr)

263 264
	for count := 0; count < total; count++ {
		str := ""
265
		for idx, row := range arrOfArr {
266
			str = str + row[count % indexArr[idx]] // get one item from each child, grouped as a1 or b2
267 268
		}

269
		*values = append(*values, str)
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
	}
}

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
}