Skip to content

Commit 538350a

Browse files
committed
made a few changes and added Point type
1 parent 73255d7 commit 538350a

File tree

7 files changed

+103
-63
lines changed

7 files changed

+103
-63
lines changed

example/graphqldev/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func run() error {
5959
*/
6060
var q struct {
6161
Hero struct {
62-
ID graphql.GqlID
62+
ID graphql.GqlString
6363
Name graphql.GqlString
6464
}
6565
Character struct {

example/subscription/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func run() error {
5050
*/
5151
var sub struct {
5252
User struct {
53-
ID graphql.GqlID
53+
ID graphql.GqlString
5454
Name graphql.GqlString
5555
} `graphql:"users(limit: $limit, order_by: { id: desc })"`
5656
}

example/test/main.go

+39-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ func main() {
1414

1515
var query struct {
1616
QueryUser []struct {
17-
ID graphql.GqlID
1817
Username graphql.GqlString
1918
Name graphql.GqlString
2019
Note graphql.GqlString
@@ -33,7 +32,7 @@ func main() {
3332
UserShared: UserShared{
3433
Username: graphql.NewStringStruct("abc"),
3534
Name: graphql.NewStringStruct("ABC"),
36-
Note: graphql.NewStringStruct("note ABC"),
35+
// Note: graphql.NewStringStruct("note ABC"),
3736
},
3837
Password: graphql.NewStringStruct("password1"),
3938
},
@@ -46,14 +45,42 @@ func main() {
4645
},
4746
}
4847

48+
// var mutation struct {
49+
// AddUser struct {
50+
// User []User
51+
// } `graphql:"addUser(input: $input)"`
52+
// }
53+
54+
// vars := map[string]interface{}{
55+
// "input": input,
56+
// }
57+
58+
// err = client.Mutate(context.Background(), &mutation, vars)
59+
// if err != nil {
60+
// // Handle error.
61+
// log.Fatalln(err)
62+
// }
63+
64+
// fmt.Printf("%+v\n", mutation.AddUser)
65+
66+
saveTest(client, AddUserInputContainer{input})
67+
}
68+
69+
type InterfaceTest interface {
70+
GetList() interface{}
71+
}
72+
73+
func saveTest(client *graphql.Client, input InterfaceTest) {
74+
var err error
75+
4976
var mutation struct {
5077
AddUser struct {
5178
User []User
5279
} `graphql:"addUser(input: $input)"`
5380
}
5481

5582
vars := map[string]interface{}{
56-
"input": input,
83+
"input": input.GetList(),
5784
}
5885

5986
err = client.Mutate(context.Background(), &mutation, vars)
@@ -70,8 +97,16 @@ type AddUserInput struct {
7097
Password graphql.GqlString `json:"password,omitempty"`
7198
}
7299

100+
type AddUserInputContainer struct {
101+
List interface{}
102+
}
103+
104+
func (aui AddUserInputContainer) GetList() interface{} {
105+
return aui.List
106+
}
107+
73108
type User struct {
74-
ID graphql.GqlID
109+
ID *graphql.GqlString
75110
UserShared
76111
}
77112

graphql_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ func TestClient_Query_partialDataWithErrorResponse(t *testing.T) {
4343

4444
var q struct {
4545
Node1 *struct {
46-
ID *graphql.GqlID
46+
ID *graphql.GqlString
4747
} `graphql:"node1: node(id: \"MDEyOklzc3VlQ29tbWVudDE2OTQwNzk0Ng==\")"`
4848
Node2 *struct {
49-
ID *graphql.GqlID
49+
ID *graphql.GqlString
5050
} `graphql:"node2: node(id: \"NotExist\")"`
5151
}
5252

@@ -63,7 +63,7 @@ func TestClient_Query_partialDataWithErrorResponse(t *testing.T) {
6363
t.Errorf("got error: %v, want: %v", got, want)
6464
}
6565

66-
if q.Node1 == nil || q.Node1.ID != graphql.NewID("MDEyOklzc3VlQ29tbWVudDE2OTQwNzk0Ng==") {
66+
if q.Node1 == nil || q.Node1.ID != graphql.NewString("MDEyOklzc3VlQ29tbWVudDE2OTQwNzk0Ng==") {
6767
t.Errorf("got wrong q.Node1: %v", q.Node1)
6868
}
6969
if q.Node2 != nil {

query.go

+36-20
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package graphql
33
import (
44
"bytes"
55
"encoding/json"
6+
"fmt"
67
"io"
78
"reflect"
89
"sort"
@@ -13,7 +14,7 @@ import (
1314
func constructQuery(v interface{}, variables map[string]interface{}, name string) string {
1415
query := query(v)
1516
if len(variables) > 0 {
16-
return "query " + name + "(" + queryArguments(variables) + ")" + query
17+
return "query " + name + "(" + queryArguments(variables, false) + ")" + query
1718
}
1819

1920
if name != "" {
@@ -25,7 +26,7 @@ func constructQuery(v interface{}, variables map[string]interface{}, name string
2526
func constructMutation(v interface{}, variables map[string]interface{}, name string) string {
2627
query := query(v)
2728
if len(variables) > 0 {
28-
return "mutation " + name + "(" + queryArguments(variables) + ")" + query
29+
return "mutation " + name + "(" + queryArguments(variables, true) + ")" + query
2930
}
3031
if name != "" {
3132
return "mutation " + name + query
@@ -36,7 +37,7 @@ func constructMutation(v interface{}, variables map[string]interface{}, name str
3637
func constructSubscription(v interface{}, variables map[string]interface{}, name string) string {
3738
query := query(v)
3839
if len(variables) > 0 {
39-
return "subscription " + name + "(" + queryArguments(variables) + ")" + query
40+
return "subscription " + name + "(" + queryArguments(variables, false) + ")" + query
4041
}
4142
if name != "" {
4243
return "subscription " + name + query
@@ -47,7 +48,7 @@ func constructSubscription(v interface{}, variables map[string]interface{}, name
4748
// queryArguments constructs a minified arguments string for variables.
4849
//
4950
// E.g., map[string]interface{}{"a": Int(123), "b": NewBoolean(true)} -> "$a:Int!$b:Boolean".
50-
func queryArguments(variables map[string]interface{}) string {
51+
func queryArguments(variables map[string]interface{}, isMutation bool) string {
5152
// Sort keys in order to produce deterministic output for testing purposes.
5253
// TODO: If tests can be made to work with non-deterministic output, then no need to sort.
5354
keys := make([]string, 0, len(variables))
@@ -61,7 +62,7 @@ func queryArguments(variables map[string]interface{}) string {
6162
io.WriteString(&buf, "$")
6263
io.WriteString(&buf, k)
6364
io.WriteString(&buf, ":")
64-
writeArgumentType(&buf, reflect.TypeOf(variables[k]), true)
65+
writeArgumentType(&buf, reflect.TypeOf(variables[k]), true, isMutation)
6566
// Don't insert a comma here.
6667
// Commas in GraphQL are insignificant, and we want minified output.
6768
// See https://facebook.github.io/graphql/October2016/#sec-Insignificant-Commas.
@@ -72,18 +73,21 @@ func queryArguments(variables map[string]interface{}) string {
7273
// writeArgumentType writes a minified GraphQL type for t to w.
7374
// value indicates whether t is a value (required) type or pointer (optional) type.
7475
// If value is true, then "!" is written at the end of t.
75-
func writeArgumentType(w io.Writer, t reflect.Type, value bool) {
76-
if t.Kind() == reflect.Ptr {
76+
func writeArgumentType(w io.Writer, t reflect.Type, value, isMutation bool) {
77+
if t.Kind() == reflect.Ptr && !isMutation {
7778
// Pointer is an optional type, so no "!" at the end of the pointer's underlying type.
78-
writeArgumentType(w, t.Elem(), false)
79+
writeArgumentType(w, t.Elem(), false, isMutation)
80+
return
81+
} else if t.Kind() == reflect.Ptr {
82+
writeArgumentType(w, t.Elem(), true, isMutation)
7983
return
8084
}
8185

8286
switch t.Kind() {
8387
case reflect.Slice, reflect.Array:
8488
// List. E.g., "[Int]".
8589
io.WriteString(w, "[")
86-
writeArgumentType(w, t.Elem(), true)
90+
writeArgumentType(w, t.Elem(), true, isMutation)
8791
io.WriteString(w, "]")
8892
default:
8993
// Named type. E.g., "Int".
@@ -117,16 +121,19 @@ func writeArgumentType(w io.Writer, t reflect.Type, value bool) {
117121
// E.g., struct{Foo Int, BarBaz *Boolean} -> "{foo,barBaz}".
118122
func query(v interface{}) string {
119123
var buf bytes.Buffer
120-
writeQuery(&buf, reflect.TypeOf(v), false)
124+
seen := make(map[string]struct{})
125+
writeQuery(&buf, reflect.TypeOf(v), false, "")
126+
fmt.Println(seen)
121127
return buf.String()
122128
}
123129

124130
// writeQuery writes a minified query for t to w.
125131
// If inline is true, the struct fields of t are inlined into parent struct.
126-
func writeQuery(w io.Writer, t reflect.Type, inline bool) {
132+
// Seen is used to stop infinite loops
133+
func writeQuery(w io.Writer, t reflect.Type, inline bool, inverseName string) {
127134
switch t.Kind() {
128135
case reflect.Ptr, reflect.Slice:
129-
writeQuery(w, t.Elem(), false)
136+
writeQuery(w, t.Elem(), false, inverseName)
130137
case reflect.Struct:
131138
// If the type implements json.Unmarshaler, it's a scalar. Don't expand it.
132139
if reflect.PtrTo(t).Implements(jsonUnmarshaler) {
@@ -136,20 +143,29 @@ func writeQuery(w io.Writer, t reflect.Type, inline bool) {
136143
io.WriteString(w, "{")
137144
}
138145
for i := 0; i < t.NumField(); i++ {
146+
f := t.Field(i)
147+
value, ok := f.Tag.Lookup("graphql")
148+
if value == "-" {
149+
//skip (this is 'omit')
150+
continue
151+
} else if value == "" {
152+
value = ident.ParseMixedCaps(f.Name).ToLowerCamelCase()
153+
}
154+
if inverseName == value {
155+
continue //Don't allow recursion
156+
}
157+
thisInverseName, _ := f.Tag.Lookup("hasInverse")
158+
// if thisInverseName != "" {
159+
// fmt.Println()
160+
// }
139161
if i != 0 {
140162
io.WriteString(w, ",")
141163
}
142-
f := t.Field(i)
143-
value, ok := f.Tag.Lookup("graphql")
144164
inlineField := f.Anonymous && !ok
145165
if !inlineField {
146-
if ok {
147-
io.WriteString(w, value)
148-
} else {
149-
io.WriteString(w, ident.ParseMixedCaps(f.Name).ToLowerCamelCase())
150-
}
166+
io.WriteString(w, value)
151167
}
152-
writeQuery(w, f.Type, inlineField)
168+
writeQuery(w, f.Type, inlineField, thisInverseName)
153169
}
154170
if !inline {
155171
io.WriteString(w, "}")

query_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func TestConstructQuery(t *testing.T) {
1818
Viewer struct {
1919
Login GqlString
2020
CreatedAt GqlTime
21-
ID GqlID
21+
ID GqlString
2222
DatabaseID GqlInt64
2323
}
2424
RateLimit struct {
@@ -259,7 +259,7 @@ func TestConstructMutation(t *testing.T) {
259259
}{},
260260
inVariables: map[string]interface{}{
261261
"input": AddReactionInput{
262-
SubjectID: NewID("MDU6SXNzdWUyMzE1MjcyNzk="),
262+
SubjectID: NewString("MDU6SXNzdWUyMzE1MjcyNzk="),
263263
Content: ReactionContentThumbsUp,
264264
},
265265
},
@@ -286,7 +286,7 @@ func TestConstructSubscription(t *testing.T) {
286286
Viewer struct {
287287
Login GqlString
288288
CreatedAt GqlTime
289-
ID GqlID
289+
ID GqlString
290290
DatabaseID GqlInt64
291291
}
292292
RateLimit struct {
@@ -542,16 +542,16 @@ func TestQueryArguments(t *testing.T) {
542542
want: "$id:ID!",
543543
},
544544
{
545-
in: map[string]interface{}{"ids": []*GqlID{NewID("someID"), NewID("anotherID")}},
545+
in: map[string]interface{}{"ids": []*GqlString{NewString("someID"), NewString("anotherID")}},
546546
want: `$ids:[ID!]!`,
547547
},
548548
{
549-
in: map[string]interface{}{"ids": &[]*GqlID{NewID("someID"), NewID("anotherID")}},
549+
in: map[string]interface{}{"ids": &[]*GqlString{NewString("someID"), NewString("anotherID")}},
550550
want: `$ids:[ID!]`,
551551
},
552552
}
553553
for i, tc := range tests {
554-
got := queryArguments(tc.in)
554+
got := queryArguments(tc.in, false) //todo:mm: not sure if I should have made this false
555555
if got != tc.want {
556556
t.Errorf("test case %d:\n got: %q\nwant: %q", i, got, tc.want)
557557
}
@@ -594,7 +594,7 @@ const (
594594
// AddReactionInput is an autogenerated input type of AddReaction.
595595
type AddReactionInput struct {
596596
// The Node ID of the subject to modify. (Required.)
597-
SubjectID *GqlID `json:"subjectId"`
597+
SubjectID *GqlString `json:"subjectId"`
598598
// The name of the emoji to react with. (Required.)
599599
Content ReactionContent `json:"content"`
600600

scalar.go

+16-27
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,6 @@ type Query struct {
99
Data interface{} `graphql:"data"`
1010
}
1111

12-
type GqlID struct {
13-
ID string `json:"id,omitempty"`
14-
}
15-
16-
func NewIDStruct(x string) GqlID {
17-
nw := NewID(x)
18-
return *nw
19-
}
20-
21-
func NewID(x string) *GqlID { return &GqlID{x} }
22-
23-
func (id *GqlID) MarshalJSON() ([]byte, error) {
24-
return json.Marshal(id.ID)
25-
}
26-
27-
func (id *GqlID) UnmarshalJSON(data []byte) error {
28-
var s *string
29-
if err := json.Unmarshal(data, &s); err != nil {
30-
return err
31-
}
32-
if s != nil {
33-
id.ID = *s
34-
}
35-
36-
return nil
37-
}
38-
3912
type GqlBool struct {
4013
Bool bool
4114
Valid bool // Valid is true if Bool is not NULL
@@ -200,3 +173,19 @@ func (nt *GqlTime) UnmarshalJSON(data []byte) error {
200173
}
201174
return nil
202175
}
176+
177+
type GqlPoint struct {
178+
//this does not need an ID as it is a scalar type in GraphQL
179+
180+
Latitude *GqlFloat64 `json:"latitude,omitempty"`
181+
Longitude *GqlFloat64 `json:"longitude,omitempty"`
182+
}
183+
184+
func NewPointStruct(lat, lng float64) GqlPoint {
185+
nw := NewPoint(lat, lng)
186+
return *nw
187+
}
188+
189+
func NewPoint(lat, lng float64) *GqlPoint {
190+
return &GqlPoint{Latitude: NewFloat64(lat), Longitude: NewFloat64(lng)}
191+
}

0 commit comments

Comments
 (0)