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  }