diff options
author | Michael Muré <batolettre@gmail.com> | 2018-07-29 19:37:06 +0200 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2018-07-29 19:37:32 +0200 |
commit | c351cfd30d59c9179cc940f9ae15c461462e1a50 (patch) | |
tree | f2a218d26f350f265200e2ee89a1c94ca26fd770 | |
parent | 8fa0b258ac89781dae269790a4bde09cbcd2f324 (diff) | |
download | git-bug-c351cfd30d59c9179cc940f9ae15c461462e1a50.tar.gz |
graphql: directly return a connection, cleaning
-rw-r--r-- | graphql/connections/connection_template.go | 82 | ||||
-rw-r--r-- | graphql/connections/connections.go | 39 | ||||
-rw-r--r-- | graphql/connections/gen_bug.go | 83 | ||||
-rw-r--r-- | graphql/connections/gen_comment.go | 83 | ||||
-rw-r--r-- | graphql/connections/gen_operation.go | 83 | ||||
-rw-r--r-- | graphql/gqlgen.yml | 2 | ||||
-rw-r--r-- | graphql/models/edges.go | 13 | ||||
-rw-r--r-- | graphql/models/gen_models.go (renamed from graphql/resolvers/gen_model.go) | 8 | ||||
-rw-r--r-- | graphql/resolvers/bug.go | 58 | ||||
-rw-r--r-- | graphql/resolvers/gen_graph.go | 118 | ||||
-rw-r--r-- | graphql/resolvers/operations.go | 9 | ||||
-rw-r--r-- | graphql/resolvers/pager_bug.go | 225 | ||||
-rw-r--r-- | graphql/resolvers/pager_comment.go | 225 | ||||
-rw-r--r-- | graphql/resolvers/pager_operation.go | 225 | ||||
-rw-r--r-- | graphql/resolvers/pagers.go | 51 | ||||
-rw-r--r-- | graphql/resolvers/pagers_template.go | 224 | ||||
-rw-r--r-- | graphql/resolvers/repo.go | 3 | ||||
-rw-r--r-- | graphql/schema.graphql | 2 |
18 files changed, 480 insertions, 1053 deletions
diff --git a/graphql/connections/connection_template.go b/graphql/connections/connection_template.go new file mode 100644 index 00000000..3dfaca8f --- /dev/null +++ b/graphql/connections/connection_template.go @@ -0,0 +1,82 @@ +package connections + +import ( + "fmt" + "github.com/MichaelMure/git-bug/graphql/models" + "github.com/cheekybits/genny/generic" +) + +type NodeType generic.Type +type EdgeType generic.Type +type ConnectionType generic.Type + +type NodeTypeEdger func(value NodeType, offset int) Edge +type NodeTypeConMaker func(edges []EdgeType, info models.PageInfo, totalCount int) ConnectionType + +func NodeTypeCon(source []NodeType, edger NodeTypeEdger, conMaker NodeTypeConMaker, input models.ConnectionInput) (ConnectionType, error) { + var edges []EdgeType + var pageInfo models.PageInfo + + emptyCon := conMaker(edges, pageInfo, 0) + + offset := 0 + + if input.After != nil { + for i, value := range source { + edge := edger(value, i) + if edge.GetCursor() == *input.After { + // remove all previous element including the "after" one + source = source[i+1:] + offset = i + 1 + break + } + } + } + + if input.Before != nil { + for i, value := range source { + edge := edger(value, i+offset) + + if edge.GetCursor() == *input.Before { + // remove all after element including the "before" one + break + } + + edges = append(edges, edge.(EdgeType)) + } + } else { + edges = make([]EdgeType, len(source)) + + for i, value := range source { + edges[i] = edger(value, i+offset).(EdgeType) + } + } + + if input.First != nil { + if *input.First < 0 { + return emptyCon, fmt.Errorf("first less than zero") + } + + if len(edges) > *input.First { + // Slice result to be of length first by removing edges from the end + edges = edges[:*input.First] + pageInfo.HasNextPage = true + } + } + + if input.Last != nil { + if *input.Last < 0 { + return emptyCon, fmt.Errorf("last less than zero") + } + + if len(edges) > *input.Last { + // Slice result to be of length last by removing edges from the start + edges = edges[len(edges)-*input.Last:] + pageInfo.HasPreviousPage = true + } + } + + con := conMaker(edges, pageInfo, len(source)) + + return con, nil +} diff --git a/graphql/connections/connections.go b/graphql/connections/connections.go new file mode 100644 index 00000000..145bfbbe --- /dev/null +++ b/graphql/connections/connections.go @@ -0,0 +1,39 @@ +//go:generate genny -in=connection_template.go -out=gen_bug.go gen "NodeType=bug.Snapshot EdgeType=models.BugEdge ConnectionType=models.BugConnection" +//go:generate genny -in=connection_template.go -out=gen_operation.go gen "NodeType=bug.Operation EdgeType=models.OperationEdge ConnectionType=models.OperationConnection" +//go:generate genny -in=connection_template.go -out=gen_comment.go gen "NodeType=bug.Comment EdgeType=models.CommentEdge ConnectionType=models.CommentConnection" + +package connections + +import ( + "encoding/base64" + "fmt" + "strconv" + "strings" +) + +const cursorPrefix = "cursor:" + +type Edge interface { + GetCursor() string +} + +// Creates the cursor string from an offset +func OffsetToCursor(offset int) string { + str := fmt.Sprintf("%v%v", cursorPrefix, offset) + return base64.StdEncoding.EncodeToString([]byte(str)) +} + +// Re-derives the offset from the cursor string. +func CursorToOffset(cursor string) (int, error) { + str := "" + b, err := base64.StdEncoding.DecodeString(cursor) + if err == nil { + str = string(b) + } + str = strings.Replace(str, cursorPrefix, "", -1) + offset, err := strconv.Atoi(str) + if err != nil { + return 0, fmt.Errorf("Invalid cursor") + } + return offset, nil +} diff --git a/graphql/connections/gen_bug.go b/graphql/connections/gen_bug.go new file mode 100644 index 00000000..b43d5c11 --- /dev/null +++ b/graphql/connections/gen_bug.go @@ -0,0 +1,83 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package connections + +import ( + "fmt" + + "github.com/MichaelMure/git-bug/bug" + "github.com/MichaelMure/git-bug/graphql/models" +) + +type BugSnapshotEdger func(value bug.Snapshot, offset int) Edge +type BugSnapshotConMaker func(edges []models.BugEdge, info models.PageInfo, totalCount int) models.BugConnection + +func BugSnapshotCon(source []bug.Snapshot, edger BugSnapshotEdger, conMaker BugSnapshotConMaker, input models.ConnectionInput) (models.BugConnection, error) { + var edges []models.BugEdge + var pageInfo models.PageInfo + + emptyCon := conMaker(edges, pageInfo, 0) + + offset := 0 + + if input.After != nil { + for i, value := range source { + edge := edger(value, i) + if edge.GetCursor() == *input.After { + // remove all previous element including the "after" one + source = source[i+1:] + offset = i + 1 + break + } + } + } + + if input.Before != nil { + for i, value := range source { + edge := edger(value, i+offset) + + if edge.GetCursor() == *input.Before { + // remove all after element including the "before" one + break + } + + edges = append(edges, edge.(models.BugEdge)) + } + } else { + edges = make([]models.BugEdge, len(source)) + + for i, value := range source { + edges[i] = edger(value, i+offset).(models.BugEdge) + } + } + + if input.First != nil { + if *input.First < 0 { + return emptyCon, fmt.Errorf("first less than zero") + } + + if len(edges) > *input.First { + // Slice result to be of length first by removing edges from the end + edges = edges[:*input.First] + pageInfo.HasNextPage = true + } + } + + if input.Last != nil { + if *input.Last < 0 { + return emptyCon, fmt.Errorf("last less than zero") + } + + if len(edges) > *input.Last { + // Slice result to be of length last by removing edges from the start + edges = edges[len(edges)-*input.Last:] + pageInfo.HasPreviousPage = true + } + } + + con := conMaker(edges, pageInfo, len(source)) + + return con, nil +} diff --git a/graphql/connections/gen_comment.go b/graphql/connections/gen_comment.go new file mode 100644 index 00000000..dfcce42a --- /dev/null +++ b/graphql/connections/gen_comment.go @@ -0,0 +1,83 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package connections + +import ( + "fmt" + + "github.com/MichaelMure/git-bug/bug" + "github.com/MichaelMure/git-bug/graphql/models" +) + +type BugCommentEdger func(value bug.Comment, offset int) Edge +type BugCommentConMaker func(edges []models.CommentEdge, info models.PageInfo, totalCount int) models.CommentConnection + +func BugCommentCon(source []bug.Comment, edger BugCommentEdger, conMaker BugCommentConMaker, input models.ConnectionInput) (models.CommentConnection, error) { + var edges []models.CommentEdge + var pageInfo models.PageInfo + + emptyCon := conMaker(edges, pageInfo, 0) + + offset := 0 + + if input.After != nil { + for i, value := range source { + edge := edger(value, i) + if edge.GetCursor() == *input.After { + // remove all previous element including the "after" one + source = source[i+1:] + offset = i + 1 + break + } + } + } + + if input.Before != nil { + for i, value := range source { + edge := edger(value, i+offset) + + if edge.GetCursor() == *input.Before { + // remove all after element including the "before" one + break + } + + edges = append(edges, edge.(models.CommentEdge)) + } + } else { + edges = make([]models.CommentEdge, len(source)) + + for i, value := range source { + edges[i] = edger(value, i+offset).(models.CommentEdge) + } + } + + if input.First != nil { + if *input.First < 0 { + return emptyCon, fmt.Errorf("first less than zero") + } + + if len(edges) > *input.First { + // Slice result to be of length first by removing edges from the end + edges = edges[:*input.First] + pageInfo.HasNextPage = true + } + } + + if input.Last != nil { + if *input.Last < 0 { + return emptyCon, fmt.Errorf("last less than zero") + } + + if len(edges) > *input.Last { + // Slice result to be of length last by removing edges from the start + edges = edges[len(edges)-*input.Last:] + pageInfo.HasPreviousPage = true + } + } + + con := conMaker(edges, pageInfo, len(source)) + + return con, nil +} diff --git a/graphql/connections/gen_operation.go b/graphql/connections/gen_operation.go new file mode 100644 index 00000000..32cee97a --- /dev/null +++ b/graphql/connections/gen_operation.go @@ -0,0 +1,83 @@ +// This file was automatically generated by genny. +// Any changes will be lost if this file is regenerated. +// see https://github.com/cheekybits/genny + +package connections + +import ( + "fmt" + + "github.com/MichaelMure/git-bug/bug" + "github.com/MichaelMure/git-bug/graphql/models" +) + +type BugOperationEdger func(value bug.Operation, offset int) Edge +type BugOperationConMaker func(edges []models.OperationEdge, info models.PageInfo, totalCount int) models.OperationConnection + +func BugOperationCon(source []bug.Operation, edger BugOperationEdger, conMaker BugOperationConMaker, input models.ConnectionInput) (models.OperationConnection, error) { + var edges []models.OperationEdge + var pageInfo models.PageInfo + + emptyCon := conMaker(edges, pageInfo, 0) + + offset := 0 + + if input.After != nil { + for i, value := range source { + edge := edger(value, i) + if edge.GetCursor() == *input.After { + // remove all previous element including the "after" one + source = source[i+1:] + offset = i + 1 + break + } + } + } + + if input.Before != nil { + for i, value := range source { + edge := edger(value, i+offset) + + if edge.GetCursor() == *input.Before { + // remove all after element including the "before" one + break + } + + edges = append(edges, edge.(models.OperationEdge)) + } + } else { + edges = make([]models.OperationEdge, len(source)) + + for i, value := range source { + edges[i] = edger(value, i+offset).(models.OperationEdge) + } + } + + if input.First != nil { + if *input.First < 0 { + return emptyCon, fmt.Errorf("first less than zero") + } + + if len(edges) > *input.First { + // Slice result to be of length first by removing edges from the end + edges = edges[:*input.First] + pageInfo.HasNextPage = true + } + } + + if input.Last != nil { + if *input.Last < 0 { + return emptyCon, fmt.Errorf("last less than zero") + } + + if len(edges) > *input.Last { + // Slice result to be of length last by removing edges from the start + edges = edges[len(edges)-*input.Last:] + pageInfo.HasPreviousPage = true + } + } + + con := conMaker(edges, pageInfo, len(source)) + + return con, nil +} diff --git a/graphql/gqlgen.yml b/graphql/gqlgen.yml index 131a8b58..b0b89ab7 100644 --- a/graphql/gqlgen.yml +++ b/graphql/gqlgen.yml @@ -2,7 +2,7 @@ schema: schema.graphql exec: filename: resolvers/gen_graph.go model: - filename: resolvers/gen_model.go + filename: models/gen_models.go models: Repository: diff --git a/graphql/models/edges.go b/graphql/models/edges.go new file mode 100644 index 00000000..677d13f5 --- /dev/null +++ b/graphql/models/edges.go @@ -0,0 +1,13 @@ +package models + +func (e OperationEdge) GetCursor() string { + return e.Cursor +} + +func (e BugEdge) GetCursor() string { + return e.Cursor +} + +func (e CommentEdge) GetCursor() string { + return e.Cursor +} diff --git a/graphql/resolvers/gen_model.go b/graphql/models/gen_models.go index f6d78471..a59288ec 100644 --- a/graphql/resolvers/gen_model.go +++ b/graphql/models/gen_models.go @@ -1,6 +1,6 @@ // Code generated by github.com/vektah/gqlgen, DO NOT EDIT. -package resolvers +package models import ( fmt "fmt" @@ -12,9 +12,9 @@ import ( type Authored interface{} type BugConnection struct { - Edges []*BugEdge `json:"edges"` - PageInfo PageInfo `json:"pageInfo"` - TotalCount int `json:"totalCount"` + Edges []BugEdge `json:"edges"` + PageInfo PageInfo `json:"pageInfo"` + TotalCount int `json:"totalCount"` } type BugEdge struct { Cursor string `json:"cursor"` diff --git a/graphql/resolvers/bug.go b/graphql/resolvers/bug.go index ad6c288b..246507c6 100644 --- a/graphql/resolvers/bug.go +++ b/graphql/resolvers/bug.go @@ -4,58 +4,52 @@ import ( "context" "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/cache" + "github.com/MichaelMure/git-bug/graphql/connections" + "github.com/MichaelMure/git-bug/graphql/models" ) type bugResolver struct { cache cache.Cacher } -func (bugResolver) Status(ctx context.Context, obj *bug.Snapshot) (Status, error) { +func (bugResolver) Status(ctx context.Context, obj *bug.Snapshot) (models.Status, error) { return convertStatus(obj.Status) } -func (bugResolver) Comments(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (CommentConnection, error) { - var connection CommentConnection - - edger := func(comment bug.Comment, offset int) Edge { - return CommentEdge{ +func (bugResolver) Comments(ctx context.Context, obj *bug.Snapshot, input models.ConnectionInput) (models.CommentConnection, error) { + edger := func(comment bug.Comment, offset int) connections.Edge { + return models.CommentEdge{ Node: comment, - Cursor: offsetToCursor(offset), + Cursor: connections.OffsetToCursor(offset), } } - edges, pageInfo, err := BugCommentPaginate(obj.Comments, edger, input) - - if err != nil { - return connection, err + conMaker := func(edges []models.CommentEdge, info models.PageInfo, totalCount int) models.CommentConnection { + return models.CommentConnection{ + Edges: edges, + PageInfo: info, + TotalCount: totalCount, + } } - connection.Edges = edges - connection.PageInfo = pageInfo - connection.TotalCount = len(obj.Comments) - - return connection, nil + return connections.BugCommentCon(obj.Comments, edger, conMaker, input) } -func (bugResolver) Operations(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (OperationConnection, error) { - var connection OperationConnection - - edger := func(op bug.Operation, offset int) Edge { - return OperationEdge{ - Node: op.(OperationUnion), - Cursor: offsetToCursor(offset), +func (bugResolver) Operations(ctx context.Context, obj *bug.Snapshot, input models.ConnectionInput) (models.OperationConnection, error) { + edger := func(op bug.Operation, offset int) connections.Edge { + return models.OperationEdge{ + Node: op.(models.OperationUnion), + Cursor: connections.OffsetToCursor(offset), } } - edges, pageInfo, err := BugOperationPaginate(obj.Operations, edger, input) - - if err != nil { - return connection, err + conMaker := func(edges []models.OperationEdge, info models.PageInfo, totalCount int) models.OperationConnection { + return models.OperationConnection{ + Edges: edges, + PageInfo: info, + TotalCount: totalCount, + } } - connection.Edges = edges - connection.PageInfo = pageInfo - connection.TotalCount = len(obj.Operations) - - return connection, nil + return connections.BugOperationCon(obj.Operations, edger, conMaker, input) } diff --git a/graphql/resolvers/gen_graph.go b/graphql/resolvers/gen_graph.go index 3d752ddc..409b7e42 100644 --- a/graphql/resolvers/gen_graph.go +++ b/graphql/resolvers/gen_graph.go @@ -11,6 +11,7 @@ import ( bug "github.com/MichaelMure/git-bug/bug" operations "github.com/MichaelMure/git-bug/bug/operations" + models "github.com/MichaelMure/git-bug/graphql/models" graphql "github.com/vektah/gqlgen/graphql" introspection "github.com/vektah/gqlgen/neelance/introspection" query "github.com/vektah/gqlgen/neelance/query" @@ -30,10 +31,10 @@ func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { type Resolvers interface { AddCommentOperation_date(ctx context.Context, obj *operations.AddCommentOperation) (time.Time, error) - Bug_status(ctx context.Context, obj *bug.Snapshot) (Status, error) + Bug_status(ctx context.Context, obj *bug.Snapshot) (models.Status, error) - Bug_comments(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (CommentConnection, error) - Bug_operations(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (OperationConnection, error) + Bug_comments(ctx context.Context, obj *bug.Snapshot, input models.ConnectionInput) (models.CommentConnection, error) + Bug_operations(ctx context.Context, obj *bug.Snapshot, input models.ConnectionInput) (models.OperationConnection, error) CreateOperation_date(ctx context.Context, obj *operations.CreateOperation) (time.Time, error) @@ -42,11 +43,11 @@ type Resolvers interface { Query_defaultRepository(ctx context.Context) (*repoResolver, error) Query_repository(ctx context.Context, id string) (*repoResolver, error) - Repository_allBugs(ctx context.Context, obj *repoResolver, input ConnectionInput) (BugConnection, error) + Repository_allBugs(ctx context.Context, obj *repoResolver, input models.ConnectionInput) (models.BugConnection, error) Repository_bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error) SetStatusOperation_date(ctx context.Context, obj *operations.SetStatusOperation) (time.Time, error) - SetStatusOperation_status(ctx context.Context, obj *operations.SetStatusOperation) (Status, error) + SetStatusOperation_status(ctx context.Context, obj *operations.SetStatusOperation) (models.Status, error) SetTitleOperation_date(ctx context.Context, obj *operations.SetTitleOperation) (time.Time, error) } @@ -65,10 +66,10 @@ type AddCommentOperationResolver interface { Date(ctx context.Context, obj *operations.AddCommentOperation) (time.Time, error) } type BugResolver interface { - Status(ctx context.Context, obj *bug.Snapshot) (Status, error) + Status(ctx context.Context, obj *bug.Snapshot) (models.Status, error) - Comments(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (CommentConnection, error) - Operations(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (OperationConnection, error) + Comments(ctx context.Context, obj *bug.Snapshot, input models.ConnectionInput) (models.CommentConnection, error) + Operations(ctx context.Context, obj *bug.Snapshot, input models.ConnectionInput) (models.OperationConnection, error) } type CreateOperationResolver interface { Date(ctx context.Context, obj *operations.CreateOperation) (time.Time, error) @@ -81,12 +82,12 @@ type QueryResolver interface { Repository(ctx context.Context, id string) (*repoResolver, error) } type RepositoryResolver interface { - AllBugs(ctx context.Context, obj *repoResolver, input ConnectionInput) (BugConnection, error) + AllBugs(ctx context.Context, obj *repoResolver, input models.ConnectionInput) (models.BugConnection, error) Bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error) } type SetStatusOperationResolver interface { Date(ctx context.Context, obj *operations.SetStatusOperation) (time.Time, error) - Status(ctx context.Context, obj *operations.SetStatusOperation) (Status, error) + Status(ctx context.Context, obj *operations.SetStatusOperation) (models.Status, error) } type SetTitleOperationResolver interface { Date(ctx context.Context, obj *operations.SetTitleOperation) (time.Time, error) @@ -100,15 +101,15 @@ func (s shortMapper) AddCommentOperation_date(ctx context.Context, obj *operatio return s.r.AddCommentOperation().Date(ctx, obj) } -func (s shortMapper) Bug_status(ctx context.Context, obj *bug.Snapshot) (Status, error) { +func (s shortMapper) Bug_status(ctx context.Context, obj *bug.Snapshot) (models.Status, error) { return s.r.Bug().Status(ctx, obj) } -func (s shortMapper) Bug_comments(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (CommentConnection, error) { +func (s shortMapper) Bug_comments(ctx context.Context, obj *bug.Snapshot, input models.ConnectionInput) (models.CommentConnection, error) { return s.r.Bug().Comments(ctx, obj, input) } -func (s shortMapper) Bug_operations(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (OperationConnection, error) { +func (s shortMapper) Bug_operations(ctx context.Context, obj *bug.Snapshot, input models.ConnectionInput) (models.OperationConnection, error) { return s.r.Bug().Operations(ctx, obj, input) } @@ -128,7 +129,7 @@ func (s shortMapper) Query_repository(ctx context.Context, id string) (*repoReso return s.r.Query().Repository(ctx, id) } -func (s shortMapper) Repository_allBugs(ctx context.Context, obj *repoResolver, input ConnectionInput) (BugConnection, error) { +func (s shortMapper) Repository_allBugs(ctx context.Context, obj *repoResolver, input models.ConnectionInput) (models.BugConnection, error) { return s.r.Repository().AllBugs(ctx, obj, input) } @@ -140,7 +141,7 @@ func (s shortMapper) SetStatusOperation_date(ctx context.Context, obj *operation return s.r.SetStatusOperation().Date(ctx, obj) } -func (s shortMapper) SetStatusOperation_status(ctx context.Context, obj *operations.SetStatusOperation) (Status, error) { +func (s shortMapper) SetStatusOperation_status(ctx context.Context, obj *operations.SetStatusOperation) (models.Status, error) { return s.r.SetStatusOperation().Status(ctx, obj) } @@ -358,7 +359,7 @@ func (ec *executionContext) _Bug_status(ctx context.Context, field graphql.Colle if resTmp == nil { return graphql.Null } - res := resTmp.(Status) + res := resTmp.(models.Status) return res }) } @@ -385,7 +386,7 @@ func (ec *executionContext) _Bug_labels(ctx context.Context, field graphql.Colle func (ec *executionContext) _Bug_comments(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler { args := map[string]interface{}{} - var arg0 ConnectionInput + var arg0 models.ConnectionInput if tmp, ok := field.Args["input"]; ok { var err error arg0, err = UnmarshalConnectionInput(tmp) @@ -410,7 +411,7 @@ func (ec *executionContext) _Bug_comments(ctx context.Context, field graphql.Col }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Bug_comments(ctx, obj, args["input"].(ConnectionInput)) + return ec.resolvers.Bug_comments(ctx, obj, args["input"].(models.ConnectionInput)) }) if err != nil { ec.Error(ctx, err) @@ -419,14 +420,14 @@ func (ec *executionContext) _Bug_comments(ctx context.Context, field graphql.Col if resTmp == nil { return graphql.Null } - res := resTmp.(CommentConnection) + res := resTmp.(models.CommentConnection) return ec._CommentConnection(ctx, field.Selections, &res) }) } func (ec *executionContext) _Bug_operations(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler { args := map[string]interface{}{} - var arg0 ConnectionInput + var arg0 models.ConnectionInput if tmp, ok := field.Args["input"]; ok { var err error arg0, err = UnmarshalConnectionInput(tmp) @@ -451,7 +452,7 @@ func (ec *executionContext) _Bug_operations(ctx context.Context, field graphql.C }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Bug_operations(ctx, obj, args["input"].(ConnectionInput)) + return ec.resolvers.Bug_operations(ctx, obj, args["input"].(models.ConnectionInput)) }) if err != nil { ec.Error(ctx, err) @@ -460,7 +461,7 @@ func (ec *executionContext) _Bug_operations(ctx context.Context, field graphql.C if resTmp == nil { return graphql.Null } - res := resTmp.(OperationConnection) + res := resTmp.(models.OperationConnection) return ec._OperationConnection(ctx, field.Selections, &res) }) } @@ -468,7 +469,7 @@ func (ec *executionContext) _Bug_operations(ctx context.Context, field graphql.C var bugConnectionImplementors = []string{"BugConnection"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _BugConnection(ctx context.Context, sel []query.Selection, obj *BugConnection) graphql.Marshaler { +func (ec *executionContext) _BugConnection(ctx context.Context, sel []query.Selection, obj *models.BugConnection) graphql.Marshaler { fields := graphql.CollectFields(ec.Doc, sel, bugConnectionImplementors, ec.Variables) out := graphql.NewOrderedMap(len(fields)) @@ -492,7 +493,7 @@ func (ec *executionContext) _BugConnection(ctx context.Context, sel []query.Sele return out } -func (ec *executionContext) _BugConnection_edges(ctx context.Context, field graphql.CollectedField, obj *BugConnection) graphql.Marshaler { +func (ec *executionContext) _BugConnection_edges(ctx context.Context, field graphql.CollectedField, obj *models.BugConnection) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "BugConnection" rctx.Args = nil @@ -506,16 +507,13 @@ func (ec *executionContext) _BugConnection_edges(ctx context.Context, field grap rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec._BugEdge(ctx, field.Selections, res[idx1]) + return ec._BugEdge(ctx, field.Selections, &res[idx1]) }()) } return arr1 } -func (ec *executionContext) _BugConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *BugConnection) graphql.Marshaler { +func (ec *executionContext) _BugConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *models.BugConnection) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "BugConnection" rctx.Args = nil @@ -526,7 +524,7 @@ func (ec *executionContext) _BugConnection_pageInfo(ctx context.Context, field g return ec._PageInfo(ctx, field.Selections, &res) } -func (ec *executionContext) _BugConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *BugConnection) graphql.Marshaler { +func (ec *executionContext) _BugConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *models.BugConnection) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "BugConnection" rctx.Args = nil @@ -540,7 +538,7 @@ func (ec *executionContext) _BugConnection_totalCount(ctx context.Context, field var bugEdgeImplementors = []string{"BugEdge"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _BugEdge(ctx context.Context, sel []query.Selection, obj *BugEdge) graphql.Marshaler { +func (ec *executionContext) _BugEdge(ctx context.Context, sel []query.Selection, obj *models.BugEdge) graphql.Marshaler { fields := graphql.CollectFields(ec.Doc, sel, bugEdgeImplementors, ec.Variables) out := graphql.NewOrderedMap(len(fields)) @@ -562,7 +560,7 @@ func (ec *executionContext) _BugEdge(ctx context.Context, sel []query.Selection, return out } -func (ec *executionContext) _BugEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *BugEdge) graphql.Marshaler { +func (ec *executionContext) _BugEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *models.BugEdge) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "BugEdge" rctx.Args = nil @@ -573,7 +571,7 @@ func (ec *executionContext) _BugEdge_cursor(ctx context.Context, field graphql.C return graphql.MarshalString(res) } -func (ec *executionContext) _BugEdge_node(ctx context.Context, field graphql.CollectedField, obj *BugEdge) graphql.Marshaler { +func (ec *executionContext) _BugEdge_node(ctx context.Context, field graphql.CollectedField, obj *models.BugEdge) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "BugEdge" rctx.Args = nil @@ -634,7 +632,7 @@ func (ec *executionContext) _Comment_message(ctx context.Context, field graphql. var commentConnectionImplementors = []string{"CommentConnection"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _CommentConnection(ctx context.Context, sel []query.Selection, obj *CommentConnection) graphql.Marshaler { +func (ec *executionContext) _CommentConnection(ctx context.Context, sel []query.Selection, obj *models.CommentConnection) graphql.Marshaler { fields := graphql.CollectFields(ec.Doc, sel, commentConnectionImplementors, ec.Variables) out := graphql.NewOrderedMap(len(fields)) @@ -658,7 +656,7 @@ func (ec *executionContext) _CommentConnection(ctx context.Context, sel []query. return out } -func (ec *executionContext) _CommentConnection_edges(ctx context.Context, field graphql.CollectedField, obj *CommentConnection) graphql.Marshaler { +func (ec *executionContext) _CommentConnection_edges(ctx context.Context, field graphql.CollectedField, obj *models.CommentConnection) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "CommentConnection" rctx.Args = nil @@ -678,7 +676,7 @@ func (ec *executionContext) _CommentConnection_edges(ctx context.Context, field return arr1 } -func (ec *executionContext) _CommentConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *CommentConnection) graphql.Marshaler { +func (ec *executionContext) _CommentConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *models.CommentConnection) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "CommentConnection" rctx.Args = nil @@ -689,7 +687,7 @@ func (ec *executionContext) _CommentConnection_pageInfo(ctx context.Context, fie return ec._PageInfo(ctx, field.Selections, &res) } -func (ec *executionContext) _CommentConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *CommentConnection) graphql.Marshaler { +func (ec *executionContext) _CommentConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *models.CommentConnection) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "CommentConnection" rctx.Args = nil @@ -703,7 +701,7 @@ func (ec *executionContext) _CommentConnection_totalCount(ctx context.Context, f var commentEdgeImplementors = []string{"CommentEdge"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _CommentEdge(ctx context.Context, sel []query.Selection, obj *CommentEdge) graphql.Marshaler { +func (ec *executionContext) _CommentEdge(ctx context.Context, sel []query.Selection, obj *models.CommentEdge) graphql.Marshaler { fields := graphql.CollectFields(ec.Doc, sel, commentEdgeImplementors, ec.Variables) out := graphql.NewOrderedMap(len(fields)) @@ -725,7 +723,7 @@ func (ec *executionContext) _CommentEdge(ctx context.Context, sel []query.Select return out } -func (ec *executionContext) _CommentEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *CommentEdge) graphql.Marshaler { +func (ec *executionContext) _CommentEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *models.CommentEdge) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "CommentEdge" rctx.Args = nil @@ -736,7 +734,7 @@ func (ec *executionContext) _CommentEdge_cursor(ctx context.Context, field graph return graphql.MarshalString(res) } -func (ec *executionContext) _CommentEdge_node(ctx context.Context, field graphql.CollectedField, obj *CommentEdge) graphql.Marshaler { +func (ec *executionContext) _CommentEdge_node(ctx context.Context, field graphql.CollectedField, obj *models.CommentEdge) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "CommentEdge" rctx.Args = nil @@ -952,7 +950,7 @@ func (ec *executionContext) _LabelChangeOperation_removed(ctx context.Context, f var operationConnectionImplementors = []string{"OperationConnection"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _OperationConnection(ctx context.Context, sel []query.Selection, obj *OperationConnection) graphql.Marshaler { +func (ec *executionContext) _OperationConnection(ctx context.Context, sel []query.Selection, obj *models.OperationConnection) graphql.Marshaler { fields := graphql.CollectFields(ec.Doc, sel, operationConnectionImplementors, ec.Variables) out := graphql.NewOrderedMap(len(fields)) @@ -976,7 +974,7 @@ func (ec *executionContext) _OperationConnection(ctx context.Context, sel []quer return out } -func (ec *executionContext) _OperationConnection_edges(ctx context.Context, field graphql.CollectedField, obj *OperationConnection) graphql.Marshaler { +func (ec *executionContext) _OperationConnection_edges(ctx context.Context, field graphql.CollectedField, obj *models.OperationConnection) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "OperationConnection" rctx.Args = nil @@ -996,7 +994,7 @@ func (ec *executionContext) _OperationConnection_edges(ctx context.Context, fiel return arr1 } -func (ec *executionContext) _OperationConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *OperationConnection) graphql.Marshaler { +func (ec *executionContext) _OperationConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *models.OperationConnection) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "OperationConnection" rctx.Args = nil @@ -1007,7 +1005,7 @@ func (ec *executionContext) _OperationConnection_pageInfo(ctx context.Context, f return ec._PageInfo(ctx, field.Selections, &res) } -func (ec *executionContext) _OperationConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *OperationConnection) graphql.Marshaler { +func (ec *executionContext) _OperationConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *models.OperationConnection) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "OperationConnection" rctx.Args = nil @@ -1021,7 +1019,7 @@ func (ec *executionContext) _OperationConnection_totalCount(ctx context.Context, var operationEdgeImplementors = []string{"OperationEdge"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _OperationEdge(ctx context.Context, sel []query.Selection, obj *OperationEdge) graphql.Marshaler { +func (ec *executionContext) _OperationEdge(ctx context.Context, sel []query.Selection, obj *models.OperationEdge) graphql.Marshaler { fields := graphql.CollectFields(ec.Doc, sel, operationEdgeImplementors, ec.Variables) out := graphql.NewOrderedMap(len(fields)) @@ -1043,7 +1041,7 @@ func (ec *executionContext) _OperationEdge(ctx context.Context, sel []query.Sele return out } -func (ec *executionContext) _OperationEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *OperationEdge) graphql.Marshaler { +func (ec *executionContext) _OperationEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *models.OperationEdge) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "OperationEdge" rctx.Args = nil @@ -1054,7 +1052,7 @@ func (ec *executionContext) _OperationEdge_cursor(ctx context.Context, field gra return graphql.MarshalString(res) } -func (ec *executionContext) _OperationEdge_node(ctx context.Context, field graphql.CollectedField, obj *OperationEdge) graphql.Marshaler { +func (ec *executionContext) _OperationEdge_node(ctx context.Context, field graphql.CollectedField, obj *models.OperationEdge) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "OperationEdge" rctx.Args = nil @@ -1068,7 +1066,7 @@ func (ec *executionContext) _OperationEdge_node(ctx context.Context, field graph var pageInfoImplementors = []string{"PageInfo"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _PageInfo(ctx context.Context, sel []query.Selection, obj *PageInfo) graphql.Marshaler { +func (ec *executionContext) _PageInfo(ctx context.Context, sel []query.Selection, obj *models.PageInfo) graphql.Marshaler { fields := graphql.CollectFields(ec.Doc, sel, pageInfoImplementors, ec.Variables) out := graphql.NewOrderedMap(len(fields)) @@ -1090,7 +1088,7 @@ func (ec *executionContext) _PageInfo(ctx context.Context, sel []query.Selection return out } -func (ec *executionContext) _PageInfo_hasNextPage(ctx context.Context, field graphql.CollectedField, obj *PageInfo) graphql.Marshaler { +func (ec *executionContext) _PageInfo_hasNextPage(ctx context.Context, field graphql.CollectedField, obj *models.PageInfo) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "PageInfo" rctx.Args = nil @@ -1101,7 +1099,7 @@ func (ec *executionContext) _PageInfo_hasNextPage(ctx context.Context, field gra return graphql.MarshalBoolean(res) } -func (ec *executionContext) _PageInfo_hasPreviousPage(ctx context.Context, field graphql.CollectedField, obj *PageInfo) graphql.Marshaler { +func (ec *executionContext) _PageInfo_hasPreviousPage(ctx context.Context, field graphql.CollectedField, obj *models.PageInfo) graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.Object = "PageInfo" rctx.Args = nil @@ -1335,7 +1333,7 @@ func (ec *executionContext) _Repository(ctx context.Context, sel []query.Selecti func (ec *executionContext) _Repository_allBugs(ctx context.Context, field graphql.CollectedField, obj *repoResolver) graphql.Marshaler { args := map[string]interface{}{} - var arg0 ConnectionInput + var arg0 models.ConnectionInput if tmp, ok := field.Args["input"]; ok { var err error arg0, err = UnmarshalConnectionInput(tmp) @@ -1360,7 +1358,7 @@ func (ec *executionContext) _Repository_allBugs(ctx context.Context, field graph }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Repository_allBugs(ctx, obj, args["input"].(ConnectionInput)) + return ec.resolvers.Repository_allBugs(ctx, obj, args["input"].(models.ConnectionInput)) }) if err != nil { ec.Error(ctx, err) @@ -1369,7 +1367,7 @@ func (ec *executionContext) _Repository_allBugs(ctx context.Context, field graph if resTmp == nil { return graphql.Null } - res := resTmp.(BugConnection) + res := resTmp.(models.BugConnection) return ec._BugConnection(ctx, field.Selections, &res) }) } @@ -1511,7 +1509,7 @@ func (ec *executionContext) _SetStatusOperation_status(ctx context.Context, fiel if resTmp == nil { return graphql.Null } - res := resTmp.(Status) + res := resTmp.(models.Status) return res }) } @@ -2285,7 +2283,7 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co return ec.___Type(ctx, field.Selections, res) } -func (ec *executionContext) _Authored(ctx context.Context, sel []query.Selection, obj *Authored) graphql.Marshaler { +func (ec *executionContext) _Authored(ctx context.Context, sel []query.Selection, obj *models.Authored) graphql.Marshaler { switch obj := (*obj).(type) { case nil: return graphql.Null @@ -2318,7 +2316,7 @@ func (ec *executionContext) _Authored(ctx context.Context, sel []query.Selection } } -func (ec *executionContext) _Operation(ctx context.Context, sel []query.Selection, obj *Operation) graphql.Marshaler { +func (ec *executionContext) _Operation(ctx context.Context, sel []query.Selection, obj *models.Operation) graphql.Marshaler { switch obj := (*obj).(type) { case nil: return graphql.Null @@ -2347,7 +2345,7 @@ func (ec *executionContext) _Operation(ctx context.Context, sel []query.Selectio } } -func (ec *executionContext) _OperationUnion(ctx context.Context, sel []query.Selection, obj *OperationUnion) graphql.Marshaler { +func (ec *executionContext) _OperationUnion(ctx context.Context, sel []query.Selection, obj *models.OperationUnion) graphql.Marshaler { switch obj := (*obj).(type) { case nil: return graphql.Null @@ -2376,8 +2374,8 @@ func (ec *executionContext) _OperationUnion(ctx context.Context, sel []query.Sel } } -func UnmarshalConnectionInput(v interface{}) (ConnectionInput, error) { - var it ConnectionInput +func UnmarshalConnectionInput(v interface{}) (models.ConnectionInput, error) { + var it models.ConnectionInput var asMap = v.(map[string]interface{}) for k, v := range asMap { @@ -2584,7 +2582,7 @@ union OperationUnion = # The connection type for Bug. type BugConnection { # A list of edges. - edges: [BugEdge]! + edges: [BugEdge!]! # Information to aid in pagination. pageInfo: PageInfo! diff --git a/graphql/resolvers/operations.go b/graphql/resolvers/operations.go index 1279a1b4..7fb3f3e2 100644 --- a/graphql/resolvers/operations.go +++ b/graphql/resolvers/operations.go @@ -6,6 +6,7 @@ import ( "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/bug/operations" "time" + "github.com/MichaelMure/git-bug/graphql/models" ) type addCommentOperationResolver struct{} @@ -32,7 +33,7 @@ func (setStatusOperationResolver) Date(ctx context.Context, obj *operations.SetS return obj.Time(), nil } -func (setStatusOperationResolver) Status(ctx context.Context, obj *operations.SetStatusOperation) (Status, error) { +func (setStatusOperationResolver) Status(ctx context.Context, obj *operations.SetStatusOperation) (models.Status, error) { return convertStatus(obj.Status) } @@ -42,12 +43,12 @@ func (setTitleOperationResolver) Date(ctx context.Context, obj *operations.SetTi return obj.Time(), nil } -func convertStatus(status bug.Status) (Status, error) { +func convertStatus(status bug.Status) (models.Status, error) { switch status { case bug.OpenStatus: - return StatusOpen, nil + return models.StatusOpen, nil case bug.ClosedStatus: - return StatusClosed, nil + return models.StatusClosed, nil } return "", fmt.Errorf("Unknown status") diff --git a/graphql/resolvers/pager_bug.go b/graphql/resolvers/pager_bug.go deleted file mode 100644 index 55acfcc4..00000000 --- a/graphql/resolvers/pager_bug.go +++ /dev/null @@ -1,225 +0,0 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -package resolvers - -import ( - "fmt" - - "github.com/MichaelMure/git-bug/bug" -) - -type BugSnapshotEdger func(value bug.Snapshot, offset int) Edge - -func BugSnapshotPaginate(source []bug.Snapshot, edger BugSnapshotEdger, input ConnectionInput) ([]BugEdge, PageInfo, error) { - var result []BugEdge - var pageInfo PageInfo - - offset := 0 - - if input.After != nil { - for i, value := range source { - edge := edger(value, i) - if edge.GetCursor() == *input.After { - // remove all previous element including the "after" one - source = source[i+1:] - offset = i + 1 - break - } - } - } - - if input.Before != nil { - for i, value := range source { - edge := edger(value, i+offset) - - if edge.GetCursor() == *input.Before { - // remove all after element including the "before" one - break - } - - result = append(result, edge.(BugEdge)) - } - } else { - result = make([]BugEdge, len(source)) - - for i, value := range source { - result[i] = edger(value, i+offset).(BugEdge) - } - } - - if input.First != nil { - if *input.First < 0 { - return nil, PageInfo{}, fmt.Errorf("first less than zero") - } - - if len(result) > *input.First { - // Slice result to be of length first by removing edges from the end - result = result[:*input.First] - pageInfo.HasNextPage = true - } - } - - if input.Last != nil { - if *input.Last < 0 { - return nil, PageInfo{}, fmt.Errorf("last less than zero") - } - - if len(result) > *input.Last { - // Slice result to be of length last by removing edges from the start - result = result[len(result)-*input.Last:] - pageInfo.HasPreviousPage = true - } - } - - return result, pageInfo, nil -} - -// Apply the before/after cursor params to the source and return an array of edges -//func ApplyCursorToEdges(source []interface{}, edger Edger, input ConnectionInput) []Edge { -// var result []Edge -// -// if input.After != nil { -// for i, value := range source { -// edge := edger(value) -// if edge.Cursor() == *input.After { -// // remove all previous element including the "after" one -// source = source[i+1:] -// break -// } -// } -// } -// -// if input.Before != nil { -// for _, value := range source { -// edge := edger(value) -// -// if edge.Cursor() == *input.Before { -// // remove all after element including the "before" one -// break -// } -// -// result = append(result, edge) -// } -// } else { -// result = make([]Edge, len(source)) -// -// for i, value := range source { -// result[i] = edger(value) -// } -// } -// -// return result -//} - -// Apply the first/last cursor params to the edges -//func EdgesToReturn(edges []Edge, input ConnectionInput) ([]Edge, PageInfo, error) { -// hasPreviousPage := false -// hasNextPage := false -// -// if input.First != nil { -// if *input.First < 0 { -// return nil, nil, fmt.Errorf("first less than zero") -// } -// -// if len(edges) > *input.First { -// // Slice result to be of length first by removing edges from the end -// edges = edges[:*input.First] -// hasNextPage = true -// } -// } -// -// if input.Last != nil { -// if *input.Last < 0 { -// return nil, nil, fmt.Errorf("last less than zero") -// } -// -// if len(edges) > *input.Last { -// // Slice result to be of length last by removing edges from the start -// edges = edges[len(edges)-*input.Last:] -// hasPreviousPage = true -// } -// } -// -// pageInfo := PageInfo{ -// HasNextPage: hasNextPage, -// HasPreviousPage: hasPreviousPage, -// } -// -// return edges, pageInfo, nil -//} - -//func EdgesToReturn(allEdges []Edge, before *cursor, after *cursor, first *int, last *int) ([]Edge, error) { -// result := ApplyCursorToEdges(allEdges, before, after) -// -// if first != nil { -// if *first < 0 { -// return nil, fmt.Errorf("first less than zero") -// } -// -// if len(result) > *first { -// // Slice result to be of length first by removing edges from the end -// result = result[:*first] -// } -// } -// -// if last != nil { -// if *last < 0 { -// return nil, fmt.Errorf("last less than zero") -// } -// -// if len(result) > *last { -// // Slice result to be of length last by removing edges from the start -// result = result[len(result)-*last:] -// } -// } -// -// return result, nil -//} - -//func ApplyCursorToEdges(allEdges []Edge, before *cursor, after *cursor) []Edge { -// result := allEdges -// -// if after != nil { -// for i, edge := range result { -// if edge.Cursor() == *after { -// // remove all previous element including the "after" one -// result = result[i+1:] -// break -// } -// } -// } -// -// if before != nil { -// for i, edge := range result { -// if edge.Cursor() == *before { -// // remove all after element including the "before" one -// result = result[:i] -// } -// } -// } -// -// return result -//} - -//func HasPreviousPage(allEdges []Edge, before *cursor, after *cursor, last *int) bool { -// if last != nil { -// edges := ApplyCursorToEdges(allEdges, before, after) -// return len(edges) > *last -// } -// -// // TODO: handle "after", but according to the spec it's ok to return false -// -// return false -//} -// -//func HasNextPage(allEdges []Edge, before *cursor, after *cursor, first *int) bool { -// if first != nil { -// edges := ApplyCursorToEdges(allEdges, before, after) -// return len(edges) > *first -// } -// -// // TODO: handle "before", but according to the spec it's ok to return false -// -// return false diff --git a/graphql/resolvers/pager_comment.go b/graphql/resolvers/pager_comment.go deleted file mode 100644 index 3dd11757..00000000 --- a/graphql/resolvers/pager_comment.go +++ /dev/null @@ -1,225 +0,0 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -package resolvers - -import ( - "fmt" - - "github.com/MichaelMure/git-bug/bug" -) - -type BugCommentEdger func(value bug.Comment, offset int) Edge - -func BugCommentPaginate(source []bug.Comment, edger BugCommentEdger, input ConnectionInput) ([]CommentEdge, PageInfo, error) { - var result []CommentEdge - var pageInfo PageInfo - - offset := 0 - - if input.After != nil { - for i, value := range source { - edge := edger(value, i) - if edge.GetCursor() == *input.After { - // remove all previous element including the "after" one - source = source[i+1:] - offset = i + 1 - break - } - } - } - - if input.Before != nil { - for i, value := range source { - edge := edger(value, i+offset) - - if edge.GetCursor() == *input.Before { - // remove all after element including the "before" one - break - } - - result = append(result, edge.(CommentEdge)) - } - } else { - result = make([]CommentEdge, len(source)) - - for i, value := range source { - result[i] = edger(value, i+offset).(CommentEdge) - } - } - - if input.First != nil { - if *input.First < 0 { - return nil, PageInfo{}, fmt.Errorf("first less than zero") - } - - if len(result) > *input.First { - // Slice result to be of length first by removing edges from the end - result = result[:*input.First] - pageInfo.HasNextPage = true - } - } - - if input.Last != nil { - if *input.Last < 0 { - return nil, PageInfo{}, fmt.Errorf("last less than zero") - } - - if len(result) > *input.Last { - // Slice result to be of length last by removing edges from the start - result = result[len(result)-*input.Last:] - pageInfo.HasPreviousPage = true - } - } - - return result, pageInfo, nil -} - -// Apply the before/after cursor params to the source and return an array of edges -//func ApplyCursorToEdges(source []interface{}, edger Edger, input ConnectionInput) []Edge { -// var result []Edge -// -// if input.After != nil { -// for i, value := range source { -// edge := edger(value) -// if edge.Cursor() == *input.After { -// // remove all previous element including the "after" one -// source = source[i+1:] -// break -// } -// } -// } -// -// if input.Before != nil { -// for _, value := range source { -// edge := edger(value) -// -// if edge.Cursor() == *input.Before { -// // remove all after element including the "before" one -// break -// } -// -// result = append(result, edge) -// } -// } else { -// result = make([]Edge, len(source)) -// -// for i, value := range source { -// result[i] = edger(value) -// } -// } -// -// return result -//} - -// Apply the first/last cursor params to the edges -//func EdgesToReturn(edges []Edge, input ConnectionInput) ([]Edge, PageInfo, error) { -// hasPreviousPage := false -// hasNextPage := false -// -// if input.First != nil { -// if *input.First < 0 { -// return nil, nil, fmt.Errorf("first less than zero") -// } -// -// if len(edges) > *input.First { -// // Slice result to be of length first by removing edges from the end -// edges = edges[:*input.First] -// hasNextPage = true -// } -// } -// -// if input.Last != nil { -// if *input.Last < 0 { -// return nil, nil, fmt.Errorf("last less than zero") -// } -// -// if len(edges) > *input.Last { -// // Slice result to be of length last by removing edges from the start -// edges = edges[len(edges)-*input.Last:] -// hasPreviousPage = true -// } -// } -// -// pageInfo := PageInfo{ -// HasNextPage: hasNextPage, -// HasPreviousPage: hasPreviousPage, -// } -// -// return edges, pageInfo, nil -//} - -//func EdgesToReturn(allEdges []Edge, before *cursor, after *cursor, first *int, last *int) ([]Edge, error) { -// result := ApplyCursorToEdges(allEdges, before, after) -// -// if first != nil { -// if *first < 0 { -// return nil, fmt.Errorf("first less than zero") -// } -// -// if len(result) > *first { -// // Slice result to be of length first by removing edges from the end -// result = result[:*first] -// } -// } -// -// if last != nil { -// if *last < 0 { -// return nil, fmt.Errorf("last less than zero") -// } -// -// if len(result) > *last { -// // Slice result to be of length last by removing edges from the start -// result = result[len(result)-*last:] -// } -// } -// -// return result, nil -//} - -//func ApplyCursorToEdges(allEdges []Edge, before *cursor, after *cursor) []Edge { -// result := allEdges -// -// if after != nil { -// for i, edge := range result { -// if edge.Cursor() == *after { -// // remove all previous element including the "after" one -// result = result[i+1:] -// break -// } -// } -// } -// -// if before != nil { -// for i, edge := range result { -// if edge.Cursor() == *before { -// // remove all after element including the "before" one -// result = result[:i] -// } -// } -// } -// -// return result -//} - -//func HasPreviousPage(allEdges []Edge, before *cursor, after *cursor, last *int) bool { -// if last != nil { -// edges := ApplyCursorToEdges(allEdges, before, after) -// return len(edges) > *last -// } -// -// // TODO: handle "after", but according to the spec it's ok to return false -// -// return false -//} -// -//func HasNextPage(allEdges []Edge, before *cursor, after *cursor, first *int) bool { -// if first != nil { -// edges := ApplyCursorToEdges(allEdges, before, after) -// return len(edges) > *first -// } -// -// // TODO: handle "before", but according to the spec it's ok to return false -// -// return false diff --git a/graphql/resolvers/pager_operation.go b/graphql/resolvers/pager_operation.go deleted file mode 100644 index fe4eebc2..00000000 --- a/graphql/resolvers/pager_operation.go +++ /dev/null @@ -1,225 +0,0 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -package resolvers - -import ( - "fmt" - - "github.com/MichaelMure/git-bug/bug" -) - -type BugOperationEdger func(value bug.Operation, offset int) Edge - -func BugOperationPaginate(source []bug.Operation, edger BugOperationEdger, input ConnectionInput) ([]OperationEdge, PageInfo, error) { - var result []OperationEdge - var pageInfo PageInfo - - offset := 0 - - if input.After != nil { - for i, value := range source { - edge := edger(value, i) - if edge.GetCursor() == *input.After { - // remove all previous element including the "after" one - source = source[i+1:] - offset = i + 1 - break - } - } - } - - if input.Before != nil { - for i, value := range source { - edge := edger(value, i+offset) - - if edge.GetCursor() == *input.Before { - // remove all after element including the "before" one - break - } - - result = append(result, edge.(OperationEdge)) - } - } else { - result = make([]OperationEdge, len(source)) - - for i, value := range source { - result[i] = edger(value, i+offset).(OperationEdge) - } - } - - if input.First != nil { - if *input.First < 0 { - return nil, PageInfo{}, fmt.Errorf("first less than zero") - } - - if len(result) > *input.First { - // Slice result to be of length first by removing edges from the end - result = result[:*input.First] - pageInfo.HasNextPage = true - } - } - - if input.Last != nil { - if *input.Last < 0 { - return nil, PageInfo{}, fmt.Errorf("last less than zero") - } - - if len(result) > *input.Last { - // Slice result to be of length last by removing edges from the start - result = result[len(result)-*input.Last:] - pageInfo.HasPreviousPage = true - } - } - - return result, pageInfo, nil -} - -// Apply the before/after cursor params to the source and return an array of edges -//func ApplyCursorToEdges(source []interface{}, edger Edger, input ConnectionInput) []Edge { -// var result []Edge -// -// if input.After != nil { -// for i, value := range source { -// edge := edger(value) -// if edge.Cursor() == *input.After { -// // remove all previous element including the "after" one -// source = source[i+1:] -// break -// } -// } -// } -// -// if input.Before != nil { -// for _, value := range source { -// edge := edger(value) -// -// if edge.Cursor() == *input.Before { -// // remove all after element including the "before" one -// break -// } -// -// result = append(result, edge) -// } -// } else { -// result = make([]Edge, len(source)) -// -// for i, value := range source { -// result[i] = edger(value) -// } -// } -// -// return result -//} - -// Apply the first/last cursor params to the edges -//func EdgesToReturn(edges []Edge, input ConnectionInput) ([]Edge, PageInfo, error) { -// hasPreviousPage := false -// hasNextPage := false -// -// if input.First != nil { -// if *input.First < 0 { -// return nil, nil, fmt.Errorf("first less than zero") -// } -// -// if len(edges) > *input.First { -// // Slice result to be of length first by removing edges from the end -// edges = edges[:*input.First] -// hasNextPage = true -// } -// } -// -// if input.Last != nil { -// if *input.Last < 0 { -// return nil, nil, fmt.Errorf("last less than zero") -// } -// -// if len(edges) > *input.Last { -// // Slice result to be of length last by removing edges from the start -// edges = edges[len(edges)-*input.Last:] -// hasPreviousPage = true -// } -// } -// -// pageInfo := PageInfo{ -// HasNextPage: hasNextPage, -// HasPreviousPage: hasPreviousPage, -// } -// -// return edges, pageInfo, nil -//} - -//func EdgesToReturn(allEdges []Edge, before *cursor, after *cursor, first *int, last *int) ([]Edge, error) { -// result := ApplyCursorToEdges(allEdges, before, after) -// -// if first != nil { -// if *first < 0 { -// return nil, fmt.Errorf("first less than zero") -// } -// -// if len(result) > *first { -// // Slice result to be of length first by removing edges from the end -// result = result[:*first] -// } -// } -// -// if last != nil { -// if *last < 0 { -// return nil, fmt.Errorf("last less than zero") -// } -// -// if len(result) > *last { -// // Slice result to be of length last by removing edges from the start -// result = result[len(result)-*last:] -// } -// } -// -// return result, nil -//} - -//func ApplyCursorToEdges(allEdges []Edge, before *cursor, after *cursor) []Edge { -// result := allEdges -// -// if after != nil { -// for i, edge := range result { -// if edge.Cursor() == *after { -// // remove all previous element including the "after" one -// result = result[i+1:] -// break -// } -// } -// } -// -// if before != nil { -// for i, edge := range result { -// if edge.Cursor() == *before { -// // remove all after element including the "before" one -// result = result[:i] -// } -// } -// } -// -// return result -//} - -//func HasPreviousPage(allEdges []Edge, before *cursor, after *cursor, last *int) bool { -// if last != nil { -// edges := ApplyCursorToEdges(allEdges, before, after) -// return len(edges) > *last -// } -// -// // TODO: handle "after", but according to the spec it's ok to return false -// -// return false -//} -// -//func HasNextPage(allEdges []Edge, before *cursor, after *cursor, first *int) bool { -// if first != nil { -// edges := ApplyCursorToEdges(allEdges, before, after) -// return len(edges) > *first -// } -// -// // TODO: handle "before", but according to the spec it's ok to return false -// -// return false diff --git a/graphql/resolvers/pagers.go b/graphql/resolvers/pagers.go deleted file mode 100644 index 378dcdbf..00000000 --- a/graphql/resolvers/pagers.go +++ /dev/null @@ -1,51 +0,0 @@ -//go:generate genny -in=pagers_template.go -out=pager_bug.go gen "NodeType=bug.Snapshot EdgeType=BugEdge" -//go:generate genny -in=pagers_template.go -out=pager_operation.go gen "NodeType=bug.Operation EdgeType=OperationEdge" -//go:generate genny -in=pagers_template.go -out=pager_comment.go gen "NodeType=bug.Comment EdgeType=CommentEdge" - -package resolvers - -import ( - "encoding/base64" - "fmt" - "strconv" - "strings" -) - -const cursorPrefix = "cursor:" - -type Edge interface { - GetCursor() string -} - -// Creates the cursor string from an offset -func offsetToCursor(offset int) string { - str := fmt.Sprintf("%v%v", cursorPrefix, offset) - return base64.StdEncoding.EncodeToString([]byte(str)) -} - -// Re-derives the offset from the cursor string. -func cursorToOffset(cursor string) (int, error) { - str := "" - b, err := base64.StdEncoding.DecodeString(cursor) - if err == nil { - str = string(b) - } - str = strings.Replace(str, cursorPrefix, "", -1) - offset, err := strconv.Atoi(str) - if err != nil { - return 0, fmt.Errorf("Invalid cursor") - } - return offset, nil -} - -func (e OperationEdge) GetCursor() string { - return e.Cursor -} - -func (e BugEdge) GetCursor() string { - return e.Cursor -} - -func (e CommentEdge) GetCursor() string { - return e.Cursor -} diff --git a/graphql/resolvers/pagers_template.go b/graphql/resolvers/pagers_template.go deleted file mode 100644 index 0ca7de75..00000000 --- a/graphql/resolvers/pagers_template.go +++ /dev/null @@ -1,224 +0,0 @@ -package resolvers - -import ( - "fmt" - "github.com/cheekybits/genny/generic" -) - -type NodeType generic.Type -type EdgeType generic.Type - -type NodeTypeEdger func(value NodeType, offset int) Edge - -func NodeTypePaginate(source []NodeType, edger NodeTypeEdger, input ConnectionInput) ([]EdgeType, PageInfo, error) { - var result []EdgeType - var pageInfo PageInfo - - offset := 0 - - if input.After != nil { - for i, value := range source { - edge := edger(value, i) - if edge.GetCursor() == *input.After { - // remove all previous element including the "after" one - source = source[i+1:] - offset = i + 1 - break - } - } - } - - if input.Before != nil { - for i, value := range source { - edge := edger(value, i+offset) - - if edge.GetCursor() == *input.Before { - // remove all after element including the "before" one - break - } - - result = append(result, edge.(EdgeType)) - } - } else { - result = make([]EdgeType, len(source)) - - for i, value := range source { - result[i] = edger(value, i+offset).(EdgeType) - } - } - - if input.First != nil { - if *input.First < 0 { - return nil, PageInfo{}, fmt.Errorf("first less than zero") - } - - if len(result) > *input.First { - // Slice result to be of length first by removing edges from the end - result = result[:*input.First] - pageInfo.HasNextPage = true - } - } - - if input.Last != nil { - if *input.Last < 0 { - return nil, PageInfo{}, fmt.Errorf("last less than zero") - } - - if len(result) > *input.Last { - // Slice result to be of length last by removing edges from the start - result = result[len(result)-*input.Last:] - pageInfo.HasPreviousPage = true - } - } - - return result, pageInfo, nil -} - -// Apply the before/after cursor params to the source and return an array of edges -//func ApplyCursorToEdges(source []interface{}, edger Edger, input ConnectionInput) []Edge { -// var result []Edge -// -// if input.After != nil { -// for i, value := range source { -// edge := edger(value) -// if edge.Cursor() == *input.After { -// // remove all previous element including the "after" one -// source = source[i+1:] -// break -// } -// } -// } -// -// if input.Before != nil { -// for _, value := range source { -// edge := edger(value) -// -// if edge.Cursor() == *input.Before { -// // remove all after element including the "before" one -// break -// } -// -// result = append(result, edge) -// } -// } else { -// result = make([]Edge, len(source)) -// -// for i, value := range source { -// result[i] = edger(value) -// } -// } -// -// return result -//} - -// Apply the first/last cursor params to the edges -//func EdgesToReturn(edges []Edge, input ConnectionInput) ([]Edge, PageInfo, error) { -// hasPreviousPage := false -// hasNextPage := false -// -// if input.First != nil { -// if *input.First < 0 { -// return nil, nil, fmt.Errorf("first less than zero") -// } -// -// if len(edges) > *input.First { -// // Slice result to be of length first by removing edges from the end -// edges = edges[:*input.First] -// hasNextPage = true -// } -// } -// -// if input.Last != nil { -// if *input.Last < 0 { -// return nil, nil, fmt.Errorf("last less than zero") -// } -// -// if len(edges) > *input.Last { -// // Slice result to be of length last by removing edges from the start -// edges = edges[len(edges)-*input.Last:] -// hasPreviousPage = true -// } -// } -// -// pageInfo := PageInfo{ -// HasNextPage: hasNextPage, -// HasPreviousPage: hasPreviousPage, -// } -// -// return edges, pageInfo, nil -//} - -//func EdgesToReturn(allEdges []Edge, before *cursor, after *cursor, first *int, last *int) ([]Edge, error) { -// result := ApplyCursorToEdges(allEdges, before, after) -// -// if first != nil { -// if *first < 0 { -// return nil, fmt.Errorf("first less than zero") -// } -// -// if len(result) > *first { -// // Slice result to be of length first by removing edges from the end -// result = result[:*first] -// } -// } -// -// if last != nil { -// if *last < 0 { -// return nil, fmt.Errorf("last less than zero") -// } -// -// if len(result) > *last { -// // Slice result to be of length last by removing edges from the start -// result = result[len(result)-*last:] -// } -// } -// -// return result, nil -//} - -//func ApplyCursorToEdges(allEdges []Edge, before *cursor, after *cursor) []Edge { -// result := allEdges -// -// if after != nil { -// for i, edge := range result { -// if edge.Cursor() == *after { -// // remove all previous element including the "after" one -// result = result[i+1:] -// break -// } -// } -// } -// -// if before != nil { -// for i, edge := range result { -// if edge.Cursor() == *before { -// // remove all after element including the "before" one -// result = result[:i] -// } -// } -// } -// -// return result -//} - -//func HasPreviousPage(allEdges []Edge, before *cursor, after *cursor, last *int) bool { -// if last != nil { -// edges := ApplyCursorToEdges(allEdges, before, after) -// return len(edges) > *last -// } -// -// // TODO: handle "after", but according to the spec it's ok to return false -// -// return false -//} -// -//func HasNextPage(allEdges []Edge, before *cursor, after *cursor, first *int) bool { -// if first != nil { -// edges := ApplyCursorToEdges(allEdges, before, after) -// return len(edges) > *first -// } -// -// // TODO: handle "before", but according to the spec it's ok to return false -// -// return false -//} diff --git a/graphql/resolvers/repo.go b/graphql/resolvers/repo.go index 14019b65..d8190f15 100644 --- a/graphql/resolvers/repo.go +++ b/graphql/resolvers/repo.go @@ -4,6 +4,7 @@ import ( "context" "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/cache" + "github.com/MichaelMure/git-bug/graphql/models" ) type repoResolver struct { @@ -11,7 +12,7 @@ type repoResolver struct { repo cache.RepoCacher } -func (repoResolver) AllBugs(ctx context.Context, obj *repoResolver, input ConnectionInput) (BugConnection, error) { +func (repoResolver) AllBugs(ctx context.Context, obj *repoResolver, input models.ConnectionInput) (models.BugConnection, error) { panic("implement me") } diff --git a/graphql/schema.graphql b/graphql/schema.graphql index 47716488..14b2bec5 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -138,7 +138,7 @@ union OperationUnion = # The connection type for Bug. type BugConnection { # A list of edges. - edges: [BugEdge]! + edges: [BugEdge!]! # Information to aid in pagination. pageInfo: PageInfo! |