diff --git a/data/.cache/.data.db b/data/.cache/.data.db index 7f5dcf2dec7935f50e32a1e2415cb00ab8916092..0d8d21106bcda3bb442c298e4c95d5e392cb98f1 100644 Binary files a/data/.cache/.data.db and b/data/.cache/.data.db differ diff --git a/res/en/messages.json b/res/en/messages.json index 6e55db8fbdac513de274feb6d7c2db4a587c1187..38c17d45ef3eec20cb7279142bddc715e0b03a59 100644 --- a/res/en/messages.json +++ b/res/en/messages.json @@ -120,6 +120,14 @@ { "id": "analyse_success", "translation": "Success to decode data to %s." + }, + { + "id": "miss_table_name", + "translation": "Parameter 'table' is needed to generate sql format output." + }, + { + "id": "fail_to_generate_field", + "translation": "Fail to generate data for filed '%s'." } ] } \ No newline at end of file diff --git a/res/en/sample.yaml b/res/en/sample.yaml index 7730e3fb65d2efcae18982db5089adce8c42f18c..21026976c69c37105c42651ac8d0c09fd80538db 100644 --- a/res/en/sample.yaml +++ b/res/en/sample.yaml @@ -102,7 +102,7 @@ fields: postfix: "\t" - field: field_use_ranges # Other definition file can be referred, in which more than one ranges are defined. - from: custom.number.v1.yaml # Refer to the ranges in data/custom/number/v1.yaml. + from: custom.test.number.v1.yaml # Refer to the ranges in data/custom/number/v1.yaml. use: medium # use medium range. postfix: "\t" diff --git a/res/zh/messages.json b/res/zh/messages.json index c2f16f8660024fec6165ca5e6464199420e2d5df..320eb2dc1c504a18605d54e245f3bb9ba7412e08 100644 --- a/res/zh/messages.json +++ b/res/zh/messages.json @@ -86,7 +86,7 @@ }, { "id": "start_server", - "translation": "zendata http服务已经成功运行,按CTRL+C键推出。\n您可以通过http://%s:%s地址来调用,比如:\ncurl http://%s:%s/?config=demo/default.yaml&F=field_common&lines=10。" + "translation": "zendata http服务已经成功运行,按CTRL+C键退出。\n您可以通过http://%s:%s地址来调用,比如:\ncurl http://%s:%s/?config=demo/default.yaml&F=field_common&lines=10。" }, { "id": "server_request", @@ -111,6 +111,14 @@ { "id": "analyse_success", "translation": "成功解析数据到%s." + }, + { + "id": "miss_table_name", + "translation": "以sql格式输出时,需要指定table参数。" + }, + { + "id": "fail_to_generate_field", + "translation": "为Field %s生成数据失败。" } ] } \ No newline at end of file diff --git a/res/zh/sample.yaml b/res/zh/sample.yaml index 9a58aa3ed8a6616c11b0f77c07aab9b30fe09d11..b2e5bdbb1fc55b9fb6a9754dcde29d384ce7969c 100644 --- a/res/zh/sample.yaml +++ b/res/zh/sample.yaml @@ -96,7 +96,7 @@ fields: postfix: "\t" - field: field_use_ranges # 引用內置的定义文件,该文件定义了多个range,他们共享了一些field层面的属性。 - from: custom.number.v1.yaml # 引用data/custom/number/v1.yaml文件里面的ranges定义。 + from: custom.test.number.v1.yaml # 引用data/custom/number/v1.yaml文件里面的ranges定义。 use: medium # 使用该文件中定义的medium分组。 postfix: "\t" diff --git a/src/action/generator.go b/src/action/generator.go index 989ff6720a118422d7c4e80645b0246a9e748355..cdff6bc789691e3dbe52f2b738bf55951f1471ec 100644 --- a/src/action/generator.go +++ b/src/action/generator.go @@ -11,6 +11,7 @@ import ( 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/fatih/color" "net/http" "os" "regexp" @@ -38,13 +39,16 @@ func Generate(defaultFile string, configFile string, total int, fieldsToExportSt vari.Total = total - rows, colIsNumArr := gen.GenerateForDefinition(defaultFile, configFile, &fieldsToExport, 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)) - } + //if vari.RunMode == constant.RunModeServerRequest { + logUtils.PrintToWithColor(i118Utils.I118Prt.Sprintf("server_response", len(rows), entTime - startTime), color.FgCyan) + //} } func Print(rows [][]string, format string, table string, colIsNumArr []bool, fields []string) { @@ -130,8 +134,6 @@ func RowToJson(cols []string, fieldsToExport []string) string { return respJson } - - func genSqlLine(valuesForSql string, i int, length int) string { temp := "" @@ -226,6 +228,18 @@ func getValForPlaceholder(placeholderStr string, count int) []string { return strs } +func PrintErrMsg(msg string) { + //if vari.RunMode == constant.RunModeServerRequest { + // mp := map[string]string{} + // mp["msg"] = msg + // + // json, _ := json.Marshal(mp) + // PrintToHttp(string(json)) + //} else { + logUtils.PrintToWithColor(msg, color.FgCyan) + //} +} + func printLine(line string) { if FileWriter != nil { PrintToFile(line) diff --git a/src/action/sql.go b/src/action/sql.go index a7801f47de43089505865b0cffcb9f117c883992..c787e92f15ee84acca1058e48943e8ab37fd98b4 100644 --- a/src/action/sql.go +++ b/src/action/sql.go @@ -32,7 +32,7 @@ func ParseSql(file string, out string) { content := string(bytes) if out != "" { - out = fileUtils.UpdateDir(out) + out = fileUtils.AddSepIfNeeded(out) outFile := out + tableName + ".yaml" WriteToFile(outFile, content) } else { diff --git a/src/gen/definition.go b/src/gen/definition.go index 5e64ad2ebf085e37f3affa71a3a93db902fe9e28..37ac7639ce813b80a492c30a566b1c87f815edd3 100644 --- a/src/gen/definition.go +++ b/src/gen/definition.go @@ -6,6 +6,7 @@ import ( i118Utils "github.com/easysoft/zendata/src/utils/i118" logUtils "github.com/easysoft/zendata/src/utils/log" "github.com/easysoft/zendata/src/utils/vari" + "github.com/fatih/color" "gopkg.in/yaml.v3" "io/ioutil" "strings" @@ -16,30 +17,32 @@ func LoadConfigDef(defaultFile, configFile string, fieldsToExport *[]string) mod configDef := model.DefData{} // load defaultDef + path := vari.ExeDir + defaultFile if defaultFile != "" { - defaultContent, err := ioutil.ReadFile(defaultFile) + defaultContent, err := ioutil.ReadFile(path) defaultContent = ReplaceSpecialChars(defaultContent) if err != nil { - logUtils.PrintTo(i118Utils.I118Prt.Sprintf("fail_to_read_file", defaultFile)) + logUtils.PrintToWithColor(i118Utils.I118Prt.Sprintf("fail_to_read_file", path), color.FgCyan) return defaultDef } err = yaml.Unmarshal(defaultContent, &defaultDef) if err != nil { - logUtils.PrintTo(i118Utils.I118Prt.Sprintf("fail_to_read_file", defaultFile)) + logUtils.PrintToWithColor(i118Utils.I118Prt.Sprintf("fail_to_read_file", path), color.FgCyan) return defaultDef } } // load configDef - yamlContent, err := ioutil.ReadFile(configFile) + path = vari.ExeDir + configFile + yamlContent, err := ioutil.ReadFile(path) yamlContent = ReplaceSpecialChars(yamlContent) if err != nil { - logUtils.PrintTo(i118Utils.I118Prt.Sprintf("fail_to_read_file", configFile)) + logUtils.PrintToWithColor(i118Utils.I118Prt.Sprintf("fail_to_read_file", path), color.FgCyan) return configDef } err = yaml.Unmarshal(yamlContent, &configDef) if err != nil { - logUtils.PrintTo(i118Utils.I118Prt.Sprintf("fail_to_parse_file", configFile)) + logUtils.PrintToWithColor(i118Utils.I118Prt.Sprintf("fail_to_parse_file", path), color.FgCyan) return configDef } diff --git a/src/gen/excel.go b/src/gen/excel.go index 06e9106747ca0fd8c3dee13a2422040b7788e736..00018402fe7dd8483bb73fa31016a12e51eaa990 100644 --- a/src/gen/excel.go +++ b/src/gen/excel.go @@ -68,6 +68,10 @@ func ConvertExcelToSQLiteIfNeeded(dbName string, path string) { for _, sheet := range excel.GetSheetList() { rows, err := excel.GetRows(sheet) + if len(rows) == 0 { + continue + } + dropTemplate := `DROP TABLE IF EXISTS %s;` ddlTemplate := `CREATE TABLE %s ( %s diff --git a/src/gen/generator.go b/src/gen/generator.go index 129491aa6716542357c93109fecdcca6cb06a99c..c6182049dd7dd9338d1ba5ed775976e0966ee8f1 100644 --- a/src/gen/generator.go +++ b/src/gen/generator.go @@ -1,25 +1,34 @@ package gen import ( + "errors" "fmt" "github.com/easysoft/zendata/src/model" fileUtils "github.com/easysoft/zendata/src/utils/file" + 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/fatih/color" "github.com/mattn/go-runewidth" "strconv" "strings" ) -func GenerateForDefinition(defaultFile, configFile string, fieldsToExport *[]string, total int) ([][]string, []bool) { +func GenerateForDefinition(defaultFile, configFile string, fieldsToExport *[]string, + total int) (rows [][]string, colIsNumArr []bool, err error) { + vari.DefaultDir = fileUtils.GetAbsDir(defaultFile) vari.ConfigDir = fileUtils.GetAbsDir(configFile) vari.Def = LoadConfigDef(defaultFile, configFile, fieldsToExport) + if len(vari.Def.Fields) == 0 { + err = errors.New("") + return + } vari.Res = LoadResDef(*fieldsToExport) topFieldNameToValuesMap := map[string][]string{} - colIsNumArr := make([]bool, 0) // 为每个field生成值列表 for index, field := range vari.Def.Fields { @@ -45,8 +54,8 @@ func GenerateForDefinition(defaultFile, configFile string, fieldsToExport *[]str arrOfArr = append(arrOfArr, childValues) } - rows := putChildrenToArr(arrOfArr, total) - return rows, colIsNumArr + rows = putChildrenToArr(arrOfArr, total) + return } func GenerateForField(field *model.DefField, total int, withFix bool) (values []string) { @@ -195,7 +204,10 @@ func GenerateFieldValWithFix(field *model.DefField, fieldValue model.FieldWithVa loopStr = loopStr + field.Loopfix } - str := GenerateFieldVal(*field, fieldValue, indexOfRow) + str, err := GenerateFieldVal(*field, fieldValue, indexOfRow) + if err != nil { + str = "N/A" + } loopStr = loopStr + str *indexOfRow++ @@ -217,8 +229,14 @@ func GenerateFieldValWithFix(field *model.DefField, fieldValue model.FieldWithVa return } -func GenerateFieldVal(field model.DefField, fieldValue model.FieldWithValues, index *int) (val string) { +func GenerateFieldVal(field model.DefField, fieldValue model.FieldWithValues, index *int) (val string, err error) { // 叶节点 + if len(fieldValue.Values) == 0 { + logUtils.PrintToWithColor(i118Utils.I118Prt.Sprintf("fail_to_generate_field", field.Field), color.FgCyan) + err = errors.New("") + return + } + idx := *index % len(fieldValue.Values) str := fieldValue.Values[idx] val = GetFieldValStr(field, str) diff --git a/src/gen/res.go b/src/gen/res.go index 46311c6e0f11cf931816720eabe122c3518769db..3e44f8c654f417a7f4623cb9fdec6b9653e6bd28 100644 --- a/src/gen/res.go +++ b/src/gen/res.go @@ -11,7 +11,6 @@ import ( "github.com/jinzhu/copier" "gopkg.in/yaml.v3" "io/ioutil" - "os" "path/filepath" "strings" ) @@ -46,12 +45,10 @@ func getResProp(from string) (string, string) { // from resource resFile := "" resType := "" - sep := string(os.PathSeparator) - index := strings.LastIndex(from, ".yaml") if index > -1 { // yaml, system.ip.v1.yaml left := from[:index] - left = strings.ReplaceAll(left, ".", sep) + left = strings.ReplaceAll(left, ".", constant.PthSep) resFile = left + ".yaml" resType = "yaml" @@ -59,7 +56,7 @@ func getResProp(from string) (string, string) { // from resource index = strings.LastIndex(from, ".") left := from[:index] - left = strings.ReplaceAll(left, ".", sep) + left = strings.ReplaceAll(left, ".", constant.PthSep) resFile = left + ".xlsx" resType = "excel" @@ -72,10 +69,10 @@ func getResProp(from string) (string, string) { // from resource if !filepath.IsAbs(resPath) { resPath = vari.ConfigDir + resFile - if !fileUtils.FileExist(resPath) { // res in the same folder with passed config file + if !fileUtils.FileExist(resPath) { // in same folder with passed config file resPath = vari.ExeDir + constant.ResDir + resFile - if !fileUtils.FileExist(resPath) { // res in res file + if !fileUtils.FileExist(resPath) { // in res file resPath = "" } } diff --git a/src/service/list.go b/src/service/list.go index a64e4aa969537fd73897c0fdd0e6e4e27f5d0304..90f32d6aad60070b569244d96638103a7919308a 100644 --- a/src/service/list.go +++ b/src/service/list.go @@ -11,7 +11,6 @@ import ( "github.com/mattn/go-runewidth" "gopkg.in/yaml.v3" "io/ioutil" - "os" "strings" ) @@ -20,74 +19,83 @@ const ( ) func ListRes() { - res := map[string][size]string{} - path := vari.ExeDir + "data" + string(os.PathSeparator) + "system" + res := map[string][][size]string{} + path := vari.ExeDir + "data" GetFilesAndDirs(path, &res) - msg := "" names := make([]string, 0) nameWidth := 0 titleWidth := 0 - for key, arr := range res { - path := arr[0] - if key == "yaml" { - arr[2], arr[3] = readYamlInfo(path) - } else if key == "excel" { - arr[2], arr[3] = readExcelInfo(path) - } + for key, arrOfArr := range res { + for index, arr := range arrOfArr { + path := arr[0] + if key == "yaml" { + arr[2], arr[3] = readYamlInfo(path) + } else if key == "excel" { + arr[2], arr[3] = readExcelInfo(path) + } - res[key] = arr - name := pathToName(arr[1]) - names = append(names, name) - lent := runewidth.StringWidth(name) - if lent > nameWidth { - nameWidth = lent - } + res[key][index] = arr + name := pathToName(arr[1]) + names = append(names, name) + lent := runewidth.StringWidth(name) + if lent > nameWidth { + nameWidth = lent + } - if key == "excel" { - sheets := strings.Split(arr[2], "|") - for _, sheet := range sheets { - lent2 := runewidth.StringWidth(sheet) + if key == "excel" { + sheets := strings.Split(arr[2], "|") + for _, sheet := range sheets { + lent2 := runewidth.StringWidth(sheet) + if lent2 > titleWidth { + titleWidth = lent2 + } + } + } else { + lent2 := runewidth.StringWidth(arr[2]) if lent2 > titleWidth { titleWidth = lent2 } } - } else { - lent2 := runewidth.StringWidth(arr[2]) - if lent2 > titleWidth { - titleWidth = lent2 - } } - } + sysMsg := "" + customMsg := "" idx := 0 - for _, arr := range res { - name := names[idx] + for _, arrOfArr := range res { + for _, arr := range arrOfArr { + name := names[idx] - titleStr := arr[2] - titles := strings.Split(titleStr, "|") + titleStr := arr[2] + titles := strings.Split(titleStr, "|") - idx2 := 0 - for _, title := range titles { - if idx2 > 0 { - name = "" - } - name = name + strings.Repeat(" ", nameWidth - runewidth.StringWidth(name)) + idx2 := 0 + for _, title := range titles { + if idx2 > 0 { + name = "" + } + name = name + strings.Repeat(" ", nameWidth - runewidth.StringWidth(name)) + + title = title + strings.Repeat(" ", titleWidth - runewidth.StringWidth(title)) + msg := fmt.Sprintf("%s %s %s\n", name, title, arr[3]) + if strings.Index(name, "system") > -1 { + sysMsg = sysMsg + msg + } else { + customMsg = sysMsg + msg + } - title = title + strings.Repeat(" ", titleWidth - runewidth.StringWidth(title)) - msg = msg + fmt.Sprintf("%s %s %s\n", name, title, arr[3]) + idx2++ + } - idx2++ + idx++ } - - idx++ } - logUtils.PrintTo(msg) + logUtils.PrintTo(sysMsg + "\n" + customMsg) } -func GetFilesAndDirs(path string, res *map[string][size]string) { +func GetFilesAndDirs(path string, res *map[string][][size]string) { dir, err := ioutil.ReadDir(path) if err != nil { return @@ -101,12 +109,16 @@ func GetFilesAndDirs(path string, res *map[string][size]string) { arr := [size]string{} if strings.HasSuffix(name, ".yaml") { arr[0] = path + constant.PthSep + name - arr[1] = path[strings.LastIndex(path, "system"):] + constant.PthSep + name - (*res)["yaml"] = arr + arr[1] = path[strings.LastIndex(path, "data"):] + constant.PthSep + name + arr[1] = strings.Trim(arr[1], "data"+constant.PthSep) + + (*res)["yaml"] = append((*res)["yaml"], arr) } else if strings.HasSuffix(name, ".xlsx") { arr[0] = path + constant.PthSep + name - arr[1] = path[strings.LastIndex(path, "system"):] + constant.PthSep + name - (*res)["excel"] = arr + arr[1] = path[strings.LastIndex(path, "data"):] + constant.PthSep + name + arr[1] = strings.Trim(arr[1], "data"+constant.PthSep) + + (*res)["excel"] = append((*res)["excel"], arr) } } } diff --git a/src/service/request.go b/src/service/request.go index f23b9b8975c707099534b9a67a87737245616bd6..fd0d5c714da088e6a6891519be9d799b2746ab37 100644 --- a/src/service/request.go +++ b/src/service/request.go @@ -9,14 +9,16 @@ import ( "strconv" ) -func ParseRequestParams(req *http.Request) (root, defaultFile, yamlFile, fields string, count int, +func ParseRequestParams(req *http.Request) (defaultFile, yamlFile, fields string, count int, human string, format, table string, decode bool, input, output string) { query := req.URL.Query() - root = GetRequestParams(query,"root", "R") defaultFile = GetRequestParams(query,"default", "d") yamlFile = GetRequestParams(query,"config", "c") countStr := GetRequestParams(query,"lines", "n") + if countStr == "" { + countStr = "10" + } count, _ = strconv.Atoi(countStr) fields = GetRequestParams(query,"field", "F") diff --git a/src/utils/file/file.go b/src/utils/file/file.go index 4348603a441f0daeab7b318bb515a3684b5d2e51..8ebe64df518f1389577ca6102ce86dd1e7f89b99 100644 --- a/src/utils/file/file.go +++ b/src/utils/file/file.go @@ -1,18 +1,15 @@ package fileUtils import ( - "fmt" "github.com/easysoft/zendata/res" commonUtils "github.com/easysoft/zendata/src/utils/common" constant "github.com/easysoft/zendata/src/utils/const" "github.com/easysoft/zendata/src/utils/vari" - "io" "io/ioutil" "os" "os/exec" "path" "path/filepath" - "strconv" "strings" ) @@ -81,7 +78,7 @@ func AbosutePath(pth string) string { pth, _ = filepath.Abs(pth) } - pth = UpdateDir(pth) + pth = AddSepIfNeeded(pth) return pth } @@ -91,7 +88,7 @@ func IsAbosutePath(pth string) bool { strings.Index(pth, ":") == 1 // windows } -func UpdateDir(pth string) string { +func AddSepIfNeeded(pth string) string { sepa := string(os.PathSeparator) if strings.LastIndex(pth, sepa) < len(pth)-1 { @@ -100,28 +97,6 @@ func UpdateDir(pth string) string { return pth } -func GetFilesFromParams(arguments []string) []string { - ret := make([]string, 0) - - for _, arg := range arguments { - if strings.Index(arg, "-") != 0 { - if arg == "." { - arg = AbosutePath(".") - } else if strings.Index(arg, "."+string(os.PathSeparator)) == 0 { - arg = AbosutePath(".") + arg[2:] - } else if !IsAbosutePath(arg) { - arg = AbosutePath(".") + arg - } - - ret = append(ret, arg) - } else { - break - } - } - - return ret -} - func ReadResData(path string) string { isRelease := commonUtils.IsRelease() @@ -151,53 +126,20 @@ func GetExeDir() string { // where zd.exe file in } dir, _ = filepath.Abs(dir) - dir = UpdateDir(dir) + dir = AddSepIfNeeded(dir) //fmt.Printf("Debug: Launch %s in %s \n", arg1, dir) return dir } -func GetWorkDir() string { // where run command in - dir, _ := os.Getwd() - dir, _ = filepath.Abs(dir) - dir = UpdateDir(dir) - - return dir -} - -func getLogNumb(numb int) string { - return fmt.Sprintf("%03s", strconv.Itoa(numb)) -} - -func CopyFile(src, dst string) (int64, error) { - sourceFileStat, err := os.Stat(src) - if err != nil { - return 0, err - } - - if !sourceFileStat.Mode().IsRegular() { - return 0, fmt.Errorf("%s is not a regular file", src) - } - - source, err := os.Open(src) - if err != nil { - return 0, err - } - defer source.Close() - - destination, err := os.Create(dst) - if err != nil { - return 0, err - } - defer destination.Close() - nBytes, err := io.Copy(destination, source) - return nBytes, err -} - func GetAbsDir(path string) string { - abs, _ := filepath.Abs(filepath.Dir(path)) - abs = UpdateDir(abs) + abs := "" + if !IsAbosutePath(path) { + path = vari.ExeDir + path + } + abs, _ = filepath.Abs(filepath.Dir(path)) + abs = AddSepIfNeeded(abs) return abs } diff --git a/src/zd.go b/src/zd.go index a11b043c5150a15e55549c10ff6743657280def2..d4bcc322d15dedd5bb9b94088a556e9f852ea72a 100644 --- a/src/zd.go +++ b/src/zd.go @@ -78,8 +78,8 @@ func main() { flagSet.StringVar(&output, "o", "", "") flagSet.StringVar(&output, "output", "", "") - flagSet.StringVar(&table, "t", "table_name", "") - flagSet.StringVar(&table, "table", "table_name", "") + flagSet.StringVar(&table, "t", "", "") + flagSet.StringVar(&table, "table", "", "") flagSet.BoolVar(&listRes, "l", false, "") flagSet.BoolVar(&listRes, "list", false, "") @@ -159,6 +159,16 @@ func main() { func toGen() { if vari.RunMode == constant.RunModeServer { + if root != "" { + if fileUtils.IsAbosutePath(root) { + vari.ExeDir = root + } else { + vari.ExeDir = vari.ExeDir + root + } + vari.ExeDir = fileUtils.AddSepIfNeeded(vari.ExeDir) + } + constant.SqliteSource = strings.Replace(constant.SqliteSource, "file:", "file:" + vari.ExeDir, 1) + StartServer() } else if vari.RunMode == constant.RunModeServerRequest { format = constant.FormatJson @@ -166,9 +176,6 @@ func toGen() { } else if vari.RunMode == constant.RunModeParse { action.ParseSql(input, output) } else if vari.RunMode == constant.RunModeGen { - if root != "" { - vari.ExeDir = root - } if vari.HeadSep != "" { vari.WithHead = true } @@ -187,6 +194,11 @@ func toGen() { } } + if format == constant.FormatSql && table == "" { + action.PrintErrMsg(i118Utils.I118Prt.Sprintf("miss_table_name")) + return + } + action.Generate(defaultFile, configFile, count, fields, output, format, table) } } @@ -210,7 +222,7 @@ func StartServer() { func DataHandler(writer http.ResponseWriter, req *http.Request) { action.HttpWriter = writer - root, defaultFile, configFile, fields, count, vari.HeadSep, + defaultFile, configFile, fields, count, vari.HeadSep, format, table, decode, input, output = service.ParseRequestParams(req) if decode {