From e0bf6afd14fbba795a0823248a05547c0d4fc520 Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Sat, 14 Jul 2018 12:23:07 +1000 Subject: [PATCH] Support nullable list elements --- codegen/type_build.go | 2 +- example/dataloader/generated.go | 2 +- example/dataloader/schema.graphql | 2 +- example/selection/generated.go | 2 +- example/selection/schema.graphql | 2 +- example/starwars/generated.go | 18 +++++++++--------- example/starwars/schema.graphql | 18 +++++++++--------- test/generated.go | 13 ++++++++----- test/resolvers_test.go | 4 ++-- 9 files changed, 33 insertions(+), 30 deletions(-) diff --git a/codegen/type_build.go b/codegen/type_build.go index d157b84fd6c..ba2874b0572 100644 --- a/codegen/type_build.go +++ b/codegen/type_build.go @@ -80,7 +80,7 @@ func (n NamedTypes) getType(t common.Type) *Type { if _, nonNull := t.(*common.NonNull); nonNull { usePtr = false } else if _, nonNull := t.(*common.List); nonNull { - usePtr = false + usePtr = true } else { if usePtr { modifiers = append(modifiers, modPtr) diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index eb3c3c01bbe..998b51d77b4 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -1359,7 +1359,7 @@ var parsedSchema = schema.MustParse(`type Query { customers: [Customer!] # this method is here to test code generation of nested arrays - torture(customerIds: [[Int]]): [[Customer!]] + torture(customerIds: [[Int!]]): [[Customer!]] } type Customer { diff --git a/example/dataloader/schema.graphql b/example/dataloader/schema.graphql index 1d8165bbb49..dacddf47dd8 100644 --- a/example/dataloader/schema.graphql +++ b/example/dataloader/schema.graphql @@ -2,7 +2,7 @@ type Query { customers: [Customer!] # this method is here to test code generation of nested arrays - torture(customerIds: [[Int]]): [[Customer!]] + torture(customerIds: [[Int!]]): [[Customer!]] } type Customer { diff --git a/example/selection/generated.go b/example/selection/generated.go index 7a36fa9bb28..83990834c66 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -1147,7 +1147,7 @@ type Like implements Event { } type Query { - events: [Event] + events: [Event!] } scalar Time diff --git a/example/selection/schema.graphql b/example/selection/schema.graphql index 85a14b4de86..729a71c48df 100644 --- a/example/selection/schema.graphql +++ b/example/selection/schema.graphql @@ -18,7 +18,7 @@ type Like implements Event { } type Query { - events: [Event] + events: [Event!] } scalar Time diff --git a/example/starwars/generated.go b/example/starwars/generated.go index aa10cb366ed..928e4b22d25 100644 --- a/example/starwars/generated.go +++ b/example/starwars/generated.go @@ -2386,8 +2386,8 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { var parsedSchema = schema.MustParse(`# The query type, represents all of the entry points into our object graph type Query { hero(episode: Episode = NEWHOPE): Character - reviews(episode: Episode!, since: Time): [Review]! - search(text: String!): [SearchResult]! + reviews(episode: Episode!, since: Time): [Review!]! + search(text: String!): [SearchResult!]! character(id: ID!): Character droid(id: ID!): Droid human(id: ID!): Human @@ -2413,7 +2413,7 @@ interface Character { # The name of the character name: String! # The friends of the character, or an empty list if they have none - friends: [Character] + friends: [Character!] # The friends of the character exposed as a connection with edges friendsConnection(first: Int, after: ID): FriendsConnection! # The movies this character appears in @@ -2437,13 +2437,13 @@ type Human implements Character { # Mass in kilograms, or null if unknown mass: Float # This human's friends, or an empty list if they have none - friends: [Character] + friends: [Character!] # The friends of the human exposed as a connection with edges friendsConnection(first: Int, after: ID): FriendsConnection! # The movies this human appears in appearsIn: [Episode!]! # A list of starships this person has piloted, or an empty list if none - starships: [Starship] + starships: [Starship!] } # An autonomous mechanical character in the Star Wars universe type Droid implements Character { @@ -2452,7 +2452,7 @@ type Droid implements Character { # What others call this droid name: String! # This droid's friends, or an empty list if they have none - friends: [Character] + friends: [Character!] # The friends of the droid exposed as a connection with edges friendsConnection(first: Int, after: ID): FriendsConnection! # The movies this droid appears in @@ -2465,9 +2465,9 @@ type FriendsConnection { # The total number of friends totalCount: Int! # The edges for each of the character's friends. - edges: [FriendsEdge] + edges: [FriendsEdge!] # A list of the friends, as a convenience when edges are not needed. - friends: [Character] + friends: [Character!] # Information for paginating this connection pageInfo: PageInfo! } @@ -2510,7 +2510,7 @@ type Starship { # Length of the starship, along the longest axis length(unit: LengthUnit = METER): Float! # coordinates tracking this ship - history: [[Int]] + history: [[Int!]!]! } union SearchResult = Human | Droid | Starship scalar Time diff --git a/example/starwars/schema.graphql b/example/starwars/schema.graphql index 58007fac2b8..48af8e50c1d 100644 --- a/example/starwars/schema.graphql +++ b/example/starwars/schema.graphql @@ -1,8 +1,8 @@ # The query type, represents all of the entry points into our object graph type Query { hero(episode: Episode = NEWHOPE): Character - reviews(episode: Episode!, since: Time): [Review]! - search(text: String!): [SearchResult]! + reviews(episode: Episode!, since: Time): [Review!]! + search(text: String!): [SearchResult!]! character(id: ID!): Character droid(id: ID!): Droid human(id: ID!): Human @@ -28,7 +28,7 @@ interface Character { # The name of the character name: String! # The friends of the character, or an empty list if they have none - friends: [Character] + friends: [Character!] # The friends of the character exposed as a connection with edges friendsConnection(first: Int, after: ID): FriendsConnection! # The movies this character appears in @@ -52,13 +52,13 @@ type Human implements Character { # Mass in kilograms, or null if unknown mass: Float # This human's friends, or an empty list if they have none - friends: [Character] + friends: [Character!] # The friends of the human exposed as a connection with edges friendsConnection(first: Int, after: ID): FriendsConnection! # The movies this human appears in appearsIn: [Episode!]! # A list of starships this person has piloted, or an empty list if none - starships: [Starship] + starships: [Starship!] } # An autonomous mechanical character in the Star Wars universe type Droid implements Character { @@ -67,7 +67,7 @@ type Droid implements Character { # What others call this droid name: String! # This droid's friends, or an empty list if they have none - friends: [Character] + friends: [Character!] # The friends of the droid exposed as a connection with edges friendsConnection(first: Int, after: ID): FriendsConnection! # The movies this droid appears in @@ -80,9 +80,9 @@ type FriendsConnection { # The total number of friends totalCount: Int! # The edges for each of the character's friends. - edges: [FriendsEdge] + edges: [FriendsEdge!] # A list of the friends, as a convenience when edges are not needed. - friends: [Character] + friends: [Character!] # Information for paginating this connection pageInfo: PageInfo! } @@ -125,7 +125,7 @@ type Starship { # Length of the starship, along the longest axis length(unit: LengthUnit = METER): Float! # coordinates tracking this ship - history: [[Int]] + history: [[Int!]!]! } union SearchResult = Human | Droid | Starship scalar Time diff --git a/test/generated.go b/test/generated.go index bbc95e81f97..fa4a5ce878b 100644 --- a/test/generated.go +++ b/test/generated.go @@ -28,7 +28,7 @@ func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { type Resolvers interface { Element_child(ctx context.Context, obj *models.Element) (models.Element, error) Element_error(ctx context.Context, obj *models.Element) (bool, error) - Query_path(ctx context.Context) ([]models.Element, error) + Query_path(ctx context.Context) ([]*models.Element, error) Query_date(ctx context.Context, filter models.DateFilter) (bool, error) Query_viewer(ctx context.Context) (*models.Viewer, error) Query_jsonEncoding(ctx context.Context) (string, error) @@ -46,7 +46,7 @@ type ElementResolver interface { Error(ctx context.Context, obj *models.Element) (bool, error) } type QueryResolver interface { - Path(ctx context.Context) ([]models.Element, error) + Path(ctx context.Context) ([]*models.Element, error) Date(ctx context.Context, filter models.DateFilter) (bool, error) Viewer(ctx context.Context) (*models.Viewer, error) JsonEncoding(ctx context.Context) (string, error) @@ -67,7 +67,7 @@ func (s shortMapper) Element_error(ctx context.Context, obj *models.Element) (bo return s.r.Element().Error(ctx, obj) } -func (s shortMapper) Query_path(ctx context.Context) ([]models.Element, error) { +func (s shortMapper) Query_path(ctx context.Context) ([]*models.Element, error) { return s.r.Query().Path(ctx) } @@ -272,14 +272,17 @@ func (ec *executionContext) _Query_path(ctx context.Context, field graphql.Colle if resTmp == nil { return graphql.Null } - res := resTmp.([]models.Element) + res := resTmp.([]*models.Element) arr1 := graphql.Array{} for idx1 := range res { arr1 = append(arr1, func() graphql.Marshaler { rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - return ec._Element(ctx, field.Selections, &res[idx1]) + if res[idx1] == nil { + return graphql.Null + } + return ec._Element(ctx, field.Selections, res[idx1]) }()) } return arr1 diff --git a/test/resolvers_test.go b/test/resolvers_test.go index 3deebc7aeda..1716ab1474e 100644 --- a/test/resolvers_test.go +++ b/test/resolvers_test.go @@ -127,8 +127,8 @@ func (r *testResolvers) Query_date(ctx context.Context, filter models.DateFilter return r.queryDate(ctx, filter) } -func (r *testResolvers) Query_path(ctx context.Context) ([]models.Element, error) { - return []models.Element{{1}, {2}, {3}, {4}}, nil +func (r *testResolvers) Query_path(ctx context.Context) ([]*models.Element, error) { + return []*models.Element{{1}, {2}, {3}, {4}}, nil } func (r *testResolvers) Element_child(ctx context.Context, obj *models.Element) (models.Element, error) {