From 1a91f4fdd6e8b774c933b96be78809240c49b54b Mon Sep 17 00:00:00 2001 From: Gisle Aune Date: Sat, 16 Jun 2018 22:36:27 +0200 Subject: [PATCH] Added channel link from log --- cmd/rpdata-graphiql/main.go | 2 +- loader/channel.go | 66 +++++++++++++++++++++++++++++++++++++ loader/loader.go | 5 +-- model/channel/channel.go | 10 ++++++ resolver/log.go | 21 ++++++++++-- schema/types/log.graphql | 12 +++++-- 6 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 loader/channel.go diff --git a/cmd/rpdata-graphiql/main.go b/cmd/rpdata-graphiql/main.go index 0442652..cfb23fb 100644 --- a/cmd/rpdata-graphiql/main.go +++ b/cmd/rpdata-graphiql/main.go @@ -28,7 +28,7 @@ func main() { } log.Println("Updated characters on", n, "logs") - schema, err := graphql.ParseSchema(schema.String(), &resolver.RootResolver{}, graphql.MaxParallelism(4)) + schema, err := graphql.ParseSchema(schema.String(), &resolver.RootResolver{}, graphql.MaxParallelism(32)) if err != nil { log.Fatalln("Failed to parse schema:", err) } diff --git a/loader/channel.go b/loader/channel.go new file mode 100644 index 0000000..3bb5bcb --- /dev/null +++ b/loader/channel.go @@ -0,0 +1,66 @@ +package loader + +import ( + "context" + "errors" + "strings" + + "git.aiterp.net/rpdata/api/model/channel" + "github.com/graph-gophers/dataloader" +) + +// Channel gets a character by key +func (loader *Loader) Channel(key, value string) (channel.Channel, error) { + if !strings.HasPrefix(key, "Channel.") { + key = "Channel." + key + } + + if loader.loaders[key] == nil { + return channel.Channel{}, errors.New("unsupported key") + } + + thunk := loader.loaders[key].Load(loader.ctx, dataloader.StringKey(value)) + res, err := thunk() + if err != nil { + return channel.Channel{}, err + } + + channel, ok := res.(channel.Channel) + if !ok { + return channel, errors.New("incorrect type") + } + + return channel, nil +} + +func channelNameBatch(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { + var results []*dataloader.Result + names := keys.Keys() + + channels, err := channel.ListNames(names...) + if err != nil { + for range names { + results = append(results, &dataloader.Result{Data: channel.Channel{}, Error: err}) + } + + return results + } + + for _, name := range names { + found := false + for i := range channels { + if channels[i].Name == name { + results = append(results, &dataloader.Result{Data: channels[i]}) + + found = true + break + } + } + + if !found { + results = append(results, &dataloader.Result{Data: channel.Channel{}, Error: err}) + } + } + + return results +} diff --git a/loader/loader.go b/loader/loader.go index c121692..9cb0946 100644 --- a/loader/loader.go +++ b/loader/loader.go @@ -25,8 +25,9 @@ func New() *Loader { return &Loader{ ctx: context.Background(), loaders: map[string]*dataloader.Loader{ - "Character.id": dataloader.NewBatchedLoader(characterIDBatch, dataloader.WithWait(time.Millisecond*2)), - "Character.nick": dataloader.NewBatchedLoader(characterNickBatch, dataloader.WithWait(time.Millisecond*2)), + "Character.id": dataloader.NewBatchedLoader(characterIDBatch, dataloader.WithWait(time.Millisecond)), + "Character.nick": dataloader.NewBatchedLoader(characterNickBatch, dataloader.WithWait(time.Millisecond)), + "Channel.name": dataloader.NewBatchedLoader(channelNameBatch, dataloader.WithWait(time.Millisecond)), }, } } diff --git a/model/channel/channel.go b/model/channel/channel.go index 2ccf777..53dd771 100644 --- a/model/channel/channel.go +++ b/model/channel/channel.go @@ -121,6 +121,16 @@ func List(logged bool) ([]Channel, error) { return channels, err } +// ListNames finds channels by the names provided +func ListNames(names ...string) ([]Channel, error) { + query := bson.M{"_id": bson.M{"$in": names}} + + channels := make([]Channel, 0, 32) + err := collection.Find(query).All(&channels) + + return channels, err +} + func init() { store.HandleInit(func(db *mgo.Database) { collection = db.C("common.channels") diff --git a/resolver/log.go b/resolver/log.go index 8005fa5..9645e75 100644 --- a/resolver/log.go +++ b/resolver/log.go @@ -2,8 +2,10 @@ package resolver import ( "context" + "errors" "time" + "git.aiterp.net/rpdata/api/loader" "git.aiterp.net/rpdata/api/model/change" "git.aiterp.net/rpdata/api/internal/session" @@ -239,11 +241,26 @@ func (r *LogResolver) Date() string { return r.L.Date.Format(time.RFC3339Nano) } -// Channel resolves Log.channel -func (r *LogResolver) Channel() string { +// ChannelName resolves Log.channelName +func (r *LogResolver) ChannelName() string { return r.L.Channel } +// Channel resolves Log.channe +func (r *LogResolver) Channel(ctx context.Context) (*ChannelResolver, error) { + loader := loader.FromContext(ctx) + if loader == nil { + return nil, errors.New("no loader") + } + + channel, err := loader.Channel("name", r.L.Channel) + if err != nil { + return nil, err + } + + return &ChannelResolver{C: channel}, nil +} + // Title resolves Log.title func (r *LogResolver) Title() string { return r.L.Title diff --git a/schema/types/log.graphql b/schema/types/log.graphql index 60d5a62..dae60d8 100644 --- a/schema/types/log.graphql +++ b/schema/types/log.graphql @@ -11,7 +11,10 @@ type Log { date: String! # The channel of a log. - channel: String! + channelName: String! + + # Information about the channel this log is in. + channel: Channel! # The session's title. title: String! @@ -105,9 +108,12 @@ type LogHeader { # The date for a log. date: String! - # The channel of a log. - channel: String! + # The channel name of a log. + channelName: String! + # Information about the channel this log is in. + channel: Channel! + # The session's title. title: String!