gitee.com/zhongguo168a/gocodes@v0.0.0-20230609140523-e1828349603f/datax/modifyx2/modify-array.go (about) 1 package modifyx 2 3 import ( 4 "gitee.com/zhongguo168a/gocodes/datax/convertx" 5 "strconv" 6 ) 7 8 func newArray() (obj *Array) { 9 obj = &Array{} 10 obj.disablePoolField = []bool{} 11 return 12 } 13 14 // 修正对象 15 // 如果需要在运行时,替换源的数据,可通过设置runtime实现 16 type Array struct { 17 source *Source 18 // 字段的路径 19 path string 20 // 在父对象中的字段名字 21 field string 22 // 父数据 23 parent map[string]interface{} 24 // 缓存的map/array/struct等对象, 避免重复创建对象 25 temps []interface{} 26 // 27 creator func(obj IObject) IObject 28 // 当前修正对象指向的源数据 29 sourceData []interface{} 30 // 运行时设置的数据 31 runtime []interface{} 32 // 最终的数据, 采用不同类型的原因是,初始值 33 ints []int 34 uints []uint 35 floats []float64 36 strings []string 37 bools []bool 38 // 需要使用修正池修正的字段 39 // 用于性能优化,避免进入修正池流程。 40 disablePoolField []bool 41 // 42 disabelPool bool 43 } 44 45 func (s *Array) initData() { 46 s.ints = make([]int, len(s.sourceData), len(s.sourceData)) 47 s.uints = make([]uint, len(s.sourceData), len(s.sourceData)) 48 s.floats = make([]float64, len(s.sourceData), len(s.sourceData)) 49 s.strings = make([]string, len(s.sourceData), len(s.sourceData)) 50 s.bools = make([]bool, len(s.sourceData), len(s.sourceData)) 51 s.temps = make([]interface{}, len(s.sourceData), len(s.sourceData)) 52 s.disablePoolField = make([]bool, len(s.sourceData), len(s.sourceData)) 53 54 for key, val := range s.sourceData { 55 switch v := val.(type) { 56 case int: 57 s.ints[key] = v 58 case uint: 59 s.uints[key] = v 60 case float64: 61 s.floats[key] = v 62 case bool: 63 s.bools[key] = v 64 case string: 65 s.strings[key] = v 66 } 67 } 68 } 69 70 func (s *Array) Dispose() { 71 s.sourceData = nil 72 s.ints = nil 73 s.floats = nil 74 s.strings = nil 75 s.bools = nil 76 s.parent = nil 77 s.temps = nil 78 s.source = nil 79 } 80 81 func (s *Array) getOriginBool(field int) bool { 82 // 运行时 83 if s.runtime != nil { 84 if rval := s.runtime[field]; rval != nil { 85 return rval.(bool) 86 } 87 } 88 89 return convertx.AnyToBool(s.sourceData[field]) 90 } 91 92 func (s *Array) getOriginFloat(field int) float64 { 93 // 运行时 94 if s.runtime != nil { 95 if rval := s.runtime[field]; rval != nil { 96 return rval.(float64) 97 } 98 } 99 100 return convertx.AnyToFloat64(s.sourceData[field]) 101 } 102 func (s *Array) getOriginInt(field int) int { 103 // 运行时 104 if s.runtime != nil { 105 if rval := s.runtime[field]; rval != nil { 106 return rval.(int) 107 } 108 } 109 return convertx.AnyToInt(s.sourceData[field]) 110 } 111 112 // 修正后的整型 113 func (s *Array) RefInt(field int) int { 114 origin := s.getOriginInt(field) 115 s.ints[field] = origin 116 // 池修正 117 if !s.disabelPool { 118 if !s.disablePoolField[field] { 119 pools := s.source.pools 120 if pools != nil { 121 lastkey := s.path + "/" + strconv.Itoa(field) 122 if pools.IsPropChanged(lastkey) { 123 // 更新属性 124 s.ints[field] = pools.GetNewPropInt(lastkey, origin) 125 } 126 } 127 } 128 } 129 130 return s.ints[field] 131 } 132 133 // 修正后的整型 134 func (s *Array) RefBool(field int) bool { 135 origin := s.getOriginBool(field) 136 s.bools[field] = origin 137 // 池修正 138 if !s.disabelPool { 139 if !s.disablePoolField[field] { 140 pools := s.source.pools 141 if pools != nil { 142 lastkey := s.path + "/" + strconv.Itoa(field) 143 if pools.IsPropChanged(lastkey) { 144 // 更新属性 145 s.bools[field] = pools.GetNewPropBool(lastkey, origin) 146 } 147 } 148 } 149 } 150 151 return s.bools[field] 152 153 } 154 155 // 修正后的浮点型 156 func (s *Array) RefFloat(field int) float64 { 157 origin := s.getOriginFloat(field) 158 s.floats[field] = origin 159 // 池修正 160 if !s.disabelPool { 161 if !s.disablePoolField[field] { 162 pools := s.source.pools 163 if pools != nil { 164 lastkey := s.path + "/" + strconv.Itoa(field) 165 if pools.IsPropChanged(lastkey) { 166 // 更新属性 167 s.floats[field] = pools.GetNewPropFloat(lastkey, origin) 168 } 169 } 170 } 171 } 172 173 return s.floats[field] 174 } 175 176 // 获取原始数据 177 func (s *Array) RefSourceData() []interface{} { 178 return s.sourceData 179 } 180 181 func (s *Array) RefUint(index int) (val uint) { 182 return uint(s.RefInt(index)) 183 } 184 185 func (s *Array) RefString(index int) (val string) { 186 return s.strings[index] 187 } 188 189 func (s *Array) RefObject(index int) (r IObject) { 190 iobj := s.temps[index] 191 if iobj == nil { 192 obj := newObject() 193 obj.source = s.source 194 obj.field = strconv.Itoa(index) 195 obj.path = s.path + "/" + obj.field 196 obj.temps = map[string]interface{}{} 197 // 198 m := s.sourceData[index] 199 if m != nil { 200 obj.sourceData = m.(map[string]interface{}) 201 obj.initData() 202 } 203 204 creator := s.creator 205 if creator != nil { 206 iobj = creator(obj) 207 } else { 208 iobj = obj 209 } 210 211 s.temps[index] = iobj 212 } 213 214 r = iobj.(IObject) 215 return 216 } 217 218 func (s *Array) RefLength() int { 219 return len(s.sourceData) 220 }