gitlab.com/evatix-go/core@v1.3.55/coredata/coredynamic/DynamicCollection.go (about) 1 package coredynamic 2 3 import ( 4 "encoding/json" 5 "math" 6 "reflect" 7 "strings" 8 "sync" 9 10 "gitlab.com/evatix-go/core/constants" 11 "gitlab.com/evatix-go/core/coredata/corejson" 12 "gitlab.com/evatix-go/core/defaultcapacity" 13 "gitlab.com/evatix-go/core/errcore" 14 "gitlab.com/evatix-go/core/pagingutil" 15 ) 16 17 type DynamicCollection struct { 18 items []Dynamic 19 } 20 21 func EmptyDynamicCollection() *DynamicCollection { 22 return NewDynamicCollection(constants.Zero) 23 } 24 25 func NewDynamicCollection(capacity int) *DynamicCollection { 26 slice := make([]Dynamic, 0, capacity) 27 28 return &DynamicCollection{items: slice} 29 } 30 31 func (it *DynamicCollection) At(index int) Dynamic { 32 return it.items[index] 33 } 34 35 func (it *DynamicCollection) Items() []Dynamic { 36 if it == nil || it.items == nil { 37 return []Dynamic{} 38 } 39 40 return it.items 41 } 42 43 func (it *DynamicCollection) FirstDynamic() interface{} { 44 return it.items[0] 45 } 46 47 func (it *DynamicCollection) First() Dynamic { 48 return it.items[0] 49 } 50 51 func (it *DynamicCollection) LastDynamic() interface{} { 52 return it.items[it.LastIndex()] 53 } 54 55 func (it *DynamicCollection) Last() Dynamic { 56 return it.items[it.LastIndex()] 57 } 58 59 func (it *DynamicCollection) FirstOrDefaultDynamic() interface{} { 60 return it.FirstOrDefault() 61 } 62 63 func (it *DynamicCollection) FirstOrDefault() *Dynamic { 64 if it.IsEmpty() { 65 return nil 66 } 67 68 first := it.First() 69 70 return &first 71 } 72 73 func (it *DynamicCollection) LastOrDefaultDynamic() interface{} { 74 return it.LastOrDefault() 75 } 76 77 func (it *DynamicCollection) LastOrDefault() *Dynamic { 78 if it.IsEmpty() { 79 return nil 80 } 81 82 last := it.Last() 83 84 return &last 85 } 86 87 func (it *DynamicCollection) SkipDynamic(skippingItemsCount int) interface{} { 88 return it.items[skippingItemsCount:] 89 } 90 91 func (it *DynamicCollection) Skip(skippingItemsCount int) []Dynamic { 92 return it.items[skippingItemsCount:] 93 } 94 95 func (it *DynamicCollection) SkipCollection(skippingItemsCount int) *DynamicCollection { 96 return &DynamicCollection{ 97 items: it.items[skippingItemsCount:], 98 } 99 } 100 101 func (it *DynamicCollection) TakeDynamic(takeDynamicItems int) interface{} { 102 return it.items[:takeDynamicItems] 103 } 104 105 func (it *DynamicCollection) Take(takeDynamicItems int) []Dynamic { 106 return it.items[:takeDynamicItems] 107 } 108 109 func (it *DynamicCollection) TakeCollection(takeDynamicItems int) *DynamicCollection { 110 return &DynamicCollection{ 111 items: it.items[:takeDynamicItems], 112 } 113 } 114 115 func (it *DynamicCollection) LimitCollection(limit int) *DynamicCollection { 116 return &DynamicCollection{ 117 items: it.items[:limit], 118 } 119 } 120 121 func (it *DynamicCollection) SafeLimitCollection(limit int) *DynamicCollection { 122 limit = defaultcapacity. 123 MaxLimit(it.Length(), limit) 124 125 return &DynamicCollection{ 126 items: it.items[:limit], 127 } 128 } 129 130 func (it *DynamicCollection) LimitDynamic(limit int) interface{} { 131 return it.Take(limit) 132 } 133 134 func (it *DynamicCollection) Limit(limit int) []Dynamic { 135 return it.Take(limit) 136 } 137 138 func (it *DynamicCollection) Length() int { 139 if it == nil { 140 return 0 141 } 142 143 return len(it.items) 144 } 145 146 func (it *DynamicCollection) Count() int { 147 return it.Length() 148 } 149 150 func (it *DynamicCollection) IsEmpty() bool { 151 if it == nil { 152 return true 153 } 154 155 return len(it.items) == 0 156 } 157 158 func (it *DynamicCollection) HasAnyItem() bool { 159 return !it.IsEmpty() 160 } 161 162 func (it *DynamicCollection) LastIndex() int { 163 return it.Length() - 1 164 } 165 166 func (it *DynamicCollection) Loop( 167 loopProcessorFunc func(index int, dynamicItem *Dynamic) (isBreak bool), 168 ) { 169 if it.IsEmpty() { 170 return 171 } 172 173 for i := range it.items { 174 isBreak := loopProcessorFunc(i, &it.items[i]) 175 176 if isBreak { 177 return 178 } 179 } 180 } 181 182 func (it *DynamicCollection) HasIndex(index int) bool { 183 return it.LastIndex() >= index 184 } 185 186 func (it *DynamicCollection) ListStringsPtr() *[]string { 187 slice := make([]string, constants.Zero, it.Length()+1) 188 189 for _, dynamic := range it.items { 190 str, _ := dynamic.JsonString() 191 192 slice = append(slice, str) 193 } 194 195 return &slice 196 } 197 198 func (it *DynamicCollection) ListStrings() []string { 199 return *it.ListStringsPtr() 200 } 201 202 func (it *DynamicCollection) RemoveAt(index int) (isSuccess bool) { 203 if !it.HasIndex(index) { 204 return false 205 } 206 207 items := it.items 208 it.items = append( 209 items[:index], 210 items[index+constants.One:]...) 211 212 return true 213 } 214 215 func (it *DynamicCollection) AddAnyItemsWithTypeValidation( 216 isContinueOnError, 217 isNullNotAllowed bool, 218 expectedType reflect.Type, 219 anyItems ...interface{}, 220 ) error { 221 if len(anyItems) == 0 { 222 return nil 223 } 224 225 if isContinueOnError { 226 var sliceErr []string 227 228 for _, anyItem := range anyItems { 229 err := it.AddAnyWithTypeValidation( 230 isNullNotAllowed, 231 expectedType, 232 anyItem) 233 234 if err != nil { 235 sliceErr = append(sliceErr, err.Error()) 236 } 237 } 238 239 return errcore.SliceToError(sliceErr) 240 } 241 242 for _, anyItem := range anyItems { 243 err := it.AddAnyWithTypeValidation( 244 isNullNotAllowed, 245 expectedType, 246 anyItem) 247 248 if err != nil { 249 return err 250 } 251 } 252 253 return nil 254 } 255 256 func (it *DynamicCollection) AddAnyWithTypeValidation( 257 isNullNotAllowed bool, 258 expectedType reflect.Type, 259 anyItem interface{}, 260 ) error { 261 err := ReflectTypeValidation( 262 isNullNotAllowed, 263 expectedType, 264 anyItem) 265 266 if err != nil { 267 return err 268 } 269 270 it.items = append( 271 it.items, 272 NewDynamic(anyItem, true)) 273 274 return nil 275 } 276 277 func (it *DynamicCollection) AddAny( 278 anyItem interface{}, isValid bool, 279 ) *DynamicCollection { 280 it.items = append( 281 it.items, 282 NewDynamic(anyItem, isValid)) 283 284 return it 285 } 286 287 func (it *DynamicCollection) AddAnyNonNull( 288 anyItem interface{}, isValid bool, 289 ) *DynamicCollection { 290 if anyItem == nil { 291 return it 292 } 293 294 it.items = append( 295 it.items, 296 NewDynamic(anyItem, isValid)) 297 298 return it 299 } 300 301 func (it *DynamicCollection) AddAnyMany( 302 anyItems ...interface{}, 303 ) *DynamicCollection { 304 if anyItems == nil { 305 return it 306 } 307 308 for _, item := range anyItems { 309 it.items = append( 310 it.items, 311 NewDynamic(item, true)) 312 } 313 314 return it 315 } 316 317 func (it *DynamicCollection) Add( 318 dynamic Dynamic, 319 ) *DynamicCollection { 320 it.items = append(it.items, dynamic) 321 322 return it 323 } 324 325 func (it *DynamicCollection) AddPtr( 326 dynamic *Dynamic, 327 ) *DynamicCollection { 328 if dynamic == nil { 329 return it 330 } 331 332 it.items = append(it.items, *dynamic) 333 334 return it 335 } 336 337 func (it *DynamicCollection) AddManyPtr( 338 dynamicItems ...*Dynamic, 339 ) *DynamicCollection { 340 if dynamicItems == nil { 341 return it 342 } 343 344 for _, item := range dynamicItems { 345 if item == nil { 346 continue 347 } 348 349 it.items = append(it.items, *item) 350 } 351 352 return it 353 } 354 355 func (it *DynamicCollection) AnyItems() []interface{} { 356 if it.IsEmpty() { 357 return []interface{}{} 358 } 359 360 slice := make([]interface{}, it.Length()) 361 362 for i, dynamicInstance := range it.items { 363 slice[i] = dynamicInstance.Value() 364 } 365 366 return slice 367 } 368 369 func (it *DynamicCollection) AddAnySliceFromSingleItem( 370 isValid bool, 371 sliceList interface{}, 372 ) *DynamicCollection { 373 if sliceList == nil { 374 return it 375 } 376 377 items := AnySliceValToInterfacesAsync(sliceList) 378 for _, item := range items { 379 it.items = append( 380 it.items, 381 NewDynamic(item, isValid)) 382 } 383 384 return it 385 } 386 387 func (it *DynamicCollection) AnyItemsCollection() *AnyCollection { 388 if it.IsEmpty() { 389 return EmptyAnyCollection() 390 } 391 392 slice := it.AnyItems() 393 394 return &AnyCollection{items: slice} 395 } 396 397 func (it *DynamicCollection) JsonString() (jsonString string, err error) { 398 toBytes, err := json.Marshal(it.items) 399 400 if err != nil { 401 return constants.EmptyString, nil 402 } 403 404 return string(toBytes), nil 405 } 406 407 func (it *DynamicCollection) JsonStringMust() string { 408 toString, err := it.JsonString() 409 410 if err != nil { 411 errcore. 412 MarshallingFailedType. 413 HandleUsingPanic(err.Error(), it.items) 414 } 415 416 return toString 417 } 418 419 func (it *DynamicCollection) MarshalJSON() ([]byte, error) { 420 return json.Marshal(it.JsonModelAny()) 421 } 422 423 func (it *DynamicCollection) UnmarshalJSON(data []byte) error { 424 var dataModel DynamicCollectionModel 425 err := json.Unmarshal(data, &dataModel) 426 427 if err == nil { 428 it.items = dataModel.Items 429 } 430 431 return err 432 } 433 434 func (it *DynamicCollection) JsonResultsCollection() *corejson.ResultsCollection { 435 jsonResultsCollection := corejson.NewResultsCollection.UsingCap(it.Length()) 436 437 if it.IsEmpty() { 438 return jsonResultsCollection 439 } 440 441 for _, dynamicInstance := range it.items { 442 jsonResultsCollection.AddAny( 443 dynamicInstance.Value()) 444 } 445 446 return jsonResultsCollection 447 } 448 449 func (it *DynamicCollection) JsonResultsPtrCollection() *corejson.ResultsPtrCollection { 450 jsonResultsCollection := corejson. 451 NewResultsPtrCollection. 452 UsingCap(it.Length()) 453 454 if it.IsEmpty() { 455 return jsonResultsCollection 456 } 457 458 for _, dynamicInstance := range it.items { 459 jsonResultsCollection.AddAny( 460 dynamicInstance.Value()) 461 } 462 463 return jsonResultsCollection 464 } 465 466 func (it *DynamicCollection) GetPagesSize( 467 eachPageSize int, 468 ) int { 469 length := it.Length() 470 471 pagesPossibleFloat := float64(length) / float64(eachPageSize) 472 pagesPossibleCeiling := int(math.Ceil(pagesPossibleFloat)) 473 474 return pagesPossibleCeiling 475 } 476 477 func (it *DynamicCollection) GetPagedCollection( 478 eachPageSize int, 479 ) []*DynamicCollection { 480 length := it.Length() 481 482 if length < eachPageSize { 483 return []*DynamicCollection{ 484 it, 485 } 486 } 487 488 pagesPossibleFloat := float64(length) / float64(eachPageSize) 489 pagesPossibleCeiling := int(math.Ceil(pagesPossibleFloat)) 490 collectionOfCollection := make( 491 []*DynamicCollection, 492 pagesPossibleCeiling) 493 494 wg := sync.WaitGroup{} 495 addPagedItemsFunc := func(oneBasedPageIndex int) { 496 pagedCollection := it.GetSinglePageCollection( 497 eachPageSize, 498 oneBasedPageIndex, 499 ) 500 501 collectionOfCollection[oneBasedPageIndex-1] = pagedCollection 502 503 wg.Done() 504 } 505 506 wg.Add(pagesPossibleCeiling) 507 for i := 1; i <= pagesPossibleCeiling; i++ { 508 go addPagedItemsFunc(i) 509 } 510 511 wg.Wait() 512 513 return collectionOfCollection 514 } 515 516 func (it *DynamicCollection) GetPagingInfo( 517 eachPageSize int, 518 pageIndex int, 519 ) pagingutil.PagingInfo { 520 return pagingutil.GetPagingInfo(pagingutil.PagingRequest{ 521 Length: it.Length(), 522 PageIndex: pageIndex, 523 EachPageSize: eachPageSize, 524 }) 525 } 526 527 // GetSinglePageCollection PageIndex is one based index. Should be above or equal 1 528 func (it *DynamicCollection) GetSinglePageCollection( 529 eachPageSize int, 530 pageIndex int, 531 ) *DynamicCollection { 532 length := it.Length() 533 534 if length < eachPageSize { 535 return it 536 } 537 538 pageInfo := it.GetPagingInfo( 539 eachPageSize, 540 pageIndex) 541 542 list := it.items[pageInfo.SkipItems:pageInfo.EndingLength] 543 544 return &DynamicCollection{ 545 items: list, 546 } 547 } 548 549 func (it *DynamicCollection) JsonModel() DynamicCollectionModel { 550 return DynamicCollectionModel{ 551 Items: it.items, 552 } 553 } 554 555 func (it *DynamicCollection) JsonModelAny() interface{} { 556 return it.JsonModel() 557 } 558 559 func (it DynamicCollection) Json() corejson.Result { 560 return corejson.New(it) 561 } 562 563 func (it DynamicCollection) JsonPtr() *corejson.Result { 564 return corejson.NewPtr(it) 565 } 566 567 func (it *DynamicCollection) ParseInjectUsingJson( 568 jsonResult *corejson.Result, 569 ) (*DynamicCollection, error) { 570 err := jsonResult.Unmarshal(it) 571 572 if err != nil { 573 return nil, err 574 } 575 576 return it, nil 577 } 578 579 func (it *DynamicCollection) ParseInjectUsingJsonMust( 580 jsonResult *corejson.Result, 581 ) *DynamicCollection { 582 newUsingJson, err := 583 it.ParseInjectUsingJson(jsonResult) 584 585 if err != nil { 586 panic(err) 587 } 588 589 return newUsingJson 590 } 591 592 func (it *DynamicCollection) JsonParseSelfInject( 593 jsonResult *corejson.Result, 594 ) error { 595 _, err := it.ParseInjectUsingJson( 596 jsonResult, 597 ) 598 599 return err 600 } 601 602 func (it *DynamicCollection) Strings() []string { 603 slice := make([]string, it.Length()) 604 605 if it.IsEmpty() { 606 return slice 607 } 608 609 for i, item := range it.items { 610 slice[i] = item.String() 611 } 612 613 return slice 614 } 615 616 func (it *DynamicCollection) String() string { 617 return strings.Join(it.Strings(), constants.NewLineUnix) 618 }