/
graph.clj
333 lines (273 loc) · 19.3 KB
/
graph.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
(ns clarango.graph
(:require [clarango.utilities.http-utility :as http])
(:use [clarango.utilities.core-utility :only [remove-options-map filter-out-options-map get-default-graph-name]]
[clarango.utilities.uri-utility :only [build-resource-uri connect-url-parts]]))
(defn execute-traversal
"Sends a traversal to the server to execute it. Output are vertices and edges.
First argument: The key of the start vertex.
Second argument: The name of the collection that contains the vertices.
Third argument: The name of the collection that contains the edges.
Fourth argument: The direction of the traversal. Must be either 'outbound', 'inbound' or 'any'.
Can be nil if the 'expander' attribute is set in the additional options.
Takes optionally a database name as further argument.
If omitted by user, the default database will be used.
Also optional as argument is another map containing further options for the traversal:
{'filter' {...}, 'expander' code}
- see http://www.arangodb.org/manuals/current/HttpTraversals.html#HttpTraversalsPost
The option map might be passed in an arbitrary position after the first four arguments."
[start-vertex vertex-collection edges-collection direction & args]
{:pre [(or (keyword? start-vertex) (string? start-vertex)) (or (keyword? vertex-collection) (string? vertex-collection)) (or (keyword? edges-collection) (string? edges-collection)) (or (nil? direction) (string? direction))]}
(let [body {"startVertex" (str vertex-collection "/" start-vertex) "edgeCollection" edges-collection}
body-with-direction (if (nil? direction) body (assoc body "direction" direction))]
(http/post-uri [:body "result" "visited"] (apply build-resource-uri "traversal" nil nil (remove-options-map args))
body-with-direction
(filter-out-options-map args))))
(defn- extract-edge-definitions
"Extracts from a map the values used when generating multi-collection graphs."
[edge-def-map]
(let [from-vertices (apply vector (map #(if (keyword? %) (name %) %) (:from edge-def-map)))
to-vertices (if (contains? edge-def-map :to) (apply vector (map #(if (keyword? %) (name %) %) (:to edge-def-map))) nil)]
{
:collection (:edge-collection edge-def-map)
:from from-vertices
:to (if (nil? to-vertices) from-vertices to-vertices)
:orphanCollections (if (contains? edge-def-map :orphan-collections) (:orphan-collections edge-def-map) [])
}))
; Create
(defn create
"Creates a new graph.
Takes a graph-name and a map or vector of maps containing the edge definitions.
Each edge definition map should take the following values:
{
:edge-collection - A string or keyword providing the name for the graph being created
:from - A vector of strings or keywords representing existing collection names
:to - A vector of strings or keywords representing existing collection names (if not provided, the 'from' calloection will be used)
}"
[graph-name edge-definition-vector & args]
{:pre [(or (keyword? graph-name) (string? graph-name)) (vector? edge-definition-vector)]}
(let [edge-defs (apply vector (map #(extract-edge-definitions %) edge-definition-vector))]
(http/post-uri [:body "graph"] (apply build-resource-uri "gharial" nil nil (remove-options-map args))
{:name graph-name :edgeDefinitions edge-defs} (filter-out-options-map args))))
;Get information
(defn get-info
"Gets info about the Graph
Returns a map containing info about the graph."
[graph-name & args]
{:pre [(or (keyword? graph-name) (string? graph-name))]}
(http/get-uri [:body "graph"] (apply build-resource-uri "gharial" graph-name nil (remove-options-map args))))
; Delete graph
(defn delete
"Deletes a graph.
Also deletes all vertex and edgea collections."
[graph-name & args]
{:pre [(or (keyword? graph-name) (string? graph-name))]}
(http/delete-uri [:body] (apply build-resource-uri "gharial" graph-name nil (remove-options-map args))))
;; Vertices
; Create vertex
(defn create-vertex
"Creates a new vertex.
First argument: A map representing the vertex data to be saved.
If you want to specify a key by yourself, add it as the :_key parameter to the vertex map or use method create-vertex-with-key.
If you would like the key to be created automatically, just leave this parameter out.
Second argument: The vertex collection where the vertex should be stored.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'waitForSync' true/false} (replace the single quotes with double quotes)
- waitForSync meaning if the server response should wait until the vertex is saved to disk;
The option map might be passed in an arbitrary position after the first argument."
[vertex vertex-collection & args]
{:pre [(map? vertex) (or (string? vertex-collection) (keyword? vertex-collection))]}
(http/post-uri [:body "vertex"] (apply build-resource-uri "gharial" (str "vertex/" (if (keyword? vertex-collection) (name vertex-collection) vertex-collection)) (remove-options-map args)) vertex (filter-out-options-map args)))
; Create vertex with key
(defn create-vertex-with-key
"Creates a new vertex.
First argument: A map representing the vertex data to be saved.
Second argument: The key for the new vertex (string or Clojure keyword)
Third argument: The vertex collection where the vertex should be stored.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'waitForSync' true/false} (replace the single quotes with double quotes)
- waitForSync meaning if the server response should wait until the vertex is saved to disk;
The option map might be passed in an arbitrary position after the first argument."
[vertex key vertex-collection & args]
{:pre [(map? vertex) (or (string? vertex-collection) (keyword? vertex-collection))]}
(http/post-uri [:body "vertex"] (apply build-resource-uri "gharial" (str "vertex/" (if (keyword? vertex-collection) (name vertex-collection) vertex-collection)) (remove-options-map args)) (assoc vertex :_key key) (filter-out-options-map args)))
; Get vertex
(defn get-vertex
"Gets a vertex.
Takes the vertex key as the first argument.
Takes the collection name as the second argument.
Optionally takes a graph-name and a db name as further arguments.
If omitted, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'rev' revision_id} (replace the single quotes with double quotes)
- rev is the document revision; if the current document revision_id does not match the given one, an error is thrown;
The option map might be passed in an arbitrary position after the first argument."
[key vertex-collection & args]
{:pre [(or (keyword? key) (string? key)) (or (string? vertex-collection) (keyword? vertex-collection))]}
(http/get-uri [:body "vertex"] (apply build-resource-uri "gharial" (connect-url-parts "vertex" (if (keyword? vertex-collection) (name vertex-collection) vertex-collection) key) (remove-options-map args)) (filter-out-options-map args)))
; Replace vertex
(defn replace-vertex
"Updates a vertex.
First argument: A map containing the new vertex properties.
Second argument: The vertex key.
Third argument: The vertex collection where the vertex resides.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'rev' revision_id, 'waitForSync' true/false, 'keepNull' true/false} (replace the single quotes with double quotes)
- rev is the document revision; if the current document revision_id does not match the given one, an error is thrown;
- waitForSync meaning if the server response should wait until the action was saved to disk;
- keepNull meaning if the key/value pair should be deleted in the vertex
if the argument map contains it with a null (nil) as value;
The option map might be passed in an arbitrary position after the first argument."
[vertex-properties key vertex-collection & args]
{:pre [(map? vertex-properties) (or (keyword? key) (string? key)) (or (keyword? vertex-collection) (string? vertex-collection))]}
(http/put-uri [:body "vertex"] (apply build-resource-uri "gharial" (connect-url-parts "vertex" (if (keyword? vertex-collection) (name vertex-collection) vertex-collection) key) (remove-options-map args)) vertex-properties (filter-out-options-map args)))
; Update Vertex
(defn update-vertex
"Updates a vertex.
First argument: A map containing the new vertex properties.
Second argument: The vertex key.
Third argument: The vertex collection where the vertex resides.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'rev' revision_id, 'waitForSync' true/false, 'keepNull' true/false} (replace the single quotes with double quotes)
- rev is the document revision; if the current document revision_id does not match the given one, an error is thrown;
- waitForSync meaning if the server response should wait until the action was saved to disk;
- keepNull meaning if the key/value pair should be deleted in the vertex
if the argument map contains it with a null (nil) as value;
The option map might be passed in an arbitrary position after the first argument."
[vertex-properties key vertex-collection & args]
{:pre [(map? vertex-properties) (or (keyword? key) (string? key)) (or (keyword? vertex-collection) (string? vertex-collection))]}
(http/patch-uri [:body "vertex"] (apply build-resource-uri "gharial" (connect-url-parts "vertex" (if (keyword? vertex-collection) (name vertex-collection) vertex-collection) key) (remove-options-map args)) vertex-properties (filter-out-options-map args)))
; Delete Vertex
(defn delete-vertex
"Deletes a vertex.
Takes the vertex key as first argument.
Takes the vertex-collection as the second argument.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'rev' revision_id, 'waitForSync' true/false} (replace the single quotes with double quotes)
- rev is the document revision; if the current document revision_id does not match the given one, an error is thrown;
- waitForSync meaning if the server response should wait until the action was saved to disk;
The option map might be passed in an arbitrary position after the first argument."
[key vertex-collection & args]
{:pre [(or (keyword? key) (string? key)) (or (keyword? vertex-collection) (string? vertex-collection))]}
(http/delete-uri [:body] (apply build-resource-uri "gharial" (connect-url-parts "vertex" (if (keyword? vertex-collection) (name vertex-collection) vertex-collection) key) (remove-options-map args))))
;; Edges
; Create edges
(defn create-edge
"Creates a new edge.
First argument: A map that represents the edge.
If you want to specify a key by yourself, add it as the :_key parameter to the edge map or use method create-edge-with-key.
If you would like the key to be created automatically, just leave this parameter out.
If you optionally want to specify a label for the edge, you can add it as the :$label parameter to the edge map.
Second argument: The name (_id value) of the from vertex (or just the vertex itself as a map).
Third argument: The name (_id value) of the to vertex (or just the vertex itself as a map).
Fourth argument: The edge collection where the edge is to reside.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'waitForSync' true/false} (replace the single quotes with double quotes)
- waitForSync meaning if the server response should wait until the edge is saved to disk;
The option map might be passed in an arbitrary position after the first four arguments."
[edge vertex-from vertex-to edge-collection & args]
{:pre [(map? edge) (or (keyword? vertex-from) (string? vertex-from) (map? vertex-from)) (or (keyword? vertex-to) (string? vertex-to) (map? vertex-to))]}
(let [vertex-from-name (if (map? vertex-from) (get vertex-from "_id") vertex-from)
vertex-to-name (if (map? vertex-to) (get vertex-to "_id") vertex-to)]
(http/post-uri [:body "edge"] (apply build-resource-uri "gharial" (str "edge/" (if (keyword? edge-collection) (name edge-collection) edge-collection)) (remove-options-map args))
(assoc edge "_from" vertex-from-name "_to" vertex-to-name)
(filter-out-options-map args))))
; Create edge with key
(defn create-edge-with-key
"Creates a new edge with the provided key.
First argument: A map that represents the edge.
Second argument: The key (string or clojure keyword) to be used for the new edge record. If nil then
a new key will be generated.
Third argument: The name (_id value) of the from vertex (or just the vertex itself as a map).
Fourth argument: The name (_id value) of the to vertex (or just the vertex itself as a map).
Fifth argument: The edge collection where the edge is to reside.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'waitForSync' true/false} (replace the single quotes with double quotes)
- waitForSync meaning if the server response should wait until the edge is saved to disk;
The option map might be passed in an arbitrary position after the first four arguments."
[edge edge-key vertex-from vertex-to edge-collection & args]
{:pre [(map? edge) (or (keyword? vertex-from) (string? vertex-from) (map? vertex-from)) (or (keyword? vertex-to) (string? vertex-to) (map? vertex-to))]}
(let [vertex-from-name (if (map? vertex-from) (get vertex-from "_id") vertex-from)
vertex-to-name (if (map? vertex-to) (get vertex-to "_id") vertex-to)
edge-with-or-without-key (if (nil? edge-key) edge (assoc edge :_key edge-key))]
(http/post-uri [:body "edge"] (apply build-resource-uri "gharial" (str "edge/" (if (keyword? edge-collection) (name edge-collection) edge-collection)) (remove-options-map args))
(assoc edge-with-or-without-key "_from" vertex-from-name "_to" vertex-to-name)
(filter-out-options-map args))))
; Get edge
(defn get-edge
"Gets an edge.
Takes the edge key as the first argument.
Takes the edge-collection name as the second argument.
Optionally takes a graph-name and a db name as further arguments.
If omitted, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'rev' revision_id} (replace the single quotes with double quotes)
- rev is the document revision; if the current document revision_id does not match the given one, an error is thrown;
The option map might be passed in an arbitrary position after the first argument."
[key edge-collection & args]
{:pre [(or (keyword? key) (string? key)) (or (string? edge-collection) (keyword? edge-collection))]}
(http/get-uri [:body "edge"] (apply build-resource-uri "gharial" (connect-url-parts "edge" (if (keyword? edge-collection) (name edge-collection) edge-collection) key) (remove-options-map args)) (filter-out-options-map args)))
; Replace edge
(defn replace-edge
"Updates a edge.
First argument: A map containing the new edge properties.
Second argument: The edge key.
Third argument: The edge collection where the edge resides.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'rev' revision_id, 'waitForSync' true/false, 'keepNull' true/false} (replace the single quotes with double quotes)
- rev is the document revision; if the current document revision_id does not match the given one, an error is thrown;
- waitForSync meaning if the server response should wait until the action was saved to disk;
- keepNull meaning if the key/value pair should be deleted in the vertex
if the argument map contains it with a null (nil) as value;
The option map might be passed in an arbitrary position after the first argument."
[edge-properties key edge-collection & args]
{:pre [(map? edge-properties) (or (keyword? key) (string? key)) (or (keyword? edge-collection) (string? edge-collection))]}
(http/put-uri [:body "edge"] (apply build-resource-uri "gharial" (connect-url-parts "edge" (if (keyword? edge-collection) (name edge-collection) edge-collection) key) (remove-options-map args)) edge-properties (filter-out-options-map args)))
; Update edge
(defn update-edge
"Updates an edge.
First argument: A map containing the new edge properties.
Second argument: The edge key.
Third argument: The edge collection where the edge resides.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'rev' revision_id, 'waitForSync' true/false, 'keepNull' true/false} (replace the single quotes with double quotes)
- rev is the document revision; if the current document revision_id does not match the given one, an error is thrown;
- waitForSync meaning if the server response should wait until the action was saved to disk;
- keepNull meaning if the key/value pair should be deleted in the vertex
if the argument map contains it with a null (nil) as value;
The option map might be passed in an arbitrary position after the first argument."
[edge-properties key edge-collection & args]
{:pre [(map? edge-properties) (or (keyword? key) (string? key)) (or (keyword? edge-collection) (string? edge-collection))]}
(http/patch-uri [:body "edge"] (apply build-resource-uri "gharial" (connect-url-parts "edge" (if (keyword? edge-collection) (name edge-collection) edge-collection) key) (remove-options-map args)) edge-properties (filter-out-options-map args)))
; Delete edge
(defn delete-edge
"Deletes an edge.
Takes the edge key as first argument.
Takes the edge-collection as the second argument.
Takes optional a graph name and a db name as further arguments.
If omitted by user, the default graph and db will be used.
Also optional as argument is another map containing further options:
{'rev' revision_id, 'waitForSync' true/false} (replace the single quotes with double quotes)
- rev is the document revision; if the current document revision_id does not match the given one, an error is thrown;
- waitForSync meaning if the server response should wait until the action was saved to disk;
The option map might be passed in an arbitrary position after the first argument."
[key edge-collection & args]
{:pre [(or (keyword? key) (string? key)) (or (keyword? edge-collection) (string? edge-collection))]}
(http/delete-uri [:body] (apply build-resource-uri "gharial" (connect-url-parts "edge" (if (keyword? edge-collection) (name edge-collection) edge-collection) key) (remove-options-map args))))