generator.go 6.3 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 7
	"github.com/easysoft/zendata/src/model"
	constant "github.com/easysoft/zendata/src/utils/const"
	stringUtils "github.com/easysoft/zendata/src/utils/string"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
8
	"regexp"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
9
	"strconv"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
10 11 12
	"strings"
)

aaronchen2k2k's avatar
aaronchen2k2k 已提交
13
func GenerateForDefinition(total int, fieldsToExport string, out string, table string) ([][]string, []bool) {
14 15
	def := constant.Definition

aaronchen2k2k's avatar
aaronchen2k2k 已提交
16 17 18
	fieldsToExportArr := strings.Split(fieldsToExport, ",")
	fieldNameToValues := map[string][]string{}

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

aaronchen2k2k's avatar
aaronchen2k2k 已提交
21
	// 为每个field生成值列表
aaronchen2k2k's avatar
aaronchen2k2k 已提交
22
	for index, field := range def.Fields {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
23
		if !stringUtils.FindInArr(field.Name, fieldsToExportArr) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
24 25
			continue
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
26 27

		values := GenerateForField(&field, total)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
28
		def.Fields[index].Precision = field.Precision
aaronchen2k2k's avatar
aaronchen2k2k 已提交
29 30

		fieldNameToValues[field.Name] = values
aaronchen2k2k's avatar
aaronchen2k2k 已提交
31
		colTypes = append(colTypes, field.IsNumb)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
32 33
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
34
	// 生成指定数量行的数据
aaronchen2k2k's avatar
aaronchen2k2k 已提交
35 36 37
	rows := make([][]string, 0)
	for i := 0; i < total; i++ {
		for _, field := range def.Fields {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
38
			if !stringUtils.FindInArr(field.Name, fieldsToExportArr) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
39 40
				continue
			}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
41

aaronchen2k2k's avatar
aaronchen2k2k 已提交
42 43
			values := fieldNameToValues[field.Name]
			fieldVal := values[i % len(values)]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
44
			if len(rows) == i { rows = append(rows, make([]string, 0)) }
aaronchen2k2k's avatar
aaronchen2k2k 已提交
45
			rows[i] = append(rows[i], fieldVal)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
46
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
47
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
48

aaronchen2k2k's avatar
aaronchen2k2k 已提交
49
	return rows, colTypes
aaronchen2k2k's avatar
aaronchen2k2k 已提交
50 51
}

52
func GenerateForField(field *model.Field,  total int) []string {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
53 54
	convertFieldReferToNestedIfNeeded(field)

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

57
	if len(field.Fields) > 0 { // nested definition
aaronchen2k2k's avatar
aaronchen2k2k 已提交
58 59 60 61 62 63 64 65 66 67 68 69
		arr := make([][]string, 0)
		for _, child := range field.Fields {
			childValues := GenerateForField(&child, total)
			arr = append(arr, childValues)
		}

		for i := 0; i < total; i++ {
			concat := ""
			for _, row := range arr {
				concat = concat + row[i]
			}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
70
			concat = field.Prefix + concat + field.Postfix
aaronchen2k2k's avatar
aaronchen2k2k 已提交
71 72
			values = append(values, concat)
		}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
73 74
		values = LoopSubFields(field, values, total)

75
	} else if field.Type == "list" { // list type
76
		values = GenerateFieldItemsFromDefinition(field, total)
77 78 79 80 81 82 83

	} else if field.Type == "custom" { // custom type
		if field.Range != "" { // specific custom file
			LoadDefinitionFromFile(constant.ResDir + field.Range)
		}

		referField := constant.LoadedFields[field.Name]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
84
		values = GenerateForField(&referField, total)
85

86
	} else {// like address.city to refer to other custom fields
87 88
		arr := strings.Split(field.Type, ".")
		referField := constant.LoadedFields[arr[0]]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
89
		referField.Filter = field.Range
aaronchen2k2k's avatar
aaronchen2k2k 已提交
90
		referField.Format = field.Format
91 92 93 94
		referField.Prefix = field.Prefix
		referField.Postfix = field.Postfix
		referField.Loop = field.Loop
		referField.Loopfix = field.Loopfix
95 96

		values = GenerateFieldItemsFromDefinition(&referField, total)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
97 98 99 100
	}

	return values
}
101 102

func GenerateFieldItemsFromDefinition(field *model.Field, total int) []string {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
103 104
	if field.Loop == 0 {field.Loop = 1}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
105 106 107
	values := make([]string, 0)

	// 整理出值的列表
108 109 110 111 112
	datatype := strings.TrimSpace(field.Type)
	if datatype == "" { datatype = "list" }

	fieldValue := model.FieldValue{}

113 114
	//switch datatype {
	//case constant.LIST.String():
115
		fieldValue = GenerateList(field, total)
116 117
	//default:
	//}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
118 119 120 121 122

	index := 0
	count := 0
	for {
		// 处理格式、前后缀、loop等
aaronchen2k2k's avatar
aaronchen2k2k 已提交
123
		str := GenerateFieldValWithFix(*field, fieldValue, &index, true)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
124 125 126 127 128 129 130 131 132 133 134 135
		values = append(values, str)

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

	return values
}

func GenerateFieldVal(field model.Field, fieldValue model.FieldValue, index *int) string {
136
	str := ""
137

aaronchen2k2k's avatar
aaronchen2k2k 已提交
138 139 140 141
	// 叶节点
	idx := *index % len(fieldValue.Values)
	val := fieldValue.Values[idx]
	str = GetFieldValStr(field, val)
142

aaronchen2k2k's avatar
aaronchen2k2k 已提交
143
	return str
144 145 146
}

func GetFieldValStr(field model.Field, val interface{}) string {
aaronchen2k2k's avatar
gen int  
aaronchen2k2k 已提交
147
	str := "n/a"
aaronchen2k2k's avatar
format  
aaronchen2k2k 已提交
148
	success := false
149

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

	return str
aaronchen2k2k's avatar
aaronchen2k2k 已提交
184 185 186
}

func convertFieldReferToNestedIfNeeded(field *model.Field) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
187
	// ${user_name}_${numb}@${domain}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
188
	regx := regexp.MustCompile(`\$\{([a-zA-z0-9_]+)\}`)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
189
	arrOfName := regx.FindAllStringSubmatch(field.Range, -1)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
190

aaronchen2k2k's avatar
aaronchen2k2k 已提交
191
	if len(arrOfName) > 0 {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
192 193 194
		strLeft := field.Range
		for index, a := range arrOfName {
			found := a[0]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
195 196
			name := a[1]

aaronchen2k2k's avatar
aaronchen2k2k 已提交
197 198 199 200 201 202 203 204
			arr := strings.Split(strLeft, found)

			// add string constant
			if arr[0] != "" {
				strChild := model.Field{Name: "child-" + strconv.Itoa(index), Type: "list", Range: arr[0]}
				field.Fields = append(field.Fields, strChild)
			}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
205 206 207 208 209 210 211 212 213
			child := model.Field{}
			if constant.LoadedFields[name].Name != "" {
				child = constant.LoadedFields[name]
			} else {
				child.Name = a[1]
				child.Type = "custom"
			}

			field.Fields = append(field.Fields, child)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
214 215 216 217 218 219 220 221 222

			arr = arr[1:]
			strLeft = strings.Join(arr, "")

			if index == len(arrOfName) - 1 && strLeft != "" {
				// add string constant
				strChild := model.Field{Name: "child-" + strconv.Itoa(index), Type: "list", Range: strLeft}
				field.Fields = append(field.Fields, strChild)
			}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
223 224
		}
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
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 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
}

func LoopSubFields(field *model.Field, oldValues []string, total int) []string {
	if field.Loop == 0 {field.Loop = 1}

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

	for _, val := range oldValues {
		fieldValue.Values = append(fieldValue.Values, val)
	}

	index := 0
	count := 0
	for {
		// 处理格式、前后缀、loop等
		str := GenerateFieldValWithFix(*field, fieldValue, &index, false)
		values = append(values, str)

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

	return values
}

func GenerateFieldValWithFix(field model.Field, fieldValue model.FieldValue, indexOfRow *int, withLoop bool) string {
	prefix := field.Prefix
	postfix := field.Postfix

	loopStr := ""
	for j := 0; j < field.Loop; j++ {
		if loopStr != "" {
			loopStr = loopStr + field.Loopfix
		}

		str := GenerateFieldVal(field, fieldValue, indexOfRow)
		loopStr = loopStr + str

		*indexOfRow++
	}

	if withLoop {
		loopStr = prefix + loopStr + postfix
	}

	return loopStr
274
}