github.com/easysoft/zendata@v0.0.0-20240513203326-705bd5a7fd67/internal/pkg/service/output-comm.go (about) 1 package service 2 3 import ( 4 "fmt" 5 6 consts "github.com/easysoft/zendata/internal/pkg/const" 7 "github.com/easysoft/zendata/internal/pkg/domain" 8 logUtils "github.com/easysoft/zendata/pkg/utils/log" 9 "github.com/easysoft/zendata/pkg/utils/vari" 10 ) 11 12 type OutputService struct { 13 CombineService *CombineService `inject:""` 14 PlaceholderService *PlaceholderService `inject:""` 15 16 PrintService *PrintService `inject:""` 17 ExpressionService *ExpressionService `inject:""` 18 } 19 20 func (s *OutputService) GenRecords() (records []map[string]interface{}) { 21 records = make([]map[string]interface{}, 0) 22 23 for i := range vari.GlobalVars.DefData.Fields { 24 s.genFieldVal(&vari.GlobalVars.DefData.Fields[i]) 25 } 26 27 for i := 0; i < vari.GlobalVars.Total; i++ { 28 record := map[string]interface{}{} 29 30 for _, field := range vari.GlobalVars.DefData.Fields { 31 s.GenRecordField(&field, &record, i) 32 } 33 34 records = append(records, record) 35 } 36 37 return 38 } 39 40 func (s *OutputService) genFieldVal(field *domain.DefField) { 41 field.Values = s.ExpressionService.GenExpressionValues(*field) 42 43 // for json only 44 vari.GlobalVars.FieldNameToValuesMap[field.Field] = field.Values 45 vari.GlobalVars.FieldNameToFieldMap[field.Field] = *field 46 47 for i := range field.Fields { 48 s.genFieldVal(&field.Fields[i]) 49 } 50 } 51 52 func (s *OutputService) GenRecordField(field *domain.DefField, mp *map[string]interface{}, i int) { 53 //log.Print(vari.GlobalVars.FieldNameToValuesMap) 54 55 if field.Join || len(field.Fields) == 0 { // set values 56 len := len(field.Values) 57 if len == 0 { 58 len = 1 59 } 60 val := field.Values[i%len] 61 62 switch val.(type) { 63 case string: 64 val = s.PlaceholderService.ReplacePlaceholder(fmt.Sprintf("%v", val)) 65 default: 66 } 67 68 (*mp)[field.Field] = val 69 70 } else { // set children 71 var childVal interface{} 72 73 isRecursive := field.Mode == consts.ModeRecursive || field.Mode == consts.ModeRecursiveShort 74 indexArr := make([]int, 0) 75 if isRecursive { 76 indexArr = s.getModArrForChildrenRecursive(field) 77 } 78 79 if field.Items == 0 { // output is object 80 mp := map[string]interface{}{} 81 for k, child := range field.Fields { 82 var index int 83 if isRecursive { 84 mod := indexArr[k] 85 index = i / mod % len(child.Values) 86 } else { 87 divisor := len(child.Values) 88 if divisor == 0 { 89 divisor = 1 90 } 91 index = i % divisor 92 } 93 94 s.GenRecordField(&child, &mp, index) 95 } 96 97 childVal = mp 98 99 } else { // output is array 100 var mpArr []map[string]interface{} 101 102 for itemIndex := 0; itemIndex < field.Items; itemIndex++ { 103 mp := map[string]interface{}{} 104 for k, child := range field.Fields { 105 index := i*field.Items + itemIndex 106 107 if isRecursive { 108 mod := indexArr[k] 109 index = index / mod % len(child.Values) 110 } else { 111 index = index % len(child.Values) 112 } 113 114 s.GenRecordField(&child, &mp, index) 115 } 116 117 mpArr = append(mpArr, mp) 118 } 119 120 childVal = mpArr 121 } 122 123 (*mp)[field.Field] = childVal 124 } 125 126 return 127 } 128 129 func (s *OutputService) PrintHumanHeaderIfNeeded() { 130 if !vari.GlobalVars.Human { 131 return 132 } 133 134 headerLine := "" 135 136 for idx, field := range vari.GlobalVars.ExportFields { 137 headerLine += field 138 if idx < len(vari.GlobalVars.ExportFields)-1 { 139 headerLine += "\t" 140 } 141 } 142 143 logUtils.PrintLine(headerLine + "\n") 144 } 145 146 func (s *OutputService) getModArrForChildrenRecursive(field *domain.DefField) []int { 147 indexArr := make([]int, 0) 148 for range field.Fields { 149 indexArr = append(indexArr, 0) 150 } 151 152 for i := 0; i < len(field.Fields); i++ { 153 loop := 1 154 for j := i + 1; j < len(field.Fields); j++ { 155 loop = loop * len(field.Fields[j].Values) 156 157 //if field.Items > 1 { 158 // loop /= field.Items 159 //} 160 } 161 162 indexArr[i] = loop 163 } 164 165 return indexArr 166 }