arangorb 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/ArangoRB.gemspec +2 -2
  3. data/README.md +418 -123
  4. data/lib/ArangoRB_AQL.rb +90 -103
  5. data/lib/ArangoRB_Col.rb +476 -159
  6. data/lib/ArangoRB_DB.rb +305 -79
  7. data/lib/ArangoRB_Doc.rb +112 -114
  8. data/lib/ArangoRB_Edg.rb +81 -62
  9. data/lib/ArangoRB_Gra.rb +125 -76
  10. data/lib/ArangoRB_Index.rb +144 -0
  11. data/lib/ArangoRB_Ser.rb +439 -18
  12. data/lib/ArangoRB_Task.rb +136 -0
  13. data/lib/ArangoRB_Tra.rb +47 -42
  14. data/lib/ArangoRB_Tran.rb +48 -0
  15. data/lib/ArangoRB_User.rb +152 -0
  16. data/lib/ArangoRB_Ver.rb +74 -57
  17. data/lib/arangorb.rb +4 -0
  18. data/spec/arangoRB_helper.rb +2 -9
  19. data/spec/arangoRestart_helper.rb +14 -0
  20. data/spec/lib/{arangoAQL_helper.rb → 0.1.0/arangoAQL_helper.rb} +2 -21
  21. data/spec/lib/{arangoC_helper.rb → 0.1.0/arangoC_helper.rb} +40 -19
  22. data/spec/lib/{arangoDB_helper.rb → 0.1.0/arangoDB_helper.rb} +13 -13
  23. data/spec/lib/{arangoDoc_helper.rb → 0.1.0/arangoDoc_helper.rb} +10 -23
  24. data/spec/lib/0.1.0/arangoE_helper.rb +50 -0
  25. data/spec/lib/{arangoG_helper.rb → 0.1.0/arangoG_helper.rb} +7 -21
  26. data/spec/lib/0.1.0/arangoS_helper.rb +37 -0
  27. data/spec/lib/0.1.0/arangoT_helper.rb +48 -0
  28. data/spec/lib/{arangoV_helper.rb → 0.1.0/arangoV_helper.rb} +6 -22
  29. data/spec/lib/1.0.0/arangoC_helper.rb +73 -0
  30. data/spec/lib/1.0.0/arangoDB_helper.rb +81 -0
  31. data/spec/lib/1.0.0/arangoI_helper.rb +43 -0
  32. data/spec/lib/1.0.0/arangoS_helper.rb +196 -0
  33. data/spec/lib/1.0.0/arangoTa_helper.rb +49 -0
  34. data/spec/lib/1.0.0/arangoTr_helper.rb +15 -0
  35. data/spec/lib/1.0.0/arangoU_helper.rb +72 -0
  36. data/spec/lib/arangoRB_0.1.0_helper.rb +9 -0
  37. data/spec/lib/arangoRB_1.0.0_helper.rb +6 -0
  38. data/spec/spec_helper.rb +34 -0
  39. metadata +28 -15
  40. data/spec/lib/arangoE_helper.rb +0 -70
  41. data/spec/lib/arangoS_helper.rb +0 -28
  42. data/spec/lib/arangoT_helper.rb +0 -67
data/lib/ArangoRB_Ser.rb CHANGED
@@ -1,64 +1,485 @@
1
1
  # === SERVER ===
2
2
 
3
- class ArangoS
3
+ class ArangoServer
4
4
  include HTTParty
5
+
5
6
  @@verbose = false
7
+ @@async = false
6
8
  @@database = "_system"
7
9
  @@graph = nil
8
10
  @@collection = nil
11
+ @@user = nil
12
+ @@request = {:body => {}, :headers => {}, :query => {}}
13
+ @@password = ""
14
+ @@username = "root"
15
+ @@server = "localhost"
16
+ @@port = "8529"
17
+ @@cluster = "cluster-test"
9
18
 
10
- def self.default_server(user: "root", password:, server: "localhost", port: "8529")
19
+ def self.default_server(user: @@username, password: @@password, server: @@server, port: @@port) # TESTED
11
20
  base_uri "http://#{server}:#{port}"
12
21
  basic_auth user, password
