@@ -28,22 +28,23 @@ import (
28
28
"github.com/twpayne/go-geom/encoding/geojson"
29
29
)
30
30
31
- type Op int
31
+ type opType int
32
32
33
33
const (
34
34
// SET indicates a Set mutation.
35
- SET Op = iota
35
+ SET opType = iota
36
36
// DEL indicates a Delete mutation.
37
37
DEL
38
38
)
39
39
40
- // Req wraps the protos.Request so that helper methods can be defined on it.
40
+ // A Req represents a single request to the backend Dgraph instance. Each request may contain
41
+ // multiple set, delete and schema mutations, and a single GraphQL+- query. If the query contains
42
+ // GraphQL variables, then it must be set with SetQueryWithVariables rather than SetQuery.
41
43
type Req struct {
42
44
gr protos.Request
43
45
}
44
46
45
- // Request returns the graph request object which is sent to the server to perform
46
- // a query/mutation.
47
+ // Request returns the protos.Request backing the Req.
47
48
func (req * Req ) Request () * protos.Request {
48
49
return & req .gr
49
50
}
@@ -61,18 +62,23 @@ func checkSchema(schema protos.SchemaUpdate) error {
61
62
return nil
62
63
}
63
64
64
- // SetQuery sets a query with graphQL variables as part of the request.
65
+ // SetQuery sets the query in req to the given string.
66
+ // The query string is not checked until the request is
67
+ // run, when it is parsed and checked server-side.
65
68
func (req * Req ) SetQuery (q string ) {
66
69
req .gr .Query = q
67
70
}
68
71
69
- // SetQueryWithVariables sets a query with graphQL variables as part of the request.
72
+ // SetQueryWithVariables sets query q (which contains graphQL variables mapped
73
+ // in vars) as the query in req and sets vars as the corresponding query variables.
74
+ // Neither the query string nor the variables are checked until the request is run,
75
+ // when it is parsed and checked server-side.
70
76
func (req * Req ) SetQueryWithVariables (q string , vars map [string ]string ) {
71
77
req .gr .Query = q
72
78
req .gr .Vars = vars
73
79
}
74
80
75
- func (req * Req ) addMutation (e Edge , op Op ) {
81
+ func (req * Req ) addMutation (e Edge , op opType ) {
76
82
if req .gr .Mutation == nil {
77
83
req .gr .Mutation = new (protos.Mutation )
78
84
}
@@ -84,23 +90,41 @@ func (req *Req) addMutation(e Edge, op Op) {
84
90
}
85
91
}
86
92
87
- func (req * Req ) Set (e Edge ) {
93
+ // Set adds edge e to the set mutation of request req, thus scheduling the edge to be added to the
94
+ // graph when the request is run. The edge must have a valid target (a Node or value), otherwise
95
+ // an error is returned. The edge is not checked agaist the schema until the request is
96
+ // run --- so setting a UID edge to a value, for example, doesn't result in an error until
97
+ // the request is run.
98
+ func (req * Req ) Set (e Edge ) error {
99
+ if err := e .validate (); err != nil {
100
+ return err
101
+ }
88
102
req .addMutation (e , SET )
103
+ return nil
89
104
}
90
105
91
- func (req * Req ) Delete (e Edge ) {
106
+ // Delete adds edge e to the delete mutation of request req, thus scheduling the edge to be removed
107
+ // from the graph when the request is run. The edge must have a valid target (a Node or value),
108
+ // otherwise an error is returned. The edge need not represent
109
+ // an edge in the graph --- applying such a mutation simply has no effect.
110
+ func (req * Req ) Delete (e Edge ) error {
111
+ if err := e .validate (); err != nil {
112
+ return err
113
+ }
92
114
req .addMutation (e , DEL )
115
+ return nil
93
116
}
94
117
95
- // AddSchema sets the schema mutations
96
- func (req * Req ) addSchema (s protos.SchemaUpdate ) error {
118
+ // AddSchema adds the single schema mutation s to the request.
119
+ func (req * Req ) AddSchema (s protos.SchemaUpdate ) error {
97
120
if req .gr .Mutation == nil {
98
121
req .gr .Mutation = new (protos.Mutation )
99
122
}
100
123
req .gr .Mutation .Schema = append (req .gr .Mutation .Schema , & s )
101
124
return nil
102
125
}
103
126
127
+
104
128
func (req * Req ) size () int {
105
129
if req .gr .Mutation == nil {
106
130
return 0
@@ -117,22 +141,25 @@ func (req *Req) reset() {
117
141
118
142
type nquadOp struct {
119
143
e Edge
120
- op Op
144
+ op opType
121
145
}
122
146
147
+ // Node represents a single node in the graph.
123
148
type Node struct {
124
149
uid uint64
125
150
// We can do variables in mutations.
126
151
varName string
127
152
}
128
153
154
+ // String returns Node n as a string
129
155
func (n Node ) String () string {
130
156
if n .uid != 0 {
131
157
return fmt .Sprintf ("%#x" , uint64 (n .uid ))
132
158
}
133
159
return n .varName
134
160
}
135
161
162
+ // ConnectTo creates an edge labelled pred from Node n to Node n1
136
163
func (n * Node ) ConnectTo (pred string , n1 Node ) Edge {
137
164
e := Edge {}
138
165
if len (n .varName ) != 0 {
@@ -145,6 +172,11 @@ func (n *Node) ConnectTo(pred string, n1 Node) Edge {
145
172
return e
146
173
}
147
174
175
+ // Edge create an edge with source Node n and predicate pred, but without a target.
176
+ // The edge needs to be completed by calling Edge.ConnectTo() if the edge is a
177
+ // UID edge, or one of the Edge.SetValue...() functions if the edge is of a scalar type.
178
+ // The edge can't be committed to the store --- calling Req.Set() to add the edge to
179
+ // a request will result in an error --- until it is completed.
148
180
func (n * Node ) Edge (pred string ) Edge {
149
181
e := Edge {}
150
182
if len (n .varName ) != 0 {
@@ -156,14 +188,21 @@ func (n *Node) Edge(pred string) Edge {
156
188
return e
157
189
}
158
190
191
+ // An Edge represents an edge between a source node and a target (either a node or a value).
192
+ // Facets are stored in the edge. See Node.Edge(), Node.ConnectTo(), Edge.ConnecTo(),
193
+ // Edge.AddFacet and the Edge.SetValue...() functions to
194
+ // make a valid edge for a set or delete mutation.
159
195
type Edge struct {
160
196
nq protos.NQuad
161
197
}
162
198
199
+ // NewEdge creates an Edge from an NQuad.
163
200
func NewEdge (nq protos.NQuad ) Edge {
164
201
return Edge {nq }
165
202
}
166
203
204
+ // ConnectTo adds Node n as the target of the edge. If the edge already has a known scalar type,
205
+ // for example if Edge.SetValue...() had been called on the edge, then an error is returned.
167
206
func (e * Edge ) ConnectTo (n Node ) error {
168
207
if e .nq .ObjectType > 0 {
169
208
return ErrValue
@@ -176,6 +215,15 @@ func (e *Edge) ConnectTo(n Node) error {
176
215
return nil
177
216
}
178
217
218
+ func (e * Edge ) validate () error {
219
+ // Edge should be connected to a value in which case ObjectType would be > 0.
220
+ // Or it needs to connect to a Node (ObjectId > 0) or it should be connected to a variable.
221
+ if e .nq .ObjectValue != nil || len (e .nq .ObjectId ) > 0 || len (e .nq .ObjectVar ) > 0 {
222
+ return nil
223
+ }
224
+ return ErrNotConnected
225
+ }
226
+
179
227
func validateStr (val string ) error {
180
228
for idx , c := range val {
181
229
if c == '"' && (idx == 0 || val [idx - 1 ] != '\\' ) {
@@ -185,6 +233,11 @@ func validateStr(val string) error {
185
233
return nil
186
234
}
187
235
236
+ // SetValueString sets the value of Edge e as string val and sets the type of the edge to
237
+ // types.StringID. If the edge had previous been assigned another value (even of another type),
238
+ // the value and type are overwritten. If the edge has previously been connected to a node, the
239
+ // edge and type are left unchanged and ErrConnected is returned. The string must
240
+ // escape " with \, otherwise the edge and type are left unchanged and an error returned.
188
241
func (e * Edge ) SetValueString (val string ) error {
189
242
if len (e .nq .ObjectId ) > 0 {
190
243
return ErrConnected
@@ -202,6 +255,10 @@ func (e *Edge) SetValueString(val string) error {
202
255
return nil
203
256
}
204
257
258
+ // SetValueInt sets the value of Edge e as int64 val and sets the type of the edge to types.IntID.
259
+ // If the edge had previous been assigned another value (even of another type), the value and type
260
+ // are overwritten. If the edge has previously been connected to a node, the edge and type are
261
+ // left unchanged and ErrConnected is returned.
205
262
func (e * Edge ) SetValueInt (val int64 ) error {
206
263
if len (e .nq .ObjectId ) > 0 {
207
264
return ErrConnected
@@ -215,6 +272,10 @@ func (e *Edge) SetValueInt(val int64) error {
215
272
return nil
216
273
}
217
274
275
+ // SetValueFloat sets the value of Edge e as float64 val and sets the type of the edge to
276
+ // types.FloatID. If the edge had previous been assigned another value (even of another type),
277
+ // the value and type are overwritten. If the edge has previously been connected to a node, the
278
+ // edge and type are left unchanged and ErrConnected is returned.
218
279
func (e * Edge ) SetValueFloat (val float64 ) error {
219
280
if len (e .nq .ObjectId ) > 0 {
220
281
return ErrConnected
@@ -228,6 +289,10 @@ func (e *Edge) SetValueFloat(val float64) error {
228
289
return nil
229
290
}
230
291
292
+ // SetValueBool sets the value of Edge e as bool val and sets the type of the edge to types.BoolID.
293
+ // If the edge had previous been assigned another value (even of another type), the value and type
294
+ // are overwritten. If the edge has previously been connected to a node, the edge and type are
295
+ // left unchanged and ErrConnected is returned.
231
296
func (e * Edge ) SetValueBool (val bool ) error {
232
297
if len (e .nq .ObjectId ) > 0 {
233
298
return ErrConnected
@@ -241,6 +306,10 @@ func (e *Edge) SetValueBool(val bool) error {
241
306
return nil
242
307
}
243
308
309
+ // SetValuePassword sets the value of Edge e as password string val and sets the type of the edge
310
+ // to types.PasswordID. If the edge had previous been assigned another value (even of another
311
+ // type), the value and type are overwritten. If the edge has previously been connected to a
312
+ // node, the edge and type are left unchanged and ErrConnected is returned.
244
313
func (e * Edge ) SetValuePassword (val string ) error {
245
314
if len (e .nq .ObjectId ) > 0 {
246
315
return ErrConnected
@@ -254,6 +323,10 @@ func (e *Edge) SetValuePassword(val string) error {
254
323
return nil
255
324
}
256
325
326
+ // SetValueDatetime sets the value of Edge e as time.Time dateTime and sets the type of the edge
327
+ // to types.DateTimeID. If the edge had previous been assigned another value (even of another
328
+ // type), the value and type are overwritten. If the edge has previously been connected to a node,
329
+ // the edge and type are left unchanged and ErrConnected is returned.
257
330
func (e * Edge ) SetValueDatetime (dateTime time.Time ) error {
258
331
if len (e .nq .ObjectId ) > 0 {
259
332
return ErrConnected
@@ -267,6 +340,11 @@ func (e *Edge) SetValueDatetime(dateTime time.Time) error {
267
340
return nil
268
341
}
269
342
343
+ // SetValueGeoJson sets the value of Edge e as the GeoJSON object parsed from json string and sets
344
+ // the type of the edge to types.GeoID. If the edge had previous been assigned another value (even
345
+ // of another type), the value and type are overwritten. If the edge has previously been connected
346
+ // to a node, the edge and type are left unchanged and ErrConnected is returned. If the string
347
+ // fails to parse with geojson.Unmarshal() the edge is left unchanged and an error returned.
270
348
func (e * Edge ) SetValueGeoJson (json string ) error {
271
349
if len (e .nq .ObjectId ) > 0 {
272
350
return ErrConnected
@@ -288,6 +366,11 @@ func (e *Edge) SetValueGeoJson(json string) error {
288
366
return nil
289
367
}
290
368
369
+ // SetValueDefault sets the value of Edge e as string val and sets the type of the edge to
370
+ // types.DefaultID. If the edge had previous been assigned another value (even of another
371
+ // type), the value and type are overwritten. If the edge has previously been connected to
372
+ // a node, the edge and type are left unchanged and ErrConnected is returned.
373
+ // The string must escape " with \, otherwise the edge and type are left unchanged and an error returned.
291
374
func (e * Edge ) SetValueDefault (val string ) error {
292
375
if len (e .nq .ObjectId ) > 0 {
293
376
return ErrConnected
@@ -305,6 +388,10 @@ func (e *Edge) SetValueDefault(val string) error {
305
388
return nil
306
389
}
307
390
391
+ // SetValueBytes allows setting the value of an edge to raw bytes and sets the type of the edge
392
+ // to types.BinaryID. If the edge had previous been assigned another value (even of another type),
393
+ // the value and type are overwritten. If the edge has previously been connected to a node, the
394
+ // edge and type are left unchanged and ErrConnected is returned. the bytes are encoded as base64.
308
395
func (e * Edge ) SetValueBytes (val []byte ) error {
309
396
if len (e .nq .ObjectId ) > 0 {
310
397
return ErrConnected
@@ -320,6 +407,7 @@ func (e *Edge) SetValueBytes(val []byte) error {
320
407
return nil
321
408
}
322
409
410
+ // AddFacet adds the key, value pair as facets on Edge e. No checking is done.
323
411
func (e * Edge ) AddFacet (key , val string ) {
324
412
e .nq .Facets = append (e .nq .Facets , & protos.Facet {
325
413
Key : key ,
0 commit comments