Skip to content

Commit a9f4fca

Browse files
mangalaman93dna2github
authored andcommitted
Add support for JSON data for upsert block (hypermodeinc#3412)
1 parent 11bad29 commit a9f4fca

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

Diff for: chunker/json/parse.go

+21
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"strconv"
2424
"strings"
25+
"unicode"
2526

2627
"github.com/dgraph-io/dgo/protos/api"
2728
"github.com/dgraph-io/dgraph/query"
@@ -33,6 +34,16 @@ import (
3334
"github.com/twpayne/go-geom/encoding/geojson"
3435
)
3536

37+
func stripSpaces(str string) string {
38+
return strings.Map(func(r rune) rune {
39+
if unicode.IsSpace(r) {
40+
return -1
41+
}
42+
43+
return r
44+
}, str)
45+
}
46+
3647
func parseFacets(m map[string]interface{}, prefix string) ([]*api.Facet, error) {
3748
// This happens at root.
3849
if prefix == "" {
@@ -134,6 +145,13 @@ func handleBasicType(k string, v interface{}, op int, nq *api.NQuad) error {
134145
return nil
135146
}
136147

148+
// Handle the uid function in upsert block
149+
s := stripSpaces(v)
150+
if strings.HasPrefix(s, "uid(") {
151+
nq.ObjectId = s
152+
return nil
153+
}
154+
137155
// In RDF, we assume everything is default (types.DefaultID), but in JSON we assume string
138156
// (StringID). But this value will be checked against the schema so we don't overshadow a
139157
// password value (types.PasswordID) - Issue#2623
@@ -222,10 +240,13 @@ func mapToNquads(m map[string]interface{}, idx *int, op int, parentPred string)
222240
uid = uint64(ui)
223241

224242
case string:
243+
s := stripSpaces(uidVal)
225244
if len(uidVal) == 0 {
226245
uid = 0
227246
} else if ok := strings.HasPrefix(uidVal, "_:"); ok {
228247
mr.uid = uidVal
248+
} else if ok := strings.HasPrefix(s, "uid("); ok {
249+
mr.uid = s
229250
} else if u, err := strconv.ParseUint(uidVal, 0, 64); err == nil {
230251
uid = u
231252
} else {

Diff for: dgraph/cmd/alpha/http.go

+7
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,13 @@ func mutationHandler(w http.ResponseWriter, r *http.Request) {
320320
if delJSON, ok := ms["delete"]; ok && delJSON != nil {
321321
mu.DeleteJson = delJSON.bs
322322
}
323+
if queryText, ok := ms["query"]; ok && queryText != nil {
324+
mu.Query, err = strconv.Unquote(string(queryText.bs))
325+
if err != nil {
326+
x.SetStatus(w, x.ErrorInvalidRequest, err.Error())
327+
return
328+
}
329+
}
323330

324331
case "application/rdf":
325332
// Parse N-Quads.

Diff for: dgraph/cmd/alpha/upsert_test.go

+58
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,61 @@ upsert {
9898
require.NoError(t, err)
9999
require.Contains(t, res, "Ashish")
100100
}
101+
102+
func TestUpsertExample0JSON(t *testing.T) {
103+
require.NoError(t, dropAll())
104+
require.NoError(t, alterSchema(`email: string @index(exact) .`))
105+
106+
// Mutation with wrong name
107+
m1 := `
108+
{
109+
"query": "{me(func: eq(email, \"[email protected]\")) {v as uid}}",
110+
"set": [
111+
{
112+
"uid": "uid(v)",
113+
"name": "Wrong"
114+
},
115+
{
116+
"uid": "uid(v)",
117+
"email": "[email protected]"
118+
}
119+
]
120+
}`
121+
keys, _, _, err := mutationWithTs(m1, "application/json", false, true, true, 0)
122+
require.NoError(t, err)
123+
require.True(t, len(keys) == 0)
124+
125+
// query should return the wrong name
126+
q1 := `
127+
{
128+
q(func: has(email)) {
129+
uid
130+
name
131+
email
132+
}
133+
}`
134+
res, _, err := queryWithTs(q1, "application/graphql+-", 0)
135+
require.NoError(t, err)
136+
require.Contains(t, res, "Wrong")
137+
138+
// mutation with correct name
139+
m2 := `
140+
{
141+
"query": "{me(func: eq(email, \"[email protected]\")) {v as uid}}",
142+
"set": [
143+
{
144+
"uid": "uid(v)",
145+
"name": "Ashish"
146+
}
147+
]
148+
}`
149+
keys, preds, _, err := mutationWithTs(m2, "application/json", false, true, true, 0)
150+
require.NoError(t, err)
151+
require.True(t, len(keys) == 0)
152+
require.True(t, contains(preds, "name"))
153+
154+
// query should return correct name
155+
res, _, err = queryWithTs(q1, "application/graphql+-", 0)
156+
require.NoError(t, err)
157+
require.Contains(t, res, "Ashish")
158+
}

0 commit comments

Comments
 (0)