22
+ @@username = user
23
+ @@password = password
24
+ @@server = server
25
+ @@port = port
26
+ end
27
+
28
+ def self.address # TESTED
29
+ "#{@@server}:#{@@port}"
30
+ end
31
+
32
+ def self.username # TESTED
33
+ @@username
13
34
  end
14
35
 
15
- def self.verbose=(verbose)
36
+ def self.verbose=(verbose) # TESTED
16
37
  @@verbose = verbose
17
38
  end
18
39
 
19
- def self.verbose
40
+ def self.verbose # TESTED
20
41
  @@verbose
21
42
  end
22
43
 
23
- def self.database=(database)
44
+ def self.async=(async) # TESTED
45
+ @@async = async
46
+ if async == true || async == "true"
47
+ @@request[:headers] = {"x-arango-async" => "true"}
48
+ elsif async == "store"
49
+ @@request[:headers] = {"x-arango-async" => "store"}
50
+ else
51
+ @@request[:headers] = {}
52
+ end
53
+ end
54
+
55
+ def self.async # TESTED
56
+ @@async
57
+ end
58
+
59
+ def self.database=(database) # TESTED
24
60
  if database.is_a? String
25
61
  @@database = database
26
- elsif database.is_a? ArangoDB
62
+ elsif database.is_a? ArangoDatabase
27
63
  @@database = database.database
28
64
  else
29
- raise "database should be a String or an ArangoDB instance, not a #{database.class}"
65
+ raise "database should be a String or an ArangoDatabase instance, not a #{database.class}"
30
66
  end
31
67
  end
32
68
 
33
- def self.database
69
+ def self.database # TESTED
34
70
  @@database
35
71
  end
36
72
 
37
- def self.graph=(graph)
73
+ def self.graph=(graph) # TESTED
38
74
  if graph.is_a? String
39
75
  @@graph = graph
40
- elsif graph.is_a? ArangoG
41
- @@graph = graph
76
+ elsif graph.is_a? ArangoGraph
77
+ @@graph = graph.graph
42
78
  else
43
- raise "graph should be a String or an ArangoG instance, not a #{graph.class}"
79
+ raise "graph should be a String or an ArangoGraph instance, not a #{graph.class}"
44
80
  end
45
81
  end
46
82
 
47
- def self.graph
83
+ def self.graph # TESTED
48
84
  @@graph
49
85
  end
50
86
 
51
- def self.collection=(collection)
87
+ def self.collection=(collection) # TESTED
52
88
  if collection.is_a? String
53
89
  @@collection = collection
54
- elsif collection.is_a? ArangoC
55
- @@collection = collection
90
+ elsif collection.is_a? ArangoCollection
91
+ @@collection = collection.collection
56
92
  else
57
- raise "graph should be a String or an ArangoC instance, not a #{collection.class}"
93
+ raise "graph should be a String or an ArangoCollection instance, not a #{collection.class}"
58
94
  end
59
95
  end
60
96
 
61
- def self.collection
97
+ def self.collection # TESTED
62
98
  @@collection
63
99
  end
