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
146 lines
3.2 KiB
package loader
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
|
|
"git.aiterp.net/rpdata/api/models"
|
|
"git.aiterp.net/rpdata/api/models/characters"
|
|
"github.com/graph-gophers/dataloader"
|
|
)
|
|
|
|
// Character gets a character by key
|
|
func (loader *Loader) Character(key, value string) (models.Character, error) {
|
|
if !strings.HasPrefix(key, "Character.") {
|
|
key = "Character." + key
|
|
}
|
|
|
|
loader.loadPrimed(key)
|
|
|
|
if loader.loaders[key] == nil {
|
|
return models.Character{}, errors.New("unsupported key")
|
|
}
|
|
|
|
thunk := loader.loaders[key].Load(loader.ctx, dataloader.StringKey(value))
|
|
res, err := thunk()
|
|
if err != nil {
|
|
return models.Character{}, err
|
|
}
|
|
|
|
char, ok := res.(models.Character)
|
|
if !ok {
|
|
return models.Character{}, errors.New("incorrect type")
|
|
}
|
|
|
|
return char, nil
|
|
}
|
|
|
|
// Characters gets characters by key
|
|
func (loader *Loader) Characters(key string, values ...string) ([]models.Character, error) {
|
|
if !strings.HasPrefix(key, "Character.") {
|
|
key = "Character." + key
|
|
}
|
|
|
|
if loader.loaders[key] == nil {
|
|
return nil, errors.New("unsupported key")
|
|
}
|
|
|
|
loader.loadPrimed(key)
|
|
|
|
thunk := loader.loaders[key].LoadMany(loader.ctx, dataloader.NewKeysFromStrings(values))
|
|
res, errs := thunk()
|
|
for _, err := range errs {
|
|
if err != nil && err != ErrNotFound {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
chars := make([]models.Character, len(res))
|
|
|
|
for i := range res {
|
|
char, ok := res[i].(models.Character)
|
|
if !ok {
|
|
return nil, errors.New("incorrect type")
|
|
}
|
|
|
|
chars[i] = char
|
|
}
|
|
|
|
return chars, nil
|
|
}
|
|
|
|
// PrimeCharacters adds a set of characters to be loaded if, and only if, characters
|
|
// are going to be loaded. This will fill up the cache and speed up subsequent dataloader
|
|
// runs.
|
|
func (loader *Loader) PrimeCharacters(key string, values ...string) {
|
|
if !strings.HasPrefix(key, "Character.") {
|
|
key = "Character." + key
|
|
}
|
|
|
|
loader.prime(key, values)
|
|
}
|
|
|
|
func characterIDBatch(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
|
|
results := make([]*dataloader.Result, 0, len(keys))
|
|
ids := keys.Keys()
|
|
|
|
characters, err := characters.List(&characters.Filter{IDs: ids})
|
|
if err != nil {
|
|
for range ids {
|
|
results = append(results, &dataloader.Result{Error: err})
|
|
}
|
|
|
|
return results
|
|
}
|
|
|
|
for _, id := range ids {
|
|
found := false
|
|
|
|
for _, character := range characters {
|
|
if character.ID == id {
|
|
results = append(results, &dataloader.Result{Data: character})
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
results = append(results, &dataloader.Result{Data: models.Character{}, Error: ErrNotFound})
|
|
}
|
|
}
|
|
|
|
return results
|
|
}
|
|
|
|
func characterNickBatch(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
|
|
var results []*dataloader.Result
|
|
nicks := keys.Keys()
|
|
|
|
characters, err := characters.List(&characters.Filter{Nicks: nicks})
|
|
if err != nil {
|
|
for range nicks {
|
|
results = append(results, &dataloader.Result{Error: err})
|
|
}
|
|
|
|
return results
|
|
}
|
|
|
|
for _, nick := range nicks {
|
|
found := false
|
|
for i := range characters {
|
|
if characters[i].HasNick(nick) {
|
|
results = append(results, &dataloader.Result{Data: characters[i]})
|
|
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
results = append(results, &dataloader.Result{Data: models.Character{}, Error: err})
|
|
}
|
|
}
|
|
|
|
return results
|
|
}
|