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.

146 lines
3.2 KiB

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