100
+
101
+ def self.user=(user)
102
+ if user.is_a? String
103
+ @@user = user
104
+ elsif user.is_a? ArangoUser
105
+ @@user = user.user
106
+ else
107
+ raise "graph should be a String or an ArangoUser instance, not a #{user.class}"
108
+ end
109
+ end
110
+
111
+ def self.user # TESTED
112
+ @@user
113
+ end
114
+
115
+ def self.request # TESTED
116
+ @@request
117
+ end
118
+
119
+ def self.cluster
120
+ @@cluster
121
+ end
122
+
123
+ def self.cluster=(cluster)
124
+ @@cluster = cluster
125
+ end
126
+
127
+ # === MONITORING ===
128
+
129
+ def self.log # TESTED
130
+ result = get("/_admin/log", @@request)
131
+ return_result result: result
132
+ end
133
+
134
+ def self.reload # TESTED
135
+ result = post("/_admin/routing/reload", @@request)
136
+ return_result result: result, caseTrue: true
137
+ end
138
+
139
+ def self.statistics description: false # TESTED
140
+ if description
141
+ result = get("/_admin/statistics-description", @@request)
142
+ else
143
+ result = get("/_admin/statistics", @@request)
144
+ end
145
+ return_result result: result
146
+ end
147
+
148
+ def self.role # TESTED
149
+ result = get("/_admin/server/role", @@request)
150
+ return_result result: result, key: "role"
151
+ end
152
+
153
+ def self.server
154
+ result = get("/_admin/server/id", @@request)
155
+ return_result result: result
156
+ end
157
+
158
+ def self.clusterStatistics dbserver:
159
+ query = {"DBserver": dbserver}
160
+ request = @@request.merge({ :query => query })
161
+ result = get("/_admin/clusterStatistics", request)
162
+ return_result result: result
163
+ end
164
+
165
+ # === LISTS ===
166
+
167
+ def self.endpoints # TESTED
168
+ result = get("/_api/endpoint", @@request)
169
+ return_result result: result
170
+ end
171
+
172
+ def self.users # TESTED
173
+ result = get("/_api/user", @@request)
174
+ if @@async == "store"
175
+ result.headers["x-arango-async-id"]
176
+ else
177
+ result = result.parsed_response
178
+ if @@verbose
179
+ return result
180
+ else
181
+ if result["error"]
182
+ return result["errorMessage"]
183
+ else
184
+ return result["result"].map{|x| ArangoUser.new(user: x["user"], active: x["active"], extra: x["extra"])}
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ def self.databases(user: nil) # TESTED
191
+ ArangoDatabase.databases user: user
192
+ end
193
+
194
+
195
+ def self.tasks # TESTED
196
+ result = get("/_api/tasks", @@request)
197
+ if @@async == "store"
198
+ result.headers["x-arango-async-id"]
199
+ else
200
+ result = result.parsed_response
201
+ if @@verbose
202
+ result
203
+ else
204
+ if result.is_a?(Hash) && result["error"]
205
+ result["errorMessage"]
206
+ else
207
+ result.map{|x| ArangoTask.new(id: x["id"], name: x["name"], type: x["type"], period: x["period"], created: x["created"], command: x["command"], database: x["database"])}
208
+ end
209
+ end
210
+ end
211
+ end
212
+
213
+ # === ASYNC ===
214
+
215
+ def self.pendingAsync # TESTED
216
+ result = get("/_api/job/pending")
217
+ return_result_async result: result
218
+ end
219
+
220
+ def self.fetchAsync(id:) # TESTED
221
+ result = put("/_api/job/#{id}")
222
+ return_result_async result: result
223
+ end
224
+
225
+ def self.retrieveAsync(type: nil, id: nil) # TESTED
226
+ result = id.nil? ? get("/_api/job/#{type}") : get("/_api/job/#{id}")
227
+ return_result_async result: result
228
+ end
229
+
230
+ def self.retrieveDoneAsync # TESTED
231
+ retrieveAsync(type: "done")
232
+ end
233
+
234
+ def self.retrievePendingAsync # TESTED
235
+ retrieveAsync(type: "pending")
236
+ end
237
+
238
+ def self.cancelAsync(id:) # TESTED
239
+ result = put("/_api/job/#{id}/cancel")
240
+ return_result_async result: result
241
+ end
242
+
243
+ def self.destroyAsync(type: nil, id: nil) # TESTED
244
+ result = id.nil? ? delete("/_api/job/#{type}") : delete("/_api/job/#{id}")
245
+ return_result_async result: result, caseTrue: true
246
+ end
247
+
248
+ def self.destroyAllAsync # TESTED
249
+ destroyAsync(type: "all")
250
+ end
251
+
252
+ def self.destroyExpiredAsync # TESTED
253
+ destroyAsync(type: "expired")
254
+ end
255
+
256
+ # === BATCH ===
257
+
258
+ def self.batch(queries:) # TESTED
259
+ headers = {
260
+ "Content-Type": "multipart/form-data",
261
+ "boundary": "XboundaryX"
262
+ }
263
+ body = ""
264
+ queries.each{|query|
265
+ body += "--XboundaryX\n"
266
+ body += "Content-Type: application/x-arango-batchpart\n"
267
+ body += "Content-Id: #{query[:id]}\n" unless query[:id].nil?
268
+ body += "\n"
269
+ body += "#{query[:type]} "
270
+ body += "#{query[:address]} HTTP/1.1\n"
271
+ body += "\n#{query[:body].to_json}\n" unless query[:body].nil?
272
+ }
273
+ body += "--XboundaryX--\n" if queries.length > 0
274
+ request = @@request.merge({ :body => body, :headers => headers })
275
+ result = post("/_api/batch", request)
276
+ return_result result: result
277
+ end
278
+
279
+ def self.destroyDumpBatch(id:, dbserver: nil) # TESTED
280
+ query = {"DBserver" => dbserver}.delete_if{|k,v| v.nil?}
281
+ request = @@request.merge({ :query => query })
282
+ result = delete("/_api/replication/batch/#{id}", request)
283
+ return true if result.nil?
284
+ return result["errorMessage"] if result["error"]
285
+ end
286
+
287
+ def self.createDumpBatch(ttl:, dbserver: nil) # TESTED
288
+ query = {"DBserver" => dbserver}.delete_if{|k,v| v.nil?}
289
+ body = { "ttl" => ttl }
290
+ request = @@request.merge({ :body => body.to_json, :query => query })
291
+ result = post("/_api/replication/batch", request)
292
+ return_result result: result, key: "id"
293
+ end
294
+
295
+ def self.prolongDumpBatch(id:, ttl:, dbserver: nil) # TESTED
296
+ query = {"DBserver" => dbserver}.delete_if{|k,v| v.nil?}
297
+ body = { "ttl" => ttl }
298
+ request = @@request.merge({ :body => body.to_json, :query => query })
299
+ result = post("/_api/replication/batch/#{id}", request)
300
+ return_result result: result, key: "id"
301
+ end
302
+
303
+ # === REPLICATION ===
304
+
305
+ def self.serverId # TESTED
306
+ result = get("/_api/replication/server-id", @@request)
307
+ return_result result: result, key: "serverId"
308
+ end
309
+
310
+ # === SHARDING ===
311
+
312
+ def self.clusterRoundtrip(cluster: @@cluster)
313
+ result = get("/_admin/#{cluster}", @@request)
314
+ return_result result: result
315
+ end
316
+
317
+ def self.executeCluster(body:, cluster: @@cluster)
318
+ request = @@request.merge({ "body" => body.to_json })
319
+ result = post("/_admin/#{cluster}", request)
320
+ return_result result: result
321
+ end
322
+
323
+ def self.executeClusterPut(body:, cluster: @@cluster)
324
+ request = @@request.merge({ "body" => body.to_json })
325
+ result = put("/_admin/#{cluster}", request)
326
+ return_result result: result
327
+ end
328
+
329
+ def self.destroyCluster(cluster: @@cluster)
330
+ result = delete("/_admin/#{cluster}", @@request)
331
+ return_result result: result, caseTrue: true
332
+ end
333
+
334
+ def self.updateCluster(body:, cluster: @@cluster)
335
+ request = @@request.merge({ "body" => body.to_json })
336
+ result = patch("/_admin/#{cluster}", request)
337
+ return_result result: result, caseTrue: true
338
+ end
339
+
340
+ def self.executeClusterHead(body:, cluster: @@cluster)
341
+ result = head("/_admin/#{cluster}", @@request)
342
+ return_result result: result
343
+ end
344
+
345
+ def self.checkPort(port:)
346
+ query = {"port": port}
347
+ request = @@request.merge({ "query" => query })
348
+ result = get("/_admin/clusterCheckPort", request)
349
+ return_result result: result
350
+ end
351
+
352
+ # === MISCELLANEOUS FUNCTIONS ===
353
+
354
+ def self.version(details: nil) # TESTED
355
+ query = {"details": details}
356
+ request = @@request.merge({ "query" => query })
357
+ result = get("/_api/version", request)
358
+ return_result result: result
359
+ end
360
+
361
+ def self.flushWAL(waitForSync: nil, waitForCollector: nil) # TESTED
362
+ body = {
363
+ "waitForSync" => waitForSync,
364
+ "waitForCollector" => waitForCollector
365
+ }.delete_if{|k,v| v.nil?}.to_json
366
+ request = @@request.merge({ :body => body })
367
+ result = put("/_admin/wal/flush", request)
368
+ return_result result: result, caseTrue: true
369
+ end
370
+
371
+ def self.propertyWAL # TESTED
372
+ result = put("/_admin/wal/properties", @@request)
373
+ return_result result: result
374
+ end
375
+
376
+ def self.changePropertyWAL(allowOversizeEntries: nil, logfileSize: nil, historicLogfiles: nil, reserveLogfiles: nil, throttleWait: nil, throttleWhenPending: nil) # TESTED
377
+ body = {
378
+ "allowOversizeEntries" => allowOversizeEntries,
379
+ "logfileSize" => allowOversizeEntries,
380
+ "historicLogfiles" => historicLogfiles,
381
+ "reserveLogfiles" => reserveLogfiles,
382
+ "throttleWait" => throttleWait,
383
+ "throttleWhenPending" => throttleWhenPending
384
+ }.delete_if{|k,v| v.nil?}.to_json
385
+ request = @@request.merge({ :body => body })
386
+ result = put("/_admin/wal/properties", request)
387
+ return_result result: result
388
+ end
389
+
390
+ def self.transactions # TESTED
391
+ result = get("/_admin/wal/transactions", @@request)
392
+ return_result result: result
393
+ end
394
+
395
+ def self.time # TESTED
396
+ result = get("/_admin/time", @@request)
397
+ return_result result: result, key: "time"
398
+ end
399
+
400
+ def self.echo # TESTED
401
+ result = get("/_admin/echo", @@request)
402
+ return_result result: result
403
+ end
404
+
405
+ # def self.longEcho body: {}
406
+ # request = @@request.merge({ :body => body.to_json })
407
+ # result = get("/_admin/long_echo", request)
408
+ # return_result result: result
409
+ # end
410
+
411
+ def self.databaseVersion # TESTED
412
+ result = get("/_admin/database/target-version", @@request)
413
+ return_result result: result, key: "version"
414
+ end
415
+
416
+ def self.sleep(duration:) # TESTED
417
+ query = {"duration": duration}
418
+ request = @@request.merge({ "query" => query })
419
+ result = get("/_admin/sleep", request)
420
+ return_result result: result, key: "duration"
421
+ end
422
+
423
+ def self.shutdown # TESTED
424
+ result = delete("/_admin/shutdown", @@request)
425
+ return_result result: result, caseTrue: true
426
+ end
427
+
428
+ def self.restart
429
+ `sudo service arangodb restart`
430
+ end
431
+
432
+ def self.test(body:)
433
+ request = @@request.merge({ "body" => body.to_json })
434
+ result = post("/_admin/test", request)
435
+ return_result result: result
436
+ end
437
+
438
+ def self.execute(body:)
439
+ request = @@request.merge({ "body" => body.to_json })
440
+ result = post("/_admin/execute", request)
441
+ return_result result: result
442
+ end
443
+
444
+ # === UTILITY ===
445
+
446
+ def self.return_result(result:, caseTrue: false, key: nil)
447
+ if @@async == "store"
448
+ result.headers["x-arango-async-id"]
449
+ else
450
+ result = result.parsed_response
451
+ if @@verbose || !result.is_a?(Hash)
452
+ result
453
+ else
454
+ if result["error"]
455
+ result["errorMessage"]
456
+ else
457
+ if caseTrue
458
+ true
459
+ elsif key.nil?
460
+ result.delete_if{|k,v| k == "error" || k == "code"}
461
+ else
462
+ result[key]
463
+ end
464
+ end
465
+ end
466
+ end
467
+ end
468
+
469
+ def self.return_result_async(result:, caseTrue: false)
470
+ result = result.parsed_response
471
+ if @@verbose || !result.is_a?(Hash)
472
+ result
473
+ else
474
+ if result["error"]
475
+ result["errorMessage"]
476
+ else
477
+ if caseTrue
478
+ true
479
+ else
480
+ result.delete_if{|k,v| k == "error" || k == "code"}
481
+ end
482
+ end
483
+ end
484
+ end
64
485
  end
