gitee.com/zhongguo168a/gocodes@v0.0.0-20230609140523-e1828349603f/datax/modifyx2/modify-object.go (about) 1 package modifyx 2 3 import ( 4 "gitee.com/zhongguo168a/gocodes/datax/convertx" 5 "strconv" 6 ) 7 8 func (s *Object) RefClassName() string { 9 return s.source.className 10 } 11 12 // 新建一个对象 13 func NewObject(src *Source) (obj *Object) { 14 obj = newObject() 15 obj.source = src 16 // 17 obj.sourceData = src.origin 18 obj.path = src.className 19 obj.initData() 20 21 return 22 } 23 24 func newObject() (obj *Object) { 25 obj = &Object{} 26 obj.ints = map[string]int{} 27 obj.uints = map[string]uint{} 28 obj.floats = map[string]float64{} 29 obj.strings = map[string]string{} 30 obj.bools = map[string]bool{} 31 obj.temps = map[string]interface{}{} 32 obj.runtime = map[string]interface{}{} 33 obj.disablePoolField = map[string]bool{} 34 return 35 } 36 37 // 修正对象 38 // 如果需要在运行时,替换源的数据,可通过设置runtime实现 39 type Object struct { 40 source *Source 41 // 字段的路径 42 path string 43 // 在父对象中的字段名字 44 field string 45 // 父数据 46 parent map[string]interface{} 47 // 缓存的map/array/struct等对象, 避免重复创建对象 48 temps map[string]interface{} 49 // 50 creators map[string]func(obj IObject) IObject 51 creator func(obj IObject) IObject 52 // 当前修正对象指向的源数据 53 sourceData map[string]interface{} 54 sourceDataArray []interface{} 55 // 运行时设置的数据 56 runtime map[string]interface{} 57 // 最终的数据, 采用不同类型的原因是,初始值 58 ints map[string]int 59 uints map[string]uint 60 floats map[string]float64 61 strings map[string]string 62 bools map[string]bool 63 // 需要使用修正池修正的字段 64 // 用于性能优化,避免进入修正池流程。 65 disablePoolField map[string]bool 66 // 67 disabelPool bool 68 } 69 70 func (s *Object) RefClassCreator(field string, creator func(object IObject) IObject) { 71 if s.creators == nil { 72 s.creators = map[string]func(obj IObject) IObject{} 73 } 74 s.creators[field] = creator 75 } 76 77 func (s *Object) initData() { 78 for key, val := range s.sourceData { 79 switch v := val.(type) { 80 //case int: 81 // s.ints[key] = v 82 //case uint: 83 // s.uints[key] = v 84 //case float64: 85 // s.floats[key] = v 86 case bool: 87 s.bools[key] = v 88 case string: 89 s.strings[key] = v 90 } 91 } 92 } 93 94 func (s *Object) getOriginBool(field string) bool { 95 // 运行时 96 if rval, has := s.runtime[field]; has { 97 return rval.(bool) 98 } 99 return convertx.AnyToBool(s.sourceData[field]) 100 } 101 102 func (s *Object) getOriginFloat(field string) float64 { 103 // 运行时 104 if rval, has := s.runtime[field]; has { 105 return rval.(float64) 106 } 107 return convertx.AnyToFloat64(s.sourceData[field]) 108 } 109 func (s *Object) getOriginInt(field string) int { 110 // 运行时 111 if rval, has := s.runtime[field]; has { 112 return rval.(int) 113 } 114 return convertx.AnyToInt(s.sourceData[field]) 115 } 116 117 func (s *Object) Dispose() { 118 s.sourceData = nil 119 s.runtime = nil 120 s.ints = nil 121 s.floats = nil 122 s.strings = nil 123 s.bools = nil 124 s.parent = nil 125 s.temps = nil 126 s.source = nil 127 } 128 129 // 修正后的整型 130 func (s *Object) RefInt(field string) int { 131 origin := s.getOriginInt(field) 132 s.ints[field] = origin 133 // 池修正 134 if !s.disabelPool { 135 if !s.disablePoolField[field] { 136 pools := s.source.pools 137 if pools != nil { 138 lastkey := s.path + "/" + field 139 if pools.IsPropChanged(lastkey) { 140 // 更新属性 141 s.ints[field] = pools.GetNewPropInt(lastkey, origin) 142 } 143 } 144 } 145 } 146 147 return s.ints[field] 148 149 } 150 151 func (s *Object) resetBool(field string) { 152 // 运行时 153 if rval, has := s.runtime[field]; has { 154 s.bools[field] = rval.(bool) 155 } else { 156 // 使用源数据进行初始化B 157 s.bools[field] = convertx.AnyToBool(s.sourceData[field]) 158 } 159 return 160 } 161 162 // 修正后的整型 163 func (s *Object) RefBool(field string) bool { 164 origin := s.getOriginBool(field) 165 s.bools[field] = origin 166 // 池修正 167 if !s.disabelPool { 168 if !s.disablePoolField[field] { 169 pools := s.source.pools 170 if pools != nil { 171 lastkey := s.path + "/" + field 172 if pools.IsPropChanged(lastkey) { 173 // 更新属性 174 s.bools[field] = pools.GetNewPropBool(lastkey, origin) 175 } 176 } 177 } 178 } 179 180 return s.bools[field] 181 } 182 183 // 修正后的浮点型 184 func (s *Object) RefFloat64(field string) float64 { 185 origin := s.getOriginFloat(field) 186 s.floats[field] = origin 187 // 池修正 188 if !s.disabelPool { 189 if !s.disablePoolField[field] { 190 pools := s.source.pools 191 if pools != nil { 192 lastkey := s.path + "/" + field 193 if pools.IsPropChanged(lastkey) { 194 // 更新属性 195 s.floats[field] = pools.GetNewPropFloat(lastkey, origin) 196 } 197 } 198 } 199 } 200 201 return s.floats[field] 202 203 } 204 205 // RefSourceData 获取原始数据 206 // 可通过 mapx.Int(origin, fieldName)获取指定内容的值 207 func (s *Object) RefSourceData() (origin map[string]interface{}) { 208 return s.sourceData 209 } 210 211 // RefSource 获取原始数据指定的字段 212 func (s *Object) RefSource(field string) interface{} { 213 return s.sourceData[field] 214 } 215 216 func (s *Object) RefUint(field string) (val uint) { 217 return uint(s.RefInt(field)) 218 } 219 220 func (s *Object) resetString(field string) { 221 // 运行时 222 if rval, has := s.runtime[field]; has { 223 s.strings[field] = rval.(string) 224 } else { 225 // 使用源数据进行初始化B 226 s.strings[field] = convertx.AnyToString(s.sourceData[field]) 227 } 228 return 229 } 230 231 func (s *Object) RefString(field string) (val string) { 232 // 池修正 233 //if !s.disabelPool { 234 // if !s.disablePoolField[field] { 235 // root := s.source.root 236 // versions := s.source.versions 237 // if root != nil { 238 // lastkey := s.path + "/" + field 239 // pool := root.GetPool() 240 // if pool.IsPropChanged(lastkey, versions[lastkey]) { 241 // // 更新属性 242 // s.resetString(field) 243 // s.strings[field], versions[lastkey] = pool.GetNewPropString(root, lastkey, s.strings[field]) 244 // } 245 // } 246 // 247 // } 248 //} 249 250 return s.strings[field] 251 } 252 253 func (s *Object) RefArray(field string) (r IArray) { 254 iobj, hastemp := s.temps[field] 255 if hastemp == false { 256 obj := newArray() 257 obj.source = s.source 258 obj.parent = s.sourceData 259 obj.field = field 260 obj.path = s.path + "/" + field 261 obj.creator = s.creators[field] 262 // 263 m, has := s.sourceData[field] 264 if has == true && m != nil { 265 switch mval := m.(type) { 266 case []interface{}: 267 obj.sourceData = mval 268 case map[string]interface{}: 269 max := func() (x int) { 270 for key := range mval { 271 index, _ := strconv.Atoi(key) 272 if index > x { 273 x = index 274 } 275 } 276 return 277 }() 278 obj.sourceData = make([]interface{}, max, max) 279 for key, val := range mval { 280 index, _ := strconv.Atoi(key) 281 obj.sourceData[index] = val 282 } 283 } 284 285 obj.initData() 286 } 287 iobj = obj 288 s.temps[field] = iobj 289 } 290 291 r = iobj.(IArray) 292 return 293 } 294 295 func (s *Object) RefMap(field string) (r IObject) { 296 iobj, hastemp := s.temps[field] 297 if hastemp == false { 298 obj := newObject() 299 obj.source = s.source 300 obj.parent = s.sourceData 301 obj.field = field 302 obj.path = s.path + "/" + field 303 obj.temps = map[string]interface{}{} 304 // 305 m, has := s.sourceData[field] 306 if has == true && m != nil { 307 obj.sourceData = m.(map[string]interface{}) 308 obj.initData() 309 } 310 311 creator, hascreator := s.creators[field] 312 if hascreator { 313 obj.creator = creator 314 } 315 iobj = obj 316 s.temps[field] = iobj 317 } 318 319 r = iobj.(IObject) 320 return 321 } 322 323 func (s *Object) RefObject(field string) (r IObject) { 324 iobj, hastemp := s.temps[field] 325 if hastemp == false { 326 obj := newObject() 327 obj.source = s.source 328 obj.parent = s.sourceData 329 obj.field = field 330 obj.path = s.path + "/" + field 331 obj.temps = map[string]interface{}{} 332 // 333 m, has := s.sourceData[field] 334 if has == true && m != nil { 335 obj.sourceData = m.(map[string]interface{}) 336 obj.initData() 337 } 338 339 if s.creator != nil { // 只有map对象会有此属性 340 iobj = s.creator(obj) 341 } else { 342 // 343 creator, hascreator := s.creators[field] 344 if !hascreator { 345 iobj = obj 346 } else { 347 iobj = creator(obj) 348 } 349 350 } 351 352 s.temps[field] = iobj 353 } 354 355 r = iobj.(IObject) 356 return 357 } 358 359 // SetRuntimeFloat 运行时修改的数据, 用于直接替换掉origin数据, 再进行池修正 360 // 用于已知目标的情况下使用, 可提高运行效率, 例如初始化时, 为目标单位赋予初值 361 // 注: 需要注意设置的类型 362 func (s *Object) SetRuntimeFloat(field string, val float64) { 363 s.runtime[field] = val 364 s.floats[field] = val 365 } 366 func (s *Object) SetRuntimeInt(field string, val int) { 367 s.runtime[field] = val 368 s.ints[field] = val 369 } 370 func (s *Object) SetRuntimeBool(field string, val bool) { 371 s.runtime[field] = val 372 s.bools[field] = val 373 } 374 func (s *Object) SetRuntimeString(field string, val string) { 375 s.runtime[field] = val 376 s.strings[field] = val 377 } 378 379 func (s *Object) RefIsNil() bool { 380 return s.sourceData == nil 381 } 382 383 func (s *Object) RefLength() int { 384 return len(s.sourceData) 385 } 386 387 func (s *Object) RefKeys() (r []string) { 388 if s.RefIsNil() { 389 return 390 } 391 392 for key := range s.sourceData { 393 r = append(r, key) 394 } 395 return 396 } 397 398 // 只用于无修正场合 399 func (s *Object) MapKeyOf(conf func(item interface{}) bool) string { 400 if s.RefIsNil() { 401 return "" 402 } 403 404 for key := range s.sourceData { 405 if conf(s.sourceData[key]) { 406 return key 407 } 408 } 409 410 return "" 411 } 412 413 func (s *Object) GetMapFloat() (r map[string]float64) { 414 iobj, hastemp := s.temps["mapfloat"] 415 if hastemp == false { 416 r = map[string]float64{} 417 iobj = r 418 s.temps["mapfloat"] = r 419 } 420 r = iobj.(map[string]float64) 421 for key := range s.sourceData { 422 r[key] = s.RefFloat64(key) 423 } 424 return 425 } 426 427 func (s *Object) GetMapFloatModify() (r map[string]float64) { 428 iobj, hastemp := s.temps["mapfloatmod"] 429 if hastemp == false { 430 r = map[string]float64{} 431 iobj = r 432 s.temps["mapfloatmod"] = r 433 } 434 r = iobj.(map[string]float64) 435 for key := range s.sourceData { 436 r[key] = s.RefFloat64(key) 437 } 438 return 439 } 440 441 // 只用于无修正场合 442 func (s *Object) ToMapString() (r map[string]string) { 443 iobj, hastemp := s.temps["mapstring"] 444 if hastemp == false { 445 r = map[string]string{} 446 for key := range s.sourceData { 447 r[key] = s.sourceData[key].(string) 448 } 449 iobj = r 450 s.temps["mapstring"] = r 451 } 452 r = iobj.(map[string]string) 453 return 454 } 455 456 // 只用于无修正场合 457 func (s *Object) ToArrayString() (r []string) { 458 iobj, hastemp := s.temps["arraystring"] 459 if hastemp == false { 460 r = make([]string, s.RefLength()) 461 for key, val := range s.sourceData { 462 idx := convertx.AnyToInt64(key) 463 r[idx] = val.(string) 464 } 465 iobj = r 466 s.temps["arraystring"] = r 467 } 468 r = iobj.([]string) 469 return 470 } 471 472 // 只用于无修正场合 473 func (s *Object) GetArrayFloatModify() (r []float64) { 474 iobj, hastemp := s.temps["arrayfloat64mod"] 475 if hastemp == false { 476 r = make([]float64, s.RefLength()) 477 iobj = r 478 s.temps["arrayfloat64mod"] = r 479 } 480 for key := range s.sourceData { 481 idx := convertx.AnyToInt64(key) 482 r[idx] = s.RefFloat64(key) 483 } 484 r = iobj.([]float64) 485 return 486 }