GraphQL API and utilities for the rpdata project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.1 KiB

  1. package loader
  2. import (
  3. "context"
  4. "errors"
  5. "strings"
  6. "git.aiterp.net/rpdata/api/model/character"
  7. "github.com/graph-gophers/dataloader"
  8. )
  9. // Character gets a character by key
  10. func (loader *Loader) Character(key, value string) (character.Character, error) {
  11. if !strings.HasPrefix(key, "Character.") {
  12. key = "Character." + key
  13. }
  14. loader.loadPrimed(key)
  15. if loader.loaders[key] == nil {
  16. return character.Character{}, errors.New("unsupported key")
  17. }
  18. thunk := loader.loaders[key].Load(loader.ctx, dataloader.StringKey(value))
  19. res, err := thunk()
  20. if err != nil {
  21. return character.Character{}, err
  22. }
  23. char, ok := res.(character.Character)
  24. if !ok {
  25. return character.Character{}, errors.New("incorrect type")
  26. }
  27. return char, nil
  28. }
  29. // Characters gets characters by key
  30. func (loader *Loader) Characters(key string, values ...string) ([]character.Character, error) {
  31. if !strings.HasPrefix(key, "Character.") {
  32. key = "Character." + key
  33. }
  34. if loader.loaders[key] == nil {
  35. return nil, errors.New("unsupported key")
  36. }
  37. loader.loadPrimed(key)
  38. thunk := loader.loaders[key].LoadMany(loader.ctx, dataloader.NewKeysFromStrings(values))
  39. res, errs := thunk()
  40. for _, err := range errs {
  41. if err != nil && err != ErrNotFound {
  42. return nil, err
  43. }
  44. }
  45. chars := make([]character.Character, len(res))
  46. for i := range res {
  47. char, ok := res[i].(character.Character)
  48. if !ok {
  49. return nil, errors.New("incorrect type")
  50. }
  51. chars[i] = char
  52. }
  53. return chars, nil
  54. }
  55. // PrimeCharacters adds a set of characters to be loaded if, and only if, characters
  56. // are going to be loaded. This will fill up the cache and speed up subsequent dataloader
  57. // runs.
  58. func (loader *Loader) PrimeCharacters(key string, values ...string) {
  59. if !strings.HasPrefix(key, "Character.") {
  60. key = "Character." + key
  61. }
  62. loader.prime(key, values)
  63. }
  64. func characterIDBatch(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
  65. results := make([]*dataloader.Result, 0, len(keys))
  66. ids := keys.Keys()
  67. characters, err := character.ListIDs(ids...)
  68. if err != nil {
  69. for range ids {
  70. results = append(results, &dataloader.Result{Error: err})
  71. }
  72. return results
  73. }
  74. for _, id := range ids {
  75. found := false
  76. for _, character := range characters {
  77. if character.ID == id {
  78. results = append(results, &dataloader.Result{Data: character})
  79. found = true
  80. break
  81. }
  82. }
  83. if !found {
  84. results = append(results, &dataloader.Result{Data: character.Character{}, Error: ErrNotFound})
  85. }
  86. }
  87. return results
  88. }
  89. func characterNickBatch(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
  90. var results []*dataloader.Result
  91. nicks := keys.Keys()
  92. characters, err := character.ListNicks(nicks...)
  93. if err != nil {
  94. for range nicks {
  95. results = append(results, &dataloader.Result{Error: err})
  96. }
  97. return results
  98. }
  99. for _, nick := range nicks {
  100. found := false
  101. for i := range characters {
  102. if characters[i].HasNick(nick) {
  103. results = append(results, &dataloader.Result{Data: characters[i]})
  104. found = true
  105. break
  106. }
  107. }
  108. if !found {
  109. results = append(results, &dataloader.Result{Data: character.Character{}, Error: err})
  110. }
  111. }
  112. return results
  113. }