From 137152a4cf03a17799c24e4162d7cc53d1acbd8b Mon Sep 17 00:00:00 2001 From: MentatBot <160964065+MentatBot@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:04:59 +0000 Subject: [PATCH 1/4] Generate Mentat Scripts --- .mentat/precommit.sh | 3 +++ .mentat/setup.sh | 1 + 2 files changed, 4 insertions(+) create mode 100644 .mentat/precommit.sh create mode 100644 .mentat/setup.sh diff --git a/.mentat/precommit.sh b/.mentat/precommit.sh new file mode 100644 index 00000000..502ce6d5 --- /dev/null +++ b/.mentat/precommit.sh @@ -0,0 +1,3 @@ +go fmt ./... +go vet ./... +go test -v -cover -race ./... \ No newline at end of file diff --git a/.mentat/setup.sh b/.mentat/setup.sh new file mode 100644 index 00000000..bde77c6a --- /dev/null +++ b/.mentat/setup.sh @@ -0,0 +1 @@ +go mod download \ No newline at end of file From 50f0de6add19c85d3747cba0a98e9d381597464c Mon Sep 17 00:00:00 2001 From: MentatBot <160964065+MentatBot@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:05:05 +0000 Subject: [PATCH 2/4] Fix Mentat Scripts: go mod download MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Error output: ============================== Full log:[here ❌](https://mentat.ai/log/5ee95592-7ed7-469e-9206-2997ce407621) --- .mentat/precommit.sh | 2 +- .mentat/setup.sh | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.mentat/precommit.sh b/.mentat/precommit.sh index 502ce6d5..4b8b42d2 100644 --- a/.mentat/precommit.sh +++ b/.mentat/precommit.sh @@ -1,3 +1,3 @@ go fmt ./... go vet ./... -go test -v -cover -race ./... \ No newline at end of file +go test ./... \ No newline at end of file diff --git a/.mentat/setup.sh b/.mentat/setup.sh index bde77c6a..3c2a2bb1 100644 --- a/.mentat/setup.sh +++ b/.mentat/setup.sh @@ -1 +1,5 @@ +curl -L https://go.dev/dl/go1.13.15.linux-amd64.tar.gz -o go.tar.gz +rm -rf /usr/local/go +tar -C /usr/local -xzf go.tar.gz +export PATH=$PATH:/usr/local/go/bin go mod download \ No newline at end of file From 49ceee4429e37b37bb5a6927848ac07235f24ed6 Mon Sep 17 00:00:00 2001 From: MentatBot <160964065+MentatBot@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:05:14 +0000 Subject: [PATCH 3/4] Fix Mentat Scripts: go fmt ./... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Error output: ============================== Full log:[here ❌](https://mentat.ai/log/162dbe4a-6e08-4032-9aa5-3404a72dd700) --- .mentat/precommit.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.mentat/precommit.sh b/.mentat/precommit.sh index 4b8b42d2..b7a6c210 100644 --- a/.mentat/precommit.sh +++ b/.mentat/precommit.sh @@ -1,3 +1,4 @@ +export PATH=$PATH:/usr/local/go/bin go fmt ./... go vet ./... go test ./... \ No newline at end of file From 9a8900cc1669fdb333bdefd86c20c95f566398f8 Mon Sep 17 00:00:00 2001 From: MentatBot <160964065+MentatBot@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:05:36 +0000 Subject: [PATCH 4/4] Update gitignore --- .gitignore | 3 +- examples/sql-nullstring/main.go | 510 ++++++++++++++++---------------- 2 files changed, 257 insertions(+), 256 deletions(-) diff --git a/.gitignore b/.gitignore index 3d725761..c930ed3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store -.idea \ No newline at end of file +.idea +go.tar.gz diff --git a/examples/sql-nullstring/main.go b/examples/sql-nullstring/main.go index da54f4d6..03e2a71a 100644 --- a/examples/sql-nullstring/main.go +++ b/examples/sql-nullstring/main.go @@ -1,255 +1,255 @@ -package main - -import ( - "database/sql" - "encoding/json" - "fmt" - "github.com/graphql-go/graphql" - "github.com/graphql-go/graphql/language/ast" - "log" -) - -// NullString to be used in place of sql.NullString -type NullString struct { - sql.NullString -} - -// MarshalJSON from the json.Marshaler interface -func (v NullString) MarshalJSON() ([]byte, error) { - if v.Valid { - return json.Marshal(v.String) - } - return json.Marshal(nil) -} - -// UnmarshalJSON from the json.Unmarshaler interface -func (v *NullString) UnmarshalJSON(data []byte) error { - var x *string - if err := json.Unmarshal(data, &x); err != nil { - return err - } - if x != nil { - v.String = *x - v.Valid = true - } else { - v.Valid = false - } - return nil -} - -// NewNullString create a new null string. Empty string evaluates to an -// "invalid" NullString -func NewNullString(value string) *NullString { - var null NullString - if value != "" { - null.String = value - null.Valid = true - return &null - } - null.Valid = false - return &null -} - -// SerializeNullString serializes `NullString` to a string -func SerializeNullString(value interface{}) interface{} { - switch value := value.(type) { - case NullString: - return value.String - case *NullString: - v := *value - return v.String - default: - return nil - } -} - -// ParseNullString parses GraphQL variables from `string` to `CustomID` -func ParseNullString(value interface{}) interface{} { - switch value := value.(type) { - case string: - return NewNullString(value) - case *string: - return NewNullString(*value) - default: - return nil - } -} - -// ParseLiteralNullString parses GraphQL AST value to `NullString`. -func ParseLiteralNullString(valueAST ast.Value) interface{} { - switch valueAST := valueAST.(type) { - case *ast.StringValue: - return NewNullString(valueAST.Value) - default: - return nil - } -} - -// NullableString graphql *Scalar type based of NullString -var NullableString = graphql.NewScalar(graphql.ScalarConfig{ - Name: "NullableString", - Description: "The `NullableString` type repesents a nullable SQL string.", - Serialize: SerializeNullString, - ParseValue: ParseNullString, - ParseLiteral: ParseLiteralNullString, -}) - -/* -CREATE TABLE persons ( - favorite_dog TEXT -- is a nullable field - ); - -*/ - -// Person noqa -type Person struct { - Name string `json:"name"` - FavoriteDog *NullString `json:"favorite_dog"` // Some people don't like dogs ¯\_(ツ)_/¯ -} - -// PersonType noqa -var PersonType = graphql.NewObject(graphql.ObjectConfig{ - Name: "Person", - Fields: graphql.Fields{ - "name": &graphql.Field{ - Type: graphql.String, - }, - "favorite_dog": &graphql.Field{ - Type: NullableString, - }, - }, -}) - -func main() { - schema, err := graphql.NewSchema(graphql.SchemaConfig{ - Query: graphql.NewObject(graphql.ObjectConfig{ - Name: "Query", - Fields: graphql.Fields{ - "people": &graphql.Field{ - Type: graphql.NewList(PersonType), - Args: graphql.FieldConfigArgument{ - "favorite_dog": &graphql.ArgumentConfig{ - Type: NullableString, - }, - }, - Resolve: func(p graphql.ResolveParams) (interface{}, error) { - dog, dogOk := p.Args["favorite_dog"].(*NullString) - people := []Person{ - Person{Name: "Alice", FavoriteDog: NewNullString("Yorkshire Terrier")}, - // `Bob`'s favorite dog will be saved as null in the database - Person{Name: "Bob", FavoriteDog: NewNullString("")}, - Person{Name: "Chris", FavoriteDog: NewNullString("French Bulldog")}, - } - switch { - case dogOk: - log.Printf("favorite_dog from arguments: %+v", dog) - dogPeople := make([]Person, 0) - for _, p := range people { - if p.FavoriteDog.Valid { - if p.FavoriteDog.String == dog.String { - dogPeople = append(dogPeople, p) - } - } - } - return dogPeople, nil - default: - return people, nil - } - }, - }, - }, - }), - }) - if err != nil { - log.Fatal(err) - } - query := ` -query { - people { - name - favorite_dog - } -}` - queryWithArgument := ` -query { - people(favorite_dog: "Yorkshire Terrier") { - name - favorite_dog - } -}` - r1 := graphql.Do(graphql.Params{ - Schema: schema, - RequestString: query, - }) - r2 := graphql.Do(graphql.Params{ - Schema: schema, - RequestString: queryWithArgument, - }) - if len(r1.Errors) > 0 { - log.Fatal(r1) - } - if len(r2.Errors) > 0 { - log.Fatal(r1) - } - b1, err := json.MarshalIndent(r1, "", " ") - if err != nil { - log.Fatal(err) - } - b2, err := json.MarshalIndent(r2, "", " ") - if err != nil { - log.Fatal(err) - - } - fmt.Printf("\nQuery: %+v\n", string(query)) - fmt.Printf("\nResult: %+v\n", string(b1)) - fmt.Printf("\nQuery (with arguments): %+v\n", string(queryWithArgument)) - fmt.Printf("\nResult (with arguments): %+v\n", string(b2)) -} - -/* Output: -Query: -query { - people { - name - favorite_dog - } -} - -Result: { - "data": { - "people": [ - { - "favorite_dog": "Yorkshire Terrier", - "name": "Alice" - }, - { - "favorite_dog": "", - "name": "Bob" - }, - { - "favorite_dog": "French Bulldog", - "name": "Chris" - } - ] - } -} - -Query (with arguments): -query { - people(favorite_dog: "Yorkshire Terrier") { - name - favorite_dog - } -} - -Result (with arguments): { - "data": { - "people": [ - { - "favorite_dog": "Yorkshire Terrier", - "name": "Alice" - } - ] - } -} -*/ +package main + +import ( + "database/sql" + "encoding/json" + "fmt" + "github.com/graphql-go/graphql" + "github.com/graphql-go/graphql/language/ast" + "log" +) + +// NullString to be used in place of sql.NullString +type NullString struct { + sql.NullString +} + +// MarshalJSON from the json.Marshaler interface +func (v NullString) MarshalJSON() ([]byte, error) { + if v.Valid { + return json.Marshal(v.String) + } + return json.Marshal(nil) +} + +// UnmarshalJSON from the json.Unmarshaler interface +func (v *NullString) UnmarshalJSON(data []byte) error { + var x *string + if err := json.Unmarshal(data, &x); err != nil { + return err + } + if x != nil { + v.String = *x + v.Valid = true + } else { + v.Valid = false + } + return nil +} + +// NewNullString create a new null string. Empty string evaluates to an +// "invalid" NullString +func NewNullString(value string) *NullString { + var null NullString + if value != "" { + null.String = value + null.Valid = true + return &null + } + null.Valid = false + return &null +} + +// SerializeNullString serializes `NullString` to a string +func SerializeNullString(value interface{}) interface{} { + switch value := value.(type) { + case NullString: + return value.String + case *NullString: + v := *value + return v.String + default: + return nil + } +} + +// ParseNullString parses GraphQL variables from `string` to `CustomID` +func ParseNullString(value interface{}) interface{} { + switch value := value.(type) { + case string: + return NewNullString(value) + case *string: + return NewNullString(*value) + default: + return nil + } +} + +// ParseLiteralNullString parses GraphQL AST value to `NullString`. +func ParseLiteralNullString(valueAST ast.Value) interface{} { + switch valueAST := valueAST.(type) { + case *ast.StringValue: + return NewNullString(valueAST.Value) + default: + return nil + } +} + +// NullableString graphql *Scalar type based of NullString +var NullableString = graphql.NewScalar(graphql.ScalarConfig{ + Name: "NullableString", + Description: "The `NullableString` type repesents a nullable SQL string.", + Serialize: SerializeNullString, + ParseValue: ParseNullString, + ParseLiteral: ParseLiteralNullString, +}) + +/* +CREATE TABLE persons ( + favorite_dog TEXT -- is a nullable field + ); + +*/ + +// Person noqa +type Person struct { + Name string `json:"name"` + FavoriteDog *NullString `json:"favorite_dog"` // Some people don't like dogs ¯\_(ツ)_/¯ +} + +// PersonType noqa +var PersonType = graphql.NewObject(graphql.ObjectConfig{ + Name: "Person", + Fields: graphql.Fields{ + "name": &graphql.Field{ + Type: graphql.String, + }, + "favorite_dog": &graphql.Field{ + Type: NullableString, + }, + }, +}) + +func main() { + schema, err := graphql.NewSchema(graphql.SchemaConfig{ + Query: graphql.NewObject(graphql.ObjectConfig{ + Name: "Query", + Fields: graphql.Fields{ + "people": &graphql.Field{ + Type: graphql.NewList(PersonType), + Args: graphql.FieldConfigArgument{ + "favorite_dog": &graphql.ArgumentConfig{ + Type: NullableString, + }, + }, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + dog, dogOk := p.Args["favorite_dog"].(*NullString) + people := []Person{ + Person{Name: "Alice", FavoriteDog: NewNullString("Yorkshire Terrier")}, + // `Bob`'s favorite dog will be saved as null in the database + Person{Name: "Bob", FavoriteDog: NewNullString("")}, + Person{Name: "Chris", FavoriteDog: NewNullString("French Bulldog")}, + } + switch { + case dogOk: + log.Printf("favorite_dog from arguments: %+v", dog) + dogPeople := make([]Person, 0) + for _, p := range people { + if p.FavoriteDog.Valid { + if p.FavoriteDog.String == dog.String { + dogPeople = append(dogPeople, p) + } + } + } + return dogPeople, nil + default: + return people, nil + } + }, + }, + }, + }), + }) + if err != nil { + log.Fatal(err) + } + query := ` +query { + people { + name + favorite_dog + } +}` + queryWithArgument := ` +query { + people(favorite_dog: "Yorkshire Terrier") { + name + favorite_dog + } +}` + r1 := graphql.Do(graphql.Params{ + Schema: schema, + RequestString: query, + }) + r2 := graphql.Do(graphql.Params{ + Schema: schema, + RequestString: queryWithArgument, + }) + if len(r1.Errors) > 0 { + log.Fatal(r1) + } + if len(r2.Errors) > 0 { + log.Fatal(r1) + } + b1, err := json.MarshalIndent(r1, "", " ") + if err != nil { + log.Fatal(err) + } + b2, err := json.MarshalIndent(r2, "", " ") + if err != nil { + log.Fatal(err) + + } + fmt.Printf("\nQuery: %+v\n", string(query)) + fmt.Printf("\nResult: %+v\n", string(b1)) + fmt.Printf("\nQuery (with arguments): %+v\n", string(queryWithArgument)) + fmt.Printf("\nResult (with arguments): %+v\n", string(b2)) +} + +/* Output: +Query: +query { + people { + name + favorite_dog + } +} + +Result: { + "data": { + "people": [ + { + "favorite_dog": "Yorkshire Terrier", + "name": "Alice" + }, + { + "favorite_dog": "", + "name": "Bob" + }, + { + "favorite_dog": "French Bulldog", + "name": "Chris" + } + ] + } +} + +Query (with arguments): +query { + people(favorite_dog: "Yorkshire Terrier") { + name + favorite_dog + } +} + +Result (with arguments): { + "data": { + "people": [ + { + "favorite_dog": "Yorkshire Terrier", + "name": "Alice" + } + ] + } +} +*/