Handle omitempty correctly for slices
We were generating broken code; fixes #43. Also fixes a bug where
applying omitempty to the entire query was broken by e597cac74c.
This commit is contained in:
@@ -43,7 +43,9 @@ type GenqlientDirective struct {
|
|||||||
pos *ast.Position
|
pos *ast.Position
|
||||||
|
|
||||||
// If set, this argument will be omitted if it's equal to its Go zero
|
// If set, this argument will be omitted if it's equal to its Go zero
|
||||||
// value. For example, given the following query:
|
// value, or is an empty slice.
|
||||||
|
//
|
||||||
|
// For example, given the following query:
|
||||||
// # @genqlient(omitempty: true)
|
// # @genqlient(omitempty: true)
|
||||||
// query MyQuery(arg: String) { ... }
|
// query MyQuery(arg: String) { ... }
|
||||||
// genqlient will generate a function
|
// genqlient will generate a function
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ type argument struct {
|
|||||||
GoName string
|
GoName string
|
||||||
GoType string
|
GoType string
|
||||||
GraphQLName string
|
GraphQLName string
|
||||||
|
IsSlice bool
|
||||||
Options *GenqlientDirective
|
Options *GenqlientDirective
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +128,8 @@ func (g *generator) getArgument(
|
|||||||
GraphQLName: graphQLName,
|
GraphQLName: graphQLName,
|
||||||
GoName: lowerFirst(graphQLName),
|
GoName: lowerFirst(graphQLName),
|
||||||
GoType: goType,
|
GoType: goType,
|
||||||
Options: directive,
|
IsSlice: arg.Type.Elem != nil,
|
||||||
|
Options: operationDirective.merge(directive),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,14 @@ func {{.Name}}(
|
|||||||
}
|
}
|
||||||
{{range .Args -}}
|
{{range .Args -}}
|
||||||
{{if .Options.GetOmitempty -}}
|
{{if .Options.GetOmitempty -}}
|
||||||
|
{{if .IsSlice -}}
|
||||||
|
if len({{.GoName}}) > 0 {
|
||||||
|
{{else -}}
|
||||||
{{/* zero_{{.GoType}} would be a better name, but {{.GoType}} would require
|
{{/* zero_{{.GoType}} would be a better name, but {{.GoType}} would require
|
||||||
munging since it might be, say, `time.Time`. */}}
|
munging since it might be, say, `time.Time`. */}}
|
||||||
var zero_{{.GoName}} {{.GoType}}
|
var zero_{{.GoName}} {{.GoType}}
|
||||||
if {{.GoName}} != zero_{{.GoName}} {
|
if {{.GoName}} != zero_{{.GoName}} {
|
||||||
|
{{end -}}
|
||||||
variables["{{.GraphQLName}}"] = {{.GoName}}
|
variables["{{.GraphQLName}}"] = {{.GoName}}
|
||||||
}
|
}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
+3
-3
@@ -1,14 +1,14 @@
|
|||||||
# @genqlient(omitempty: true)
|
# @genqlient(omitempty: true)
|
||||||
query OmitEmptyQuery(
|
query OmitEmptyQuery(
|
||||||
$query: UserQueryInput,
|
$query: UserQueryInput,
|
||||||
|
$queries: [UserQueryInput],
|
||||||
$dt: DateTime,
|
$dt: DateTime,
|
||||||
$tz: String,
|
$tz: String,
|
||||||
# @genqlient(omitempty: false)
|
# @genqlient(omitempty: false)
|
||||||
$tzNoOmitEmpty: String,
|
$tzNoOmitEmpty: String,
|
||||||
) {
|
) {
|
||||||
user(query: $query) {
|
user(query: $query) { id }
|
||||||
id
|
users(query: $queries) { id }
|
||||||
}
|
|
||||||
maybeConvert(dt: $dt, tz: $tz)
|
maybeConvert(dt: $dt, tz: $tz)
|
||||||
convert2: maybeConvert(dt: $dt, tz: $tzNoOmitEmpty)
|
convert2: maybeConvert(dt: $dt, tz: $tzNoOmitEmpty)
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-7
@@ -15,9 +15,10 @@ type OmitEmptyQueryResponse struct {
|
|||||||
//
|
//
|
||||||
// See UserQueryInput for what stuff is supported.
|
// See UserQueryInput for what stuff is supported.
|
||||||
// If query is null, returns the current user.
|
// If query is null, returns the current user.
|
||||||
User OmitEmptyQueryUser `json:"user"`
|
User OmitEmptyQueryUser `json:"user"`
|
||||||
MaybeConvert time.Time `json:"maybeConvert"`
|
Users OmitEmptyQueryUsersUser `json:"users"`
|
||||||
Convert2 time.Time `json:"convert2"`
|
MaybeConvert time.Time `json:"maybeConvert"`
|
||||||
|
Convert2 time.Time `json:"convert2"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OmitEmptyQueryUser includes the requested fields of the GraphQL type User.
|
// OmitEmptyQueryUser includes the requested fields of the GraphQL type User.
|
||||||
@@ -31,6 +32,17 @@ type OmitEmptyQueryUser struct {
|
|||||||
Id mypkg.ID `json:"id"`
|
Id mypkg.ID `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OmitEmptyQueryUsersUser includes the requested fields of the GraphQL type User.
|
||||||
|
// The GraphQL type's documentation follows.
|
||||||
|
//
|
||||||
|
// A User is a user!
|
||||||
|
type OmitEmptyQueryUsersUser struct {
|
||||||
|
// id is the user's ID.
|
||||||
|
//
|
||||||
|
// It is stable, unique, and opaque, like all good IDs.
|
||||||
|
Id mypkg.ID `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
// Role is a type a user may have.
|
// Role is a type a user may have.
|
||||||
type Role string
|
type Role string
|
||||||
|
|
||||||
@@ -62,26 +74,46 @@ type UserQueryInput struct {
|
|||||||
func OmitEmptyQuery(
|
func OmitEmptyQuery(
|
||||||
client graphql.Client,
|
client graphql.Client,
|
||||||
query UserQueryInput,
|
query UserQueryInput,
|
||||||
|
queries []UserQueryInput,
|
||||||
dt time.Time,
|
dt time.Time,
|
||||||
tz string,
|
tz string,
|
||||||
tzNoOmitEmpty string,
|
tzNoOmitEmpty string,
|
||||||
) (*OmitEmptyQueryResponse, error) {
|
) (*OmitEmptyQueryResponse, error) {
|
||||||
variables := map[string]interface{}{
|
variables := map[string]interface{}{
|
||||||
"query": query,
|
|
||||||
"dt": dt,
|
|
||||||
"tz": tz,
|
|
||||||
"tzNoOmitEmpty": tzNoOmitEmpty,
|
"tzNoOmitEmpty": tzNoOmitEmpty,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var zero_query UserQueryInput
|
||||||
|
if query != zero_query {
|
||||||
|
variables["query"] = query
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(queries) > 0 {
|
||||||
|
variables["queries"] = queries
|
||||||
|
}
|
||||||
|
|
||||||
|
var zero_dt time.Time
|
||||||
|
if dt != zero_dt {
|
||||||
|
variables["dt"] = dt
|
||||||
|
}
|
||||||
|
|
||||||
|
var zero_tz string
|
||||||
|
if tz != zero_tz {
|
||||||
|
variables["tz"] = tz
|
||||||
|
}
|
||||||
|
|
||||||
var retval OmitEmptyQueryResponse
|
var retval OmitEmptyQueryResponse
|
||||||
err := client.MakeRequest(
|
err := client.MakeRequest(
|
||||||
nil,
|
nil,
|
||||||
"OmitEmptyQuery",
|
"OmitEmptyQuery",
|
||||||
`
|
`
|
||||||
query OmitEmptyQuery ($query: UserQueryInput, $dt: DateTime, $tz: String, $tzNoOmitEmpty: String) {
|
query OmitEmptyQuery ($query: UserQueryInput, $queries: [UserQueryInput], $dt: DateTime, $tz: String, $tzNoOmitEmpty: String) {
|
||||||
user(query: $query) {
|
user(query: $query) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
users(query: $queries) {
|
||||||
|
id
|
||||||
|
}
|
||||||
maybeConvert(dt: $dt, tz: $tz)
|
maybeConvert(dt: $dt, tz: $tz)
|
||||||
convert2: maybeConvert(dt: $dt, tz: $tzNoOmitEmpty)
|
convert2: maybeConvert(dt: $dt, tz: $tzNoOmitEmpty)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"operations": [
|
"operations": [
|
||||||
{
|
{
|
||||||
"operationName": "OmitEmptyQuery",
|
"operationName": "OmitEmptyQuery",
|
||||||
"query": "\nquery OmitEmptyQuery ($query: UserQueryInput, $dt: DateTime, $tz: String, $tzNoOmitEmpty: String) {\n\tuser(query: $query) {\n\t\tid\n\t}\n\tmaybeConvert(dt: $dt, tz: $tz)\n\tconvert2: maybeConvert(dt: $dt, tz: $tzNoOmitEmpty)\n}\n",
|
"query": "\nquery OmitEmptyQuery ($query: UserQueryInput, $queries: [UserQueryInput], $dt: DateTime, $tz: String, $tzNoOmitEmpty: String) {\n\tuser(query: $query) {\n\t\tid\n\t}\n\tusers(query: $queries) {\n\t\tid\n\t}\n\tmaybeConvert(dt: $dt, tz: $tz)\n\tconvert2: maybeConvert(dt: $dt, tz: $tzNoOmitEmpty)\n}\n",
|
||||||
"sourceLocation": "testdata/queries/Omitempty.graphql"
|
"sourceLocation": "testdata/queries/Omitempty.graphql"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
+2
@@ -99,6 +99,8 @@ type Query {
|
|||||||
"""
|
"""
|
||||||
user(query: UserQueryInput): User
|
user(query: UserQueryInput): User
|
||||||
|
|
||||||
|
users(query: [UserQueryInput]): User
|
||||||
|
|
||||||
"""usersWithRole looks a user up by role."""
|
"""usersWithRole looks a user up by role."""
|
||||||
usersWithRole(role: Role!): [User!]!
|
usersWithRole(role: Role!): [User!]!
|
||||||
root: Topic!
|
root: Topic!
|
||||||
|
|||||||
Reference in New Issue
Block a user