package action import ( "encoding/json" "fmt" "github.com/easysoft/zendata/src/gen" constant "github.com/easysoft/zendata/src/utils/const" i118Utils "github.com/easysoft/zendata/src/utils/i118" logUtils "github.com/easysoft/zendata/src/utils/log" stringUtils "github.com/easysoft/zendata/src/utils/string" "github.com/easysoft/zendata/src/utils/vari" "github.com/mattn/go-runewidth" "regexp" "strings" "time" ) func Generate(defaultFile string, configFile string, total int, fieldsToExportStr string, out string, format string, table string) { startTime := time.Now().Unix() if defaultFile != "" && configFile == "" { configFile = defaultFile defaultFile = "" } fieldsToExport := make([]string, 0) if fieldsToExportStr != "" { fieldsToExport = strings.Split(fieldsToExportStr, ",") } vari.Total = total rows, colIsNumArr, err := gen.GenerateForDefinition(defaultFile, configFile, &fieldsToExport, total) if err != nil { return } Print(rows, format, table, colIsNumArr, fieldsToExport) entTime := time.Now().Unix() if vari.RunMode == constant.RunModeServerRequest { logUtils.PrintTo(i118Utils.I118Prt.Sprintf("server_response", len(rows), entTime - startTime)) } } func Print(rows [][]string, format string, table string, colIsNumArr []bool, fields []string) { if format == constant.FormatText { printTextHeader(fields) } else if format == constant.FormatSql { printSqlHeader(fields, table) } else if format == constant.FormatJson { printJsonHeader() } else if format == constant.FormatXml { printXmlHeader(fields, table) } for i, cols := range rows { row := make([]string, 0) rowMap := map[string]string{} valuesForSql := make([]string, 0) lineForText := "" for j, col := range cols { col = replacePlaceholder(col) field := vari.TopFiledMap[fields[j]] if field.Width > runewidth.StringWidth(col) { col = stringUtils.AddPad(col, field) } if j > 0 && vari.Human { lineForText = strings.TrimRight(lineForText, "\t") col = strings.TrimLeft(col, "\t") lineForText = lineForText + "\t" + col } else { lineForText = lineForText + col } row = append(row, col) rowMap[field.Field] = col colVal := stringUtils.ConvertForSql(col) if !colIsNumArr[j] { colVal = "'" + colVal + "'" } valuesForSql = append(valuesForSql, colVal) } if format == constant.FormatText { logUtils.PrintLine(lineForText) } else if format == constant.FormatSql { logUtils.PrintLine(genSqlLine(strings.Join(valuesForSql, ", "), i, len(rows))) } else if format == constant.FormatJson { logUtils.PrintLine(genJsonLine(i, row, len(rows), fields)) } else if format == constant.FormatXml { logUtils.PrintLine(getXmlLine(i, rowMap, len(rows))) } } } func printTextHeader(fields []string) { if !vari.WithHead { return } headerLine := "" for idx, field := range fields { headerLine += field if idx < len(fields)-1 { headerLine += "\t" } } logUtils.PrintLine(headerLine) } func printSqlHeader(fields []string, table string) { fieldNames := make([]string, 0) for _, f := range fields { fieldNames = append(fieldNames, "`" + f + "`") } logUtils.PrintLine(fmt.Sprintf("INSERT INTO %s(%s)", table, strings.Join(fieldNames, ", "))) } func printJsonHeader() { logUtils.PrintLine("[") } func printXmlHeader(fields []string, table string) { logUtils.PrintLine("\n\n Test Data") } func RowToJson(cols []string, fieldsToExport []string) string { rowMap := map[string]string{} for j, col := range cols { rowMap[fieldsToExport[j]] = col } jsonObj, _ := json.Marshal(rowMap) respJson := string(jsonObj) return respJson } func genSqlLine(valuesForSql string, i int, length int) string { temp := "" if i == 0 { temp = fmt.Sprintf(" VALUES (%s)", valuesForSql) } else { temp = fmt.Sprintf(" (%s)", valuesForSql) } if i < length - 1 { temp = temp + ", " } else { temp = temp + "; " } return temp } func genJsonLine(i int, row []string, length int, fields []string) string { temp := " " + RowToJson(row, fields) if i < length - 1 { temp = temp + ", " } else { temp = temp + "\n]" } return temp } func getXmlLine(i int, mp map[string]string, length int) string { str := "" j := 0 for key, val := range mp { str += fmt.Sprintf(" <%s>%s", key, val, key) if j != len(mp) - 1 { str = str + "\n" } j++ } text := fmt.Sprintf(" \n%s\n ", str) if i == length - 1 { text = text + "\n" } return text } func replacePlaceholder(col string) string { ret := col re := regexp.MustCompile("(?siU)\\${(.*)}") arr := re.FindAllStringSubmatch(col, -1) strForReplaceMap := map[string][]string{} for _, childArr := range arr { placeholderStr := childArr[1] strForReplaceMap[placeholderStr] = getValForPlaceholder(placeholderStr, len(childArr)) for _, str := range strForReplaceMap[placeholderStr] { temp := gen.Placeholder(placeholderStr) ret = strings.Replace(ret, temp, str, 1) } } return ret } func getValForPlaceholder(placeholderStr string, count int) []string { mp := vari.RandFieldNameToValuesMap[placeholderStr] tp := mp["type"].(string) repeatObj := mp["repeat"] repeat := "1" if repeatObj != nil { repeat = repeatObj.(string) } strs := make([]string, 0) if tp == "int" { start := mp["start"].(string) end := mp["end"].(string) precision := mp["precision"].(string) strs = gen.GetRandFromRange("int", start, end, "1", repeat, precision, count) } else if tp == "float" { start := mp["start"].(string) end := mp["end"].(string) precision := mp["precision"].(string) strs = gen.GetRandFromRange("float", start, end, "1", repeat, precision, count) } else if tp == "char" { start := mp["start"].(string) end := mp["end"].(string) precision := mp["precision"].(string) strs = gen.GetRandFromRange("char", start, end, "1", repeat, precision, count) } else if tp == "list" { list := mp["list"].([]string) strs = gen.GetRandFromList(list, repeat, count) } return strs }