Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(GraphQL): This PR adds parameterised cascade in graphql. #6251

Merged
merged 24 commits into from
Aug 26, 2020
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f288df7
Parameterized cascades
JatinDev543 Aug 19, 2020
7917951
Merge branch 'master' of github.com:dgraph-io/dgraph into jatin/graph…
JatinDev543 Aug 19, 2020
ba35dd6
added unit tests and validation for cascade directive
JatinDev543 Aug 20, 2020
2787474
added e2e tests
JatinDev543 Aug 20, 2020
db9f300
clean code
JatinDev543 Aug 21, 2020
93913ee
resolved comments and modified code
JatinDev543 Aug 23, 2020
d1b1abb
resolved comments and modified code
JatinDev543 Aug 23, 2020
284196c
fix id error and modified tests
JatinDev543 Aug 24, 2020
5faeb57
Merge branch 'master' of github.com:dgraph-io/dgraph into jatin/graph…
JatinDev543 Aug 24, 2020
437ba00
fix id error and modified tests
JatinDev543 Aug 24, 2020
af449c6
cleaned code a bit
JatinDev543 Aug 24, 2020
a4110af
added missing cascade directive
JatinDev543 Aug 24, 2020
d2eea32
fixed Json formatting
JatinDev543 Aug 25, 2020
c0228ad
fix query formatting
JatinDev543 Aug 25, 2020
37e856e
added some spaces
JatinDev543 Aug 25, 2020
d8a779e
fixed minor formatting
JatinDev543 Aug 25, 2020
aa696c4
fixed formatting
JatinDev543 Aug 25, 2020
dcbf1f2
removed extra spaces.
JatinDev543 Aug 25, 2020
d36d21c
added unit tests for cascade on interfaces and implementationy
JatinDev543 Aug 25, 2020
0d3e179
fixed bug by removing if statement and modified tests to check it
JatinDev543 Aug 25, 2020
281a034
fixed antipattern error
JatinDev543 Aug 25, 2020
faca98d
fixed bug when there is no ID field with cascade
JatinDev543 Aug 25, 2020
6d3b461
added unit test when cascade argument at outer level , not present at…
JatinDev543 Aug 25, 2020
17db61d
changed varaiable name
JatinDev543 Aug 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions graphql/dgraph/graphquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ func writeQuery(b *strings.Builder, query *gql.GraphQuery, prefix string) {
if len(query.Cascade) != 0 {
if query.Cascade[0] == "__all__" {
x.Check2(b.WriteString(" @cascade"))
} else {
x.Check2(b.WriteString(" @cascade("))
x.Check2(b.WriteString(strings.Join(query.Cascade, ", ")))
x.Check2(b.WriteRune(')'))
}
}

Expand Down
32 changes: 31 additions & 1 deletion graphql/e2e/common/error_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
[ { "message": "must be defined",
"path": [ "variable", "filter"] } ]
-
name: "subscription on type without @withSubscription directive should retur error"
name: "subscription on type without @withSubscription directive should return error"
gqlrequest: |
subscription {
getAuthor(id: "0x1") { name }
Expand All @@ -100,3 +100,33 @@
[ { "message": "Cannot query field \"getAuthor\" on type \"Subscription\".",
"locations": [ { "line": 2, "column": 3 } ] } ]

-
name: "@cascade only accepts those fields as a argument, which are present in given type "
gqlrequest: |
query {
queryAuthor @cascade(fields:["title"]){
dob
reputation
}
}
gqlvariables:
{ }
errors:
[ { "message": "Field `title` is not present in type `Author`. You can only use fields which are in type `Author`",
} ]

-
name: "@cascade only accepts numUids or given type name as arguments for add or update payload "
gqlrequest: |
mutation {
addAuthor(input:[{name:"jatin"}]) @cascade(fields:["name"]) {
author {
name
}
}
}
gqlvariables:
{ }
errors:
[ { "message": "Field `name` is not present in type `AddAuthorPayload`. You can only use fields which are in type `AddAuthorPayload`",
} ]
166 changes: 163 additions & 3 deletions graphql/e2e/common/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -1743,7 +1743,7 @@ func DgraphDirectiveWithSpecialCharacters(t *testing.T) {
}

func queryWithCascade(t *testing.T) {
// for testing @cascade with get by ID and filter queries, also for testing @cascade on field
// for testing normal and parameterized @cascade with get by ID and filter queries on multiple levels
authors := addMultipleAuthorFromRef(t, []*author{
{
Name: "George",
Expand All @@ -1752,15 +1752,20 @@ func queryWithCascade(t *testing.T) {
}, {
Name: "Jerry",
Reputation: 4.6,
Country: &country{Name: "outer Galaxy2"},
Posts: []*post{{Title: "Outside", Tags: []string{}}},
}, {
Name: "Kramer",
Posts: []*post{{Title: "Ha! Cosmo Kramer", Text: "Giddy up!", Tags: []string{}}},
Name: "Kramer",
Country: &country{Name: "outer space2"},
Posts: []*post{{Title: "Ha! Cosmo Kramer", Text: "Giddy up!", Tags: []string{}}},
},
}, postExecutor)
newStarship := addStarship(t)
humanID := addHuman(t, newStarship.ID)
authorIds := []string{authors[0].ID, authors[1].ID, authors[2].ID}
postIds := []string{authors[0].Posts[0].PostID, authors[1].Posts[0].PostID,
authors[2].Posts[0].PostID}
countryIds := []string{authors[1].Country.ID, authors[2].Country.ID}
getAuthorByIdQuery := `query ($id: ID!) {
getAuthor(id: $id) @cascade {
reputation
Expand Down Expand Up @@ -1881,6 +1886,159 @@ func queryWithCascade(t *testing.T) {
}]
}`,
},
{
name: "parameterized cascade with argument at outer level only",
query: `query ($ids: [ID!]) {
queryAuthor(filter: {id: $ids}) @cascade(fields:["name"]) {
reputation
name
country {
name
}
}
}`,
variables: map[string]interface{}{"ids": authorIds},
respData: `{
"queryAuthor": [{
"reputation": 4.6,
"name":"Jerry",
"country": {
"name": "outer Galaxy2"
}
},{
"name":"Kramer",
"reputation": null,
"country": {
"name": "outer space2"
}
},{
"reputation": 4.5,
"name":"George",
"country": null
}]
}`,
},
{
name: "parameterized cascade only at inner level ",
query: `query ($ids: [ID!]) {
queryAuthor(filter: {id: $ids}) {
reputation
name
posts @cascade(fields:["text"]) {
title
text
}
}
}`,
variables: map[string]interface{}{"ids": authorIds},
respData: `{
"queryAuthor": [{
"reputation": 4.5,
"name":"George",
"posts": [{
"title": "A show about nothing",
"text": "Got ya!"
}]
},{
"name":"Kramer",
"reputation": null,
"posts": [{
"title": "Ha! Cosmo Kramer",
"text": "Giddy up!"
}]
},{
"name":"Jerry",
"reputation": 4.6,
"posts": []
}]
}`,
},
{
name: "parameterized cascade at all levels ",
query: `query ($ids: [ID!]) {
queryAuthor(filter: {id: $ids}) @cascade(fields:["reputation","name"]) {
reputation
name
dob
posts @cascade(fields:["text"]) {
title
text
}
}
}`,
variables: map[string]interface{}{"ids": authorIds},
respData: `{
"queryAuthor": [{
"reputation": 4.5,
"name":"George",
"dob": null,
"posts": [{
"title": "A show about nothing",
"text": "Got ya!"
}]
}, {
"dob": null,
"name": "Jerry",
"posts": [],
"reputation": 4.6
}]
}`,
},
{
name: "parameterized cascade on ID type ",
query: `query ($ids: [ID!]) {
queryAuthor(filter: {id: $ids}) @cascade(fields:["reputation","id"]) {
reputation
name
dob
}
}`,
variables: map[string]interface{}{"ids": authorIds},
respData: `{
"queryAuthor": [{
"reputation": 4.5,
"name":"George",
"dob": null
}, {
"dob": null,
"name": "Jerry",
"reputation": 4.6
}]
}`,
},
{
name: "parameterized cascade on field of interface ",
query: `query {
queryHuman() @cascade(fields:["name"]) {
name
totalCredits
}
}`,
respData: `{
"queryHuman": [{
"name": "Han",
"totalCredits":10
}]
}`,
},
{
name: "parameterized cascade on interface ",
query: `query {
queryCharacter (filter: { appearsIn: { eq: [EMPIRE] } }) @cascade(fields:["appearsIn"])
{
name
appearsIn
}
}`,
respData: `{
"queryCharacter": [{
"name": "Han",
"appearsIn":[
"EMPIRE"
]
}]
}`,
},
}

for _, tcase := range tcases {
Expand All @@ -1897,7 +2055,9 @@ func queryWithCascade(t *testing.T) {

// cleanup
deleteAuthors(t, authorIds, nil)
deleteCountry(t, map[string]interface{}{"id": countryIds}, len(countryIds), nil)
deleteGqlType(t, "Post", map[string]interface{}{"postID": postIds}, len(postIds), nil)
deleteState(t, getXidFilter("xcode", []string{states[0].Code, states[1].Code}), len(states),
nil)
cleanupStarwars(t, newStarship.ID, humanID, "")
}
115 changes: 115 additions & 0 deletions graphql/resolve/mutation_query_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,121 @@ ADD_UPDATE_MUTATION:
}
}

-
name: "parameterized cascade directive on mutation payload"
gqlquery: |
mutation {
ADD_UPDATE_MUTATION @cascade(fields:["post","numUids"]) {
post {
title
text
author {
name
dob
}
}
}
}
dgquery: |-
query {
post(func: uid(0x4)) @cascade {
title : Post.title
text : Post.text
author : Post.author {
name : Author.name
dob : Author.dob
dgraph.uid : uid
}
dgraph.uid : uid
}
}

-
name: "parametrized cascade directive on mutation query field"
gqlquery: |
mutation {
ADD_UPDATE_MUTATION {
post @cascade(fields:["title","text"]) {
title
text
author {
name
dob
}
}
}
}
dgquery: |-
query {
post(func: uid(0x4)) @cascade(Post.title, Post.text) {
title : Post.title
text : Post.text
author : Post.author {
name : Author.name
dob : Author.dob
dgraph.uid : uid
}
dgraph.uid : uid
}
}

-
name: "parameterized cascade directive inside mutation query"
gqlquery: |
mutation {
ADD_UPDATE_MUTATION {
post {
title
text
author @cascade(fields:["name","dob"]) {
name
dob
}
}
}
}
dgquery: |-
query {
post(func: uid(0x4)) {
title : Post.title
text : Post.text
author : Post.author @cascade(Author.name, Author.dob) {
name : Author.name
dob : Author.dob
dgraph.uid : uid
}
dgraph.uid : uid
}
}

-
name: "parameterized cascade directive at multiple levels "
gqlquery: |
mutation {
ADD_UPDATE_MUTATION @cascade(fields:["post"]) {
post {
title
text
author @cascade(fields:["name","dob"]) {
name
dob
}
}
}
}
dgquery: |-
query {
post(func: uid(0x4)) @cascade {
title : Post.title
text : Post.text
author : Post.author @cascade(Author.name, Author.dob) {
name : Author.name
dob : Author.dob
dgraph.uid : uid
}
dgraph.uid : uid
}
}
UPDATE_MUTATION:
-
name: "filter update result"
Expand Down
Loading