@@ -0,0 +1,136 @@
1
+ # === AQL ===
2
+
3
+ class ArangoTask < ArangoServer
4
+ def initialize(database: @@database, id: nil, name: nil, type: nil, period: nil, command: nil, params: {}, created: nil) # TESTED
5
+ if database.is_a?(String)
6
+ @database = database
7
+ elsif database.is_a?(ArangoDatabase)
8
+ @database = database.database
9
+ else
10
+ raise "database should be a String or an ArangoDatabase instance, not a #{database.class}"
11
+ end
12
+ @id = id
13
+ @name = name
14
+ @type = type
15
+ @period = period
16
+ @command = command
17
+ @params = params
18
+ @created = created
19
+ end
20
+
21
+ attr_reader :id, :name, :type, :period, :created, :command, :database, :params
22
+
23
+ def retrieve # TESTED
24
+ result = self.class.get("/_db/#{@database}/_api/tasks/#{@id}")
25
+ if @@async == "store"
26
+ result.headers["x-arango-async-id"]
27
+ else
28
+ result = result.parsed_response
29
+ if @@verbose
30
+ unless result.is_a?(Hash) && result["error"]
31
+ @name = result["name"]
32
+ @type = result["type"]
33
+ @period = result["period"]
34
+ @created = result["created"]
35
+ @command = result["command"]
36
+ @database = result["database"]
37
+ end
38
+ result
39
+ else
40
+ if result.is_a?(Hash) && result["error"]
41
+ result["errorMessage"]
42
+ else
43
+ @name = result["name"]
44
+ @type = result["type"]
45
+ @period = result["period"]
46
+ @created = result["created"]
47
+ @command = result["command"]
48
+ @database = result["database"]
49
+ self
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def self.tasks # TESTED
56
+ result = get("/_db/#{@@database}/_api/tasks", @@request)
57
+ if @@async == "store"
58
+ result.headers["x-arango-async-id"]
59
+ else
60
+ result = result.parsed_response
61
+ if @@verbose
62
+ result
63
+ else
64
+ if result.is_a?(Hash) && result["error"]
65
+ result["errorMessage"]
66
+ else
67
+ result.map{|x| ArangoTask.new(id: x["id"], name: x["name"], type: x["type"], period: x["period"], created: x["created"], command: x["command"], database: x["database"])}
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ def create offset: nil # TESTED
74
+ body = {
75
+ "name" => @name,
76
+ "command" => @command,
77
+ "period" => @period,
78
+ "offset" => offset,
79
+ "params" => @params
80
+ }.delete_if{|k,v| v.nil?}.to_json
81
+ request = @@request.merge({ :body => body })
82
+ if @id.nil?
83
+ result = self.class.post("/_db/#{@database}/_api/tasks", request)
84
+ else
85
+ result = self.class.put("/_db/#{@database}/_api/tasks/#{@id}", request)
86
+ end
87
+ if @@async == "store"
88
+ result.headers["x-arango-async-id"]
89
+ else
90
+ result = result.parsed_response
91
+ if @@verbose
92
+ unless result.is_a?(Hash) && result["error"]
93
+ @id = result["id"]
94
+ @name = result["name"]
95
+ @type = result["type"]
96
+ @period = result["period"]
97
+ @created = result["created"]
98
+ @command = result["command"]
99
+ @database = result["database"]
100
+ end
101
+ result
102
+ else
103
+ if result.is_a?(Hash) && result["error"]
104
+ result["errorMessage"]
105
+ else
106
+ @id = result["id"]
107
+ @name = result["name"]
108
+ @type = result["type"]
109
+ @period = result["period"]
110
+ @created = result["created"]
111
+ @command = result["command"]
112
+ @database = result["database"]
113
+ self
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ def destroy # TESTED
120
+ result = self.class.delete("/_db/#{@database}/_api/tasks/#{@id}", @@request)
121
+ if @@async == "store"
122
+ result.headers["x-arango-async-id"]
123
+ else
124
+ result = result.parsed_response
125
+ if @@verbose
126
+ result
127
+ else
128
+ if result.is_a?(Hash) && result["error"]
129
+ result["errorMessage"]
130
+ else
131
+ true
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end