arangorb3 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md ADDED
@@ -0,0 +1,1104 @@
1
+ ArangoRB [![Gem Version](https://badge.fury.io/rb/arangorb.svg)](https://badge.fury.io/rb/arangorb)
2
+ ===============================
3
+
4
+ UNMANTAINED: This project is not mantained anymore. A new Ruby ArangoDB driver project is in development here: [arango-driver](https://github.com/isomorfeus/arango-driver). Thank you a lot for your support in these years.
5
+
6
+ [ArangoDatabase](https://www.arangodb.com/) is a native multi-model database with flexible data models for document, graphs, and key-values.
7
+ ArangoRB is a Gem to use ArangoDatabase with Ruby. ArangoRB is based on the [HTTP API of ArangoDB](https://docs.arangodb.com/3.4/HTTP/index.html).
8
+
9
+ ArangoRB 0.1.0 - 1.3.0 have been tested with ArangoDB 3.0 with Ruby 2.3.1</br>
10
+ ArangoRB 1.4.0 has been tested with ArangoDB 3.1 with Ruby 2.3.3</br>
11
+ ArangoRB 2.0.0 has been tested with ArangoDB 3.4 with Ruby 2.3.3</br>
12
+
13
+ It requires the gems "HTTParty", "Oj" and "connection_pool"</br>
14
+
15
+ To install ArangoRB: `gem install arangorb`
16
+
17
+ To use it in your application: `require "arangorb"`
18
+
19
+ ## Support
20
+
21
+ This is a project managed by one single person. ArangoDB is a wonderful project that it is hard to cover completely alone. For this reason all your supports is more than welcome.
22
+ Any pull request, issue, suggestions and ideas are more than welcome. Do not be shy to contact me, create issues on Github or pushing changes.
23
+
24
+ Here something the community can help on:
25
+ * Replication example in example/replication_year.rb is a work in progress. Any found bugs and advice to improve it will be great. I removed the IPs in the examples to make clear that it is only an example that needs work.
26
+ * Add test and correct bugs for replication, clustering, foxx and other.
27
+ * Improve AQL instance to implement in Rails.
28
+ * Improve Documentation.
29
+
30
+ If you like this project, please star it. It will remind me that my work has been useful for somebody.
31
+
32
+ For the differences between version 1.4.0 and 2.0.0: [Click here](#differences).
33
+
34
+ For testing: [Click here](#testing).
35
+
36
+ ## Classes used
37
+
38
+ ArangoRB has the two type of classes.
39
+
40
+ Classes relative to ArangoDB elements:
41
+ * [Arango::Server](#ArangoServer): to manage a Server
42
+ * [Arango::Database](#ArangoDatabase): to manage a Database
43
+ * [Arango::Collection](#ArangoCollection): to manage a Collection
44
+ * [Arango::Document](#ArangoDocument): to manage a Document
45
+ * [Arango::Vertex](#ArangoVertex): to manage a Vertex
46
+ * [Arango::Edge](#ArangoEdge): to manage an Edge
47
+ * [Arango::Graph](#ArangoGraph): to manage a Graph
48
+ * [Arango::Traversal](#ArangoTraversal): to manage a Traversal operation
49
+ * [Arango::AQL](#arangoaql): to manage an AQL instances
50
+ * [Arango::User](#ArangoUser): to manage an User
51
+ * [Arango::Index](#ArangoIndex): to manage an Index
52
+ * [Arango::Task](#ArangoTask): to manage a Task
53
+ * [Arango::Transaction](#ArangoTransaction): to manage a Transaction
54
+ * [Arango::Replication](#ArangoReplication): to manage a Replication
55
+ * [Arango::Batch](#ArangoBatch): to manage a Batch of multiple requests
56
+ * [Arango::Foxx](#ArangoFoxx): to manage a Foxx instance
57
+ * [Arango::View](#ArangoView): to manage a View instance
58
+
59
+ Classes relative to the Gem ArangoRB
60
+ * [Arango::Cache](#ArangoCache): to manage internal Cache
61
+ * [Arango::Error](#ArangoError): to handle ArangoRB errors
62
+
63
+ All the instances of these classes can be transformed in Hash with the method to_h.
64
+
65
+ Many methods can have multiple attributes not mentioned in this documentation. Keep in mind that if an attribute is defined in the ArangoDB documentation, then it is easy that it is an attribute for the relative method too.
66
+ Please refer to the ArangoDB documentation, the rubydoc documentation or open an issue for this missing attributes.
67
+
68
+ <a name="ArangoServer"></a>
69
+ ## Arango::Server
70
+
71
+ Arango::Server is used to manage a single server by managing the connection with ArangoDB.
72
+ You can provide your login credentials and it is a mandatory step to start your database.
73
+
74
+ To setup a server use the following way:
75
+
76
+ ``` ruby
77
+ server = Arango::Server.new username: "MyUsername", password: "MyPassword",
78
+ server: "localhost", port: "8529", tls: false
79
+ server.username = "MyOtherUsername" # Default "root"
80
+ server.password = "other_password"
81
+ server.server = "127.0.0.1" # Default "localhost"
82
+ server.port = "8765" # Default "8529"
83
+ server.tls = true # Default false, to do https requests instead of http
84
+ ```
85
+
86
+ Password is a mandatory field.
87
+
88
+ ### Returning results
89
+
90
+ ArangoRB try always to store the information obtained from ArangoDB in an instance.
91
+ If you need to receive the output, you can return it with:
92
+
93
+ ``` ruby
94
+ server.return_output = true # Default false
95
+ ```
96
+
97
+ ### Verbose and warnings
98
+
99
+ For Debugging reasons the user can print out the request and response to ArangoDB by setting verbose to true.
100
+
101
+ ``` ruby
102
+ server.verbose = true # Default false
103
+ ```
104
+
105
+ Remember that verbose is only for testing reason: to work efficiently verbose should be false.
106
+
107
+ Some deprecated methods will return a warning. To silence these warnings use:
108
+
109
+ ``` ruby
110
+ server.warning = false # Default true
111
+ ```
112
+
113
+ ### Connection Pool
114
+
115
+ ArangoRB supports connection pool, to activate it you can setup pool to true during the initialization or the proceedings. To do so use:
116
+
117
+ ``` ruby
118
+ server = Arango::Server.new username: "MyUsername", password: "MyPassword",
119
+ server: "localhost", port: "8529", pool: true, size: 5, timeout: 5, tls: false
120
+ server.pool = true # Defult false
121
+ server.size = 7 # Default 5
122
+ server.timeout = 10 # Default 5
123
+ server.restartPool # Restart pool with new size and timeout
124
+ ```
125
+
126
+ NB: ConnectionPool is not heavily tested.
127
+
128
+ ### Cache
129
+
130
+ Often ArangoRB returns multiple time the same object (for example for lists or for retrieving). It can happens thus that a document instance updated somewhere in your code, it is not update somewhere even if you are refering the same ArangoDB document.
131
+ To avoid this, ArangoRB provides its own cache.
132
+
133
+ You can activate the ArangoRB cache by using:
134
+
135
+ ``` ruby
136
+ server.active_cache = true # Default false
137
+ ```
138
+
139
+ If active_cache is true, then a previous document or collection instance will be stored in the ArangoRB cache. In case a new instance of the same document is created, then a new instance will NOT be created but, instead, the old one will be returned.
140
+
141
+ With an example:
142
+
143
+ ``` ruby
144
+ server.active_cache = false
145
+ a = Arango::Document.new name: "test", collection: my_collection
146
+ b = Arango::Document.new name: "test", collection: my_collection
147
+ # In this case a and b are two different instances
148
+ ```
149
+
150
+ ``` ruby
151
+ server.active_cache = true
152
+ a = Arango::Document.new name: "test", collection: my_collection
153
+ b = Arango::Document.new name: "test", collection: my_collection
154
+ # In this case a and b are the same instance
155
+ ```
156
+
157
+ Note that if you set server.active_cache to false, then the stored Cache will be emptied.
158
+ For more information about the cache, look at the section about [Arango::Cache](#ArangoCache).
159
+
160
+ ### Information
161
+
162
+ Basic information can be retrieved with these command.
163
+
164
+ ``` ruby
165
+ server.to_h # Return an hash of the instances
166
+ server.endpoint # Check address used to connect with the server
167
+ server.username # Check name used to connect with the server
168
+ server.verbose # Check if verbose is true or false
169
+ server.async # Check the status of async
170
+ ```
171
+
172
+ To retrieve lists
173
+
174
+ ``` ruby
175
+ server.databases # Lists of available databases
176
+ server.endpoints # Lists of endpoints used
177
+ server.users # Lists of available users
178
+ server.tasks # Lists of available tasks
179
+ ```
180
+
181
+ To monitoring the server you can use the following commands
182
+
183
+ ``` ruby
184
+ server.log # Return log files
185
+ server.loglevel
186
+ server.updateLoglevel body: body
187
+ server.available? # Reloads the routing information from the collection routing.
188
+ server.reload # Reloads the routing information from the collection routing.
189
+ server.statistics # Returns the statistics information
190
+ server.statisticsDescription # Fetch descriptive info of statistics
191
+ server.status # Status of the server
192
+ server.role # Get to know whether this server is a Coordinator or DB-Server
193
+ server.serverData # Get server data
194
+ server.mode # Get server mode
195
+ server.updateMode(mode: "default") # Change mode of the server
196
+ ```
197
+
198
+ ### Manage Async
199
+
200
+ With Arango::Server you can manage Async results. It can be useful to use async for heavy requests (like the one in example/year.rb).
201
+
202
+ ``` ruby
203
+ server.async = false # default
204
+ server.async = true # fire and forget
205
+ server.async = :store # fire and store
206
+ ```
207
+
208
+ If Async is "store", then the commands of ArangoRB will return the id of the Async requests.
209
+ Arango::Server provides different methods to manage these Async requests.
210
+
211
+ ``` ruby
212
+ server.fetchAsync id: id # Fetches a job result and removes it from the queue
213
+ server.cancelAsync id: id # Cancels an async job
214
+ server.destroyAsync id: id # Deletes an async job result
215
+ server.retrieveAsync id: id # Returns the status of a specific job
216
+ server.retrieveAsyncByType type: type # Returns the ids of job results with a specific
217
+ # status. Type can be "done" or "pending"
218
+ server.retrieveDoneAsync # Equivalent to server.retrieveAsync type: "done"
219
+ server.retrievePendingAsync # Equivalent to server.retrieveAsync type: "pending"
220
+ server.destroyAsync type: type # Deletes async jobs with a specific status
221
+ # Type can be "all" or "expired"
222
+ server.destroyAllAsync # Equivalent to server.destroyAsync type: "all"
223
+ server.destroyExpiredAsync # Equivalent to server.destroyAsync type: "expired"
224
+ ```
225
+
226
+ ### Miscellaneous
227
+
228
+ ``` ruby
229
+ server.version # Returns the server version number
230
+ server.engine # Returns the server engine
231
+ server.flushWAL # Flushes the write-ahead log
232
+ server.propertyWAL # Retrieves the configuration of the write-ahead log
233
+ server.changePropertyWAL # Configures the write-ahead log
234
+ server.transactions # Returns information about the currently running transactions
235
+ server.time # Get the current time of the system
236
+ server.echo # Return current request
237
+ server.databaseVersion # Return the required version of the database
238
+ server.shutdown # Initiate shutdown sequence
239
+ ```
240
+
241
+ UNTESTED
242
+
243
+ ``` ruby
244
+ server.test body: body # Runs tests on server
245
+ server.execute body: body # Execute a script on the server.
246
+ ```
247
+
248
+ ### Cluster (UNTESTED)
249
+
250
+ ArangoDB permits the sharding of the database. Although these methods has not been tested with ArangoRB.
251
+
252
+ ``` ruby
253
+ server.clusterHealth port: port # Allows to check whether a given port is usable
254
+ server.serverId # Returns the id of a server in a cluster.
255
+ server.clusterStatistics dbserver: dbserver # Allows to query the statistics of a
256
+ # DBserver in the cluster
257
+ ```
258
+
259
+ <a name="ArangoDatabase"></a>
260
+ ## Arango::Database
261
+
262
+ Arango::Database is used to manage a Database. You can create an instance in one of the following ways:
263
+
264
+ ``` ruby
265
+ myDatabase = server.database name: "MyDatabase"
266
+ myDatabase = server["MyDatabase"]
267
+ myDatabase = Arango::Database.new database: "MyDatabase", server: server
268
+ ```
269
+
270
+ ### Main methods
271
+
272
+ ``` ruby
273
+ myDatabase.create # Create a new Database
274
+ myDatabase.retrieve # Retrieve database
275
+ myDatabase.destroy # Delete the selected Database
276
+ ```
277
+
278
+ ### Retrieve information
279
+
280
+ ``` ruby
281
+ server.databases # Obtain an Array with the available databases in the server
282
+ myDatabase.to_h # Hash of the instance
283
+ myDatabase.info # Obtain general info about the databases
284
+ myDatabase.sever # Return the server connected with the database
285
+ myDatabase.collections # Obtain an Array with the available collections in the selected Database
286
+ myDatabase.graphs # Obtain an Array with the available graphs in the selected Database
287
+ myDatabase.aqlFunctions # Obtain an Array with the available functions in the selected Database
288
+ myDatabase.foxxes # Return all the foxx available in the database
289
+ myDatabase.views # Return all the views available in the database
290
+ myDatabase.tasks # Return all the tasks available in the database
291
+ ```
292
+
293
+ <a name="arangoaql"></a>
294
+ ## Arango::AQL
295
+
296
+ An AQL instance can be created by using one of the following way:
297
+
298
+ ``` ruby
299
+ query = "FOR v,e,p IN 1..6 ANY 'Year/2016' GRAPH 'MyGraph' FILTER p.vertices[1].num == 6 && p.vertices[2].num == 22 && p.vertices[6]._key == '424028e5-e429-4885-b50b-007867208c71' RETURN [p.vertices[4].value, p.vertices[5].data]"
300
+ myQuery = myDatabase.aql query: query
301
+ myQuery = ArangoAQL.new database: myDatabase, query: query
302
+ ```
303
+
304
+ To execute it use:
305
+
306
+ ``` ruby
307
+ myQuery.execute
308
+ ```
309
+
310
+ If the query is too big, you can divide the fetching in pieces, for example:
311
+
312
+ ``` ruby
313
+ myQuery.size = 10
314
+ myQuery.execute # First 10 documents
315
+ myQuery.next # Next 10 documents
316
+ myQuery.next # Next 10 documents
317
+ ```
318
+
319
+ Other useful methods are the following
320
+
321
+ ``` ruby
322
+ myQuery.destroy # Destroy cursor to retrieve documents
323
+ myQuery.kill # Kill query request (if requires too much time)
324
+ myQuery.explain # Show data query
325
+ myQuery.parse # Parse query
326
+ ```
327
+
328
+ ### Query Properties
329
+
330
+ It is possible to handle generic properties of query by Arango::Database.
331
+
332
+ ``` ruby
333
+ myQuery.to_h # Return an hash version of the instance
334
+ myQuery.properties # Check Query properties
335
+ myQuery.current # Retrieve current running Query
336
+ myQuery.changeProperties maxSlowQueries: 65 # Change Properties
337
+ myQuery.slow # Retrieve slow Queries
338
+ myQuery.stopSlowQueries # Stop slow Queries
339
+ ```
340
+
341
+ The cache of the query can handle in the following way:
342
+
343
+ ``` ruby
344
+ myDatabase.retrieveQueryCache # Retrieve Query Cache
345
+ myDatabase.clearQueryCache # Clear Query Cache
346
+ myDatabase.propertyQueryCache # Check properties Cache
347
+ myDatabase.changePropertyQueryCache maxResults: 30 # Change properties Cache
348
+ ```
349
+
350
+ ### AQL Functions
351
+
352
+ AQL queries can be potentiate by providing javascript function as supports.
353
+
354
+ ``` ruby
355
+ myDatabase.createAqlFunction code: "function(){return 1+1;}", name: "myFunction" # Create a new AQL Function
356
+ myDatabase.deleteFunction name: "myFunction" # Delete an AQL function
357
+ myDatabase.aqlFunctions # Retrieve a list of the available aql functions
358
+ ```
359
+
360
+ <a name="ArangoCollection"></a>
361
+ ## Arango::Collection
362
+
363
+ Arango::Collection is used to manage your Collections. You can create an Arango::Collection instance in one of the following way:
364
+
365
+ ``` ruby
366
+ myCollection = myDatabase.collection name: "MyCollection"
367
+ myCollection = myDatabase["MyCollection"]
368
+ myCollection = Arango::Collection.new database: myDatabase, collection: "MyCollection"
369
+ ```
370
+
371
+ A Collection can be of two types: "Document" and "Edge". If you want to specify it, uses:
372
+
373
+ ``` ruby
374
+ myCollectionA = ArangoCollection.new collection: "MyCollectionA", type: :document # Default
375
+ myEdgeCollection = ArangoCollection.new collection: "MyCollectionB", type: :edge
376
+ ```
377
+
378
+ ### Main methods
379
+
380
+ ``` ruby
381
+ myCollection.create # Create collection
382
+ myCollection.destroy # Delete collection from database
383
+ myCollection.truncate # Delete all the Documents inside the selected Collection
384
+ myCollection.retrieve # Retrieve the selected Collection
385
+ ```
386
+
387
+ ### Info methods
388
+
389
+ ``` ruby
390
+ myCollection.database # Return database of the collection
391
+ myCollection.server # Returm server of the collection
392
+ myCollection.indexes # Return a list of all used Indexes in the Collection
393
+ myCollection.rotate # Rotate the collection
394
+ myCollection.data # Returns the whole content of one collection
395
+ myCollection.properties # Properties of the Collection
396
+ myCollection.count # Number of Documents in the Collection
397
+ myCollection.stats # Statistics of the Collection
398
+ myCollection.revision # Return collection revision id
399
+ myCollection.checksum # Return checksum for the Collection
400
+ ```
401
+
402
+ ### Modify the Collection
403
+
404
+ ``` ruby
405
+ myCollection.load # Load the collection (preparing for retrieving documents)
406
+ myCollection.unload # Unload the collection (if you stop to work with it)
407
+ myCollection.loadIndexesIntoMemory # Load indexes in memory
408
+ myCollection.change(waitForSync: true) # Change some properties
409
+ myCollection.rename(newName: "myCollection2") # Change name (NB: This is not Arango::Cache compatible)
410
+ myCollection.rotate # Rotate journal of a collection
411
+ ```
412
+
413
+ ### Handle documents
414
+
415
+ To retrieve all the documents of a Collection you can use:
416
+
417
+ ``` ruby
418
+ myCollection.documents
419
+ myCollection.allDocuments
420
+ ```
421
+
422
+ These two functions are similar except for the fact that you can assign different variables.
423
+
424
+ ``` ruby
425
+ myCollection.documents type: "path"
426
+ myCollection.next # Retrieve other documents if the first request is not finished
427
+ ```
428
+
429
+ Type can be "path", "id" or "key" in relation what we wish to have. If not specified ArangoRB will return an array of Arango::Document instances.
430
+
431
+ ``` ruby
432
+ myCollection.allDocuments skip: 3, limit: 100, batchSize: 10
433
+ ```
434
+
435
+ It means that we skip the first three Documents, we can retrieve the next 100 Documents but we return only the first ten.
436
+
437
+ To retrieve specific Document you can use:
438
+
439
+ ``` ruby
440
+ myCollection.documentsMatch match: {"value": 4} # All Documents of the Collection with value equal to 4
441
+ myCollection.documentMatch match: {"value": 4} # The first Document of the Collection with value equal to 4
442
+ myCollection.documentByKeys keys: ["4546", "4646"] # Documents of the Collection with the keys in the Array
443
+ myCollection.documentByName names: ["4546", "4646"] # Documents of the Collection with the name in the Array
444
+ myCollection.random # A random Document of the Collection
445
+ ```
446
+
447
+ #### Modifying multiple documents
448
+
449
+ From a collection is it possible to create, remove and modify multiple documents.
450
+
451
+ ``` ruby
452
+ myCollection.createDocuments document: [myDocumentA, myDocumentB, {"value": 17}] # Array of Arango::Document instances and Hashes
453
+ myCollection.removeByKeys keys: ["4546", "4646"] # Documents of the Collection with the keys in the Array will be removed
454
+ myCollection.removeMatch match: {"value": 4} # All Documents of the Collection with value equal to 4 will be removed
455
+ myCollection.replaceMatch match: {"value": 4}, newValue: {"value": 6} # All Documents of the Collection with value equal to 4 will be replaced with the new Value
456
+ myCollection.updateMatch match: {"value": 4}, newValue: {"value": 6} # All Documents of the Collection with value equal to 4 will be updated with the new Value
457
+ ```
458
+
459
+ #### Create multiple Edges at once
460
+
461
+ We have the possibility to create different combination of Edges in only one line of code.
462
+
463
+ One-to-one with one Edge class
464
+
465
+ * [myDocA] --(myEdge)--> [myDocB]
466
+
467
+ ``` ruby
468
+ myEdgeCollection.createEdges document: myEdge, from: myDocA, to: myDocB
469
+ ```
470
+
471
+ One-to-more with one Edge class (and More-to-one with one Edge class)
472
+
473
+ * [myDocA] --(myEdge)--> [myDocB]
474
+ * [myDocA] --(myEdge)--> [myDocC]
475
+
476
+ ``` ruby
477
+ myEdgeCollection.createEdges document: myEdge, from: myDocA, to: [myDocB, myDocC]
478
+ ```
479
+
480
+ More-to-More with one Edge class
481
+
482
+ * [myDocA] --(myEdge)--> [myDocC]
483
+ * [myDocB] --(myEdge)--> [myDocC]
484
+ * [myDocA] --(myEdge)--> [myDocD]
485
+ * [myDocB] --(myEdge)--> [myDocD]
486
+
487
+ ``` ruby
488
+ myEdgeCollection.createEdges document: myEdge, from: [myDocA, myDocB], to: [myDocC, myDocD]
489
+ ```
490
+
491
+ More-to-More with more Edge classes
492
+
493
+ * [myDocA] --(myEdge)--> [myDocC]
494
+ * [myDocB] --(myEdge)--> [myDocC]
495
+ * [myDocA] --(myEdge)--> [myDocD]
496
+ * [myDocB] --(myEdge)--> [myDocD]
497
+ * [myDocA] --(myEdge2)--> [myDocC]
498
+ * [myDocB] --(myEdge2)--> [myDocC]
499
+ * [myDocA] --(myEdge2)--> [myDocD]
500
+ * [myDocB] --(myEdge2)--> [myDocD]
501
+
502
+ ``` ruby
503
+ myEdgeCollection.createEdges document: [myEdge, myEdge2], from: [myDocA, myDocB], to: [myDocC, myDocD]
504
+ ```
505
+
506
+
507
+ ### Import and Export Documents
508
+
509
+ Another way to create multiple documents in a Collection with only one request is by using the method import.
510
+
511
+ #### Import one Document with Array
512
+
513
+ We can import one document with the following structure {"value": "uno", "num": 1, "name": "ONE"}.
514
+
515
+ ``` ruby
516
+ attributes = ["value", "num", "name"]
517
+ values = ["uno",1,"ONE"]
518
+ myCollection.import attributes: attributes, values: values
519
+ ```
520
+
521
+ #### Import more Documents with Array
522
+
523
+ We can import three Documents with the following structure {"value": "uno", "num": 1, "name": "ONE"}, {"value": "due", "num": 2, "name": "TWO"}, {"value": "tre", "num": 3, "name": "THREE"}.
524
+
525
+ ``` ruby
526
+ attributes = ["value", "num", "name"]
527
+ values = [["uno",1,"ONE"],["due",2,"TWO"],["tre",3,"THREE"]]
528
+ myCollection.import attributes: attributes, values: values
529
+ ```
530
+
531
+ #### Import more Documents with JSON
532
+
533
+ I import two Documents with the following structure {"value": "uno", "num": 1, "name": "ONE"}, {"value": "due", "num": 2, "name": "TWO"}.
534
+
535
+ ``` ruby
536
+ body = [{"value": "uno", "num": 1, "name": "ONE"}, {"value": "due", "num": 2, "name": "DUE"}]
537
+ myCollection.importJSON body: body
538
+ ```
539
+
540
+ #### Export files
541
+
542
+ As it is possible to import files, it is possible to export all the Document of a Collection with the following command.
543
+
544
+ ``` ruby
545
+ myCollection.export
546
+ ```
547
+
548
+ Alternatively it is possible to retrieve all the Documents in a Collection gradually.
549
+
550
+ ``` ruby
551
+ myCollection.export batchSize: 3 # First three Documents of the Collection
552
+ myCollection.exportNext # Next three Documents
553
+ myCollection.exportNext # Next three Documents
554
+ ```
555
+
556
+ <a name="ArangoDocument"></a>
557
+ ## Arango::Document
558
+
559
+ An Arango::Document is an element of a Arango::Collection. Edges are Arango documents with "\_from" and "\_to" in their body.
560
+ You can create an ArangoCollection instance in one of the following way:
561
+
562
+ ``` ruby
563
+ myDocument = myCollection.document name: "MyDocument"
564
+ myDocument = myCollection["MyDocument"]
565
+ myDocument = Arango::Document.new collection: myCollection, name: "MyDocument"
566
+ ```
567
+
568
+ In the case you want to define a Edge, it is convenient to introduce the parameters "from" and "to" in the instance.
569
+
570
+ ``` ruby
571
+ myEdge = Arango::Document.new name: "MyEdge", from: myDocA, to: myDocB
572
+ ```
573
+
574
+ where myDocA and myDocB are the IDs of two Documents or are two Arango::Document instances.
575
+
576
+ During the creation of an Arango::Document instance, it is possible to define the body for the Document.
577
+
578
+ ``` ruby
579
+ myDocument = Arango::Document.new body: {"value": 17}, name: "MyDocument"
580
+ ```
581
+
582
+ ### Main methods
583
+
584
+ ArangoRB provides several way to create a single Document.
585
+
586
+ ``` ruby
587
+ myDocument.create # Create a new document
588
+ myDocument.retrieve # Retrieve Document
589
+ myDocument.update body: {"value": 3} # We update or add a value
590
+ myDocument.replace body: {"value": 3} # We replace a value
591
+ myDocument.destroy # Destroy document
592
+ ```
593
+
594
+ ### Retrieve information
595
+
596
+ ``` ruby
597
+ myDocument.collection # Retrieve Collection of the Document
598
+ myDocument.database # Retrieve Database of the Document
599
+ myDocument.server # Retrieve Server of the Document
600
+ myDocument.edges collection: myEdgeCollection # Retrieve all myEdgeCollection edges connected with the Document
601
+ myDocument.any(myEdgeCollection) # Retrieve all myEdgeCollection edges connected with the Document
602
+ myDocument.in(myEdgeCollection) # Retrieve all myEdgeCollection edges coming in the Document
603
+ myDocument.out(myEdgeCollection) # Retrieve all myEdgeCollection edges going out the Document
604
+ myEdge.from # Retrieve the document at the begin of the edge
605
+ myEdge.to # Retrieve the document at the end of the edge
606
+ ```
607
+
608
+ #### Example: how to navigate the edges
609
+
610
+ It is possible to navigate between edges and vertexes of a graph database.
611
+
612
+ Think for example that we have the following schema:
613
+ * A --[class: a, name: aa]--> B
614
+ * A --[class: a, name: bb]--> C
615
+ * A --[class: b, name: cc]--> D
616
+ * B --[class: a, name: dd]--> E
617
+
618
+ Then we have:
619
+
620
+ * A.retrieve is A
621
+ * A.edges(collection: a) is [aa, bb]
622
+ * B.in(a) is [aa]
623
+ * B.out(a) is [dd]
624
+ * B.any(a) is [aa, dd] (aa in entry, dd in exit)
625
+ * aa.from is A
626
+ * aa.to is B
627
+
628
+ We can even do some combinations: for example A.out(a)[0].to.out(a)[0].to is E since:
629
+ * A.out(a) is [aa]
630
+ * A.out(a)[0] is aa
631
+ * A.out(a)[0].to is B
632
+ * A.out(a)[0].to.out(a) is [dd]
633
+ * A.out(a)[0].to.out(a)[0] is dd
634
+ * A.out(a)[0].to.out(a)[0].to is E
635
+
636
+ <a name="ArangoGraph"></a>
637
+ ## Arango::Graph
638
+
639
+ ArangoGraph are used to manage Graphs. You can create an Arango::Graph instance in one of the following way.
640
+
641
+ ``` ruby
642
+ myGraph = myDatabase.graph name: "MyGraph"
643
+ myGraph = Arango::Graph.new name: "MyGraph", database: myDatabase
644
+ ```
645
+
646
+ ### Main methods
647
+
648
+ ``` ruby
649
+ myGraph.create # create a new Graph
650
+ myGraph.retrieve # retrieve the Graph
651
+ myGraph.database # retrieve database of the Graph
652
+ myGraph.destroy # destroy the Graph
653
+ ```
654
+
655
+ ### Manage Vertex Collections
656
+
657
+ ``` ruby
658
+ myGraph.getVertexCollections # Retrieve all the vertexCollections of the Graph
659
+ myGraph.addVertexCollection collection: "myCollection" # Add a Vertex Collection to our Graph
660
+ myGraph.removeVertexCollection collection: "myCollection" # Remove a Vertex Collection to our Graph
661
+ ```
662
+
663
+ ### Manage Edge Collections
664
+
665
+ ``` ruby
666
+ myGraph.edgeCollections # Retrieve all the edgeCollections of the Graph
667
+ myGraph.addEdgeCollections collection: "myEdgeCollection", from: "myCollectionA", to: "myCollectionB" # Add an Edge Collection to our Graph
668
+ myGraph.replaceEdgeCollections collection: "myEdgeCollection", from: "myCollectionA", to: "myCollectionB" # Replace an Edge Collection to our Graph
669
+ myGraph.removeEdgeCollections collection: "myEdgeCollection" # Remove an Edge Collection to our Graph
670
+ ```
671
+
672
+ <a name="ArangoVertex"></a>
673
+ <a name="ArangoEdge"></a>
674
+ ## Arango::Vertex and Arango::Edge
675
+
676
+ Both these two classes inherit the class Arango::Document.
677
+ These two classes have been created since Arango::Database offers, in connection of the chosen graph, different HTTP requests to manage Vertexes and Edges. We recommend the reader to read carefully the section on [Arango::Document instances](#ArangoDocument) before to start to use Arango::Vertex and Arango::Edge instances.
678
+
679
+ ### Arango::Vertex methods
680
+
681
+ Arango::Vertex inherit all the methods of Arango::Document class. The following one works similar to the one of Arango::Document Class but use different HTTP requests. For this reason the performance could be different.
682
+ To use Arango::Vertex, the Collection of the Vertex needs to be added either to the VertexCollections or to the EdgeCollections of the chosen Graph. And the Collection needs to have assigned the graph.
683
+
684
+ ``` ruby
685
+ myCollection.graph = myGraph # Be sure that the collection is assigned to a Graph
686
+ myVertex = myCollection.vertex name: "newVertex", body: {"value": 3} # If graph is not assigned, an Arango::Document will be created
687
+ myVertex = Arango::Vertex.new name: "newVertex", body: {"value": 3},
688
+ collection: myCollection # create a new instance
689
+ ```
690
+
691
+ ``` ruby
692
+ myVertex.create # create a new Document in the Graph
693
+ myVertex.retrieve # retrieve a Document
694
+ myVertex.graph # retrieve Graph of the Document
695
+ myVertex.replace body: {"value": 6} # replace the Document
696
+ myVertex.update body: {"value": 6} # update the Document
697
+ myVertex.destroy # delete the Document
698
+ ```
699
+
700
+ ### Arango::Edge methods
701
+
702
+ Arango::Edge inherit all the methods of Arango::Document class. The following one works similar to the one of Arango::Document Class but use a different HTTP request. For this reason the performance could be different.
703
+ To use Arango::Edge, the Collection of the Edge needs to be added to the EdgeCollections of the chosen Graph.
704
+
705
+ ``` ruby
706
+ myEdgeCollection.graph = myGraph
707
+ myEdge = myCollection.edge name: "newEdge", body: {"value": 3}, from: myArangoDocument1, to: myArangoDocument2 # If graph is not assigned, an Arango::Document will be created
708
+ ```
709
+
710
+ ``` ruby
711
+ myEdge.create # create a new Document of type Edge in the Graph
712
+ myEdge.retrieve # retrieve a Document
713
+ myEdge.graph # Retrieve Graph of the Document
714
+ myEdge.replace body: {"value": 6} # replace the Document
715
+ myEdge.update body: {"value": 6} # update the Document
716
+ myEdge.destroy # delete the Document
717
+ ```
718
+
719
+ <a name="ArangoTraversal"></a>
720
+ ## Arango::Traversal
721
+
722
+ Arango::Traversal is used to administrate the traversals.
723
+ Arango::Traversal needs to know the vertex from where the traversal starts, the direction the traversal is going and either the Graph or the EdgeCollection we want to analyze.
724
+
725
+
726
+ ``` ruby
727
+ myTraversal = myVertex.traversal # Start traversal from myVertex
728
+ myTraversal = myDocument.traversal # Start traversal from myDocument
729
+ myTraversal = ArangoTraversal.new database: myDatabase, startVertex: myVertex # create instance
730
+ ```
731
+
732
+ ``` ruby
733
+ myTraversal.vertex = myVertex # define starting Vertex
734
+ myTraversal.edgeCollection = myEdgeCollection # define used Edge
735
+ myTraversal.in # Direction is in
736
+ myTraversal.out # Direction is out
737
+ myTraversal.any # Direction is in and out
738
+ myTraversal.min = 1 # Define how minimum deep we want to go with the traversal
739
+ myTraversal.max = 3 # Define how maximum deep we want to go with the traversal
740
+ ```
741
+
742
+ After the traversal is setup, you can execute it:
743
+
744
+ ``` ruby
745
+ myTraversal.execute
746
+ ```
747
+
748
+ <a name="ArangoUser"></a>
749
+ ## Arango::User
750
+
751
+ Arango::User manages the users.
752
+ To initialize an user:
753
+
754
+ ``` ruby
755
+ myUser = server.user name: "MyUser", password: "password"
756
+ myUser = Arango::User.new user: "MyUser", password: "password", server: server
757
+ ```
758
+
759
+ ### User management
760
+
761
+ ``` ruby
762
+ myUser.retrieve # Retrieve User
763
+ myUser["MyDatabase"] # Retrieve database if the user can access it
764
+ myUser.database("MyDatabase") # Retrieve database if the user can access it
765
+ myUser.create # Create a new User
766
+ myUser.replace active: false # Replace User
767
+ myUser.update active: false # Update User
768
+ myUser.destroy # Delete User
769
+ ```
770
+
771
+ ### Database management
772
+
773
+ ``` ruby
774
+ myUser.databases # List of databases can access
775
+ myUser.addDatabaseAccess grant: "rw", database: myDatabase
776
+ myUser.grant database: myDatabase # Grant access to a database
777
+ myUser.revoke database: myDatabase # Revoke access to a database
778
+ myUser.databaseAccess database: myDatabase # Check permission level of an User
779
+ myUser.addCollectionAccess grant: "rw", database: myDatabase, collection: myCollection
780
+ myUser.revokeCollectionAccess database: myDatabase, collection: myCollection
781
+ myUser.collectionAccess database: myDatabase, collection: myCollection
782
+ ```
783
+
784
+ You can manage the user permissions from the database or from the collection too.
785
+
786
+ ``` ruby
787
+ myDatabase.check_user(myUser)
788
+ myDatabase.addUserAccess(grant: "rw", user: myUser)
789
+ myDatabase.revokeUserAccess(user: myUser)
790
+ myDatabase.userAccess(user: myUser)
791
+ myCollection.check_user(myUser)
792
+ myCollection.addUserAccess(grant: "rw", user: myUser)
793
+ myCollection.revokeUserAccess(user: myUser)
794
+ myCollection.userAccess(user: myUser)
795
+ ```
796
+
797
+ <a name="ArangoIndex"></a>
798
+ ## Arango::Index
799
+
800
+ Arango::Index manages the indexes.
801
+ To initialize an index:
802
+
803
+ ``` ruby
804
+ myIndex = myCollection.index fields: "num", unique: false, id: "myIndex"
805
+ myIndex = Arango::Index.new fields: "num", unique: false, id: "myIndex", collection: myCollection
806
+ ```
807
+
808
+ ### Index management
809
+
810
+ ``` ruby
811
+ myIndex.retrieve # Retrieve Index
812
+ myIndex.create # Create a new Index
813
+ myIndex.destroy # Delete Index
814
+ ```
815
+
816
+ <a name="ArangoTransaction"></a>
817
+ ## Arango::Transaction
818
+
819
+ Transactions are managed by Arango::Transaction.
820
+
821
+ ``` ruby
822
+ action = "function(){ var db = require('@arangodb').db; db.MyCollection.save({}); return db.MyCollection.count(); }"
823
+ myTransaction = myDatabase.transaction action: action
824
+ myTransaction = Arango::Transaction.new action: action, database: myDatabase
825
+ ```
826
+
827
+ ``` ruby
828
+ myTransaction.addWrite(myCollection) # Add write collection
829
+ myTransaction.addRead(myCollection) # Add read collection
830
+ myArangoTransaction.execute # Return the result of the execution
831
+ ```
832
+
833
+ <a name="ArangoTask"></a>
834
+ ## Arango::Task
835
+
836
+ Tasks are managed by ArangoTask.
837
+
838
+ ``` ruby
839
+ command = "(function(params) { require('@arangodb').print(params); })(params)"
840
+ myTask = myDatabase.task id: "mytaskid", name: "MyTaskID", command: command, params: {"foo": "bar", "bar": "foo"}, period: 2
841
+ myTask = Arango::Task.new id: "mytaskid", name: "MyTaskID", command: command, params: {"foo": "bar", "bar": "foo"}, period: 2, database: myDatabase
842
+ ```
843
+
844
+ ``` ruby
845
+ myArangoTask.create # Create a new Task
846
+ myArangoTask.retrieve # Retrieve a Task
847
+ myArangoTask.destroy # Delete a Task
848
+ ```
849
+
850
+ <a name="ArangoReplication"></a>
851
+ ## Arango::Replication
852
+
853
+ Replication is useful to create back up copy of your database or to have a master-slave relationship between two databases.
854
+
855
+ Remember: the used database is the one where the data will be written (the slave) and the remote database will be the master one.
856
+
857
+ Use with caution since the data in the slave database will be deleted.
858
+
859
+ To setup our Slave Server and Master Database use a similar command.
860
+
861
+ ``` ruby
862
+ myReplication = slaveDatabase.replication(master: masterDatabase)
863
+ myReplication = masterDatabase.replication_as_master(slave: slaveDatabase)
864
+ myReplication = Arango::Replication.new master: masterDatabase, slave: slaveDatabase
865
+ ```
866
+
867
+ Than to do a simple syncronization uses;
868
+
869
+ ``` ruby
870
+ myReplication.sync # Sync master - slave database
871
+ ```
872
+
873
+ To retrieve other information ArangoRB provides the following methods:
874
+
875
+ ``` ruby
876
+ myReplication.logger # Returns the current state of the server's replication logger
877
+ myReplication.loggerFollow # Returns data from the server's replication log.
878
+ myReplication.firstTick # Return the first available tick value from the server
879
+ myReplication.rangeTick # Returns the currently available ranges of tick values for all currently available WAL logfiles.
880
+ myReplication.serverId # Returns the servers id.
881
+ ```
882
+
883
+ ### Relation Master-Slave
884
+
885
+ To enslave a Server in relation to another Database use the following command:
886
+
887
+ ``` ruby
888
+ myReplication.enslave
889
+ ```
890
+
891
+ To manage the Configuration of a Master-Slave Replication you can use the following commands:
892
+
893
+ ``` ruby
894
+ myReplication.start # Start replication
895
+ myReplication.configuration # check the Configuration of the Replication
896
+ myReplication.state # check the status of the Replication
897
+ myReplication.stop # stop the Replication
898
+ myReplication.modify # modify the Configuration of the Replication (you can modify only a stopped Replication)
899
+ ```
900
+
901
+ ## Arango::Batch
902
+
903
+ To create a batch request, you can use ArangoRB::Batch object. This permit to do multiple requests with one single call to the API.
904
+
905
+ To create a batch use one of the following way:
906
+
907
+ ``` ruby
908
+ batch = server.batch
909
+ batch = Arango::Batch.new(server: server)
910
+ ```
911
+
912
+ To add a queries to the batch request you can use the brutal way:
913
+
914
+ ``` ruby
915
+ batch.queries = [
916
+ {
917
+ "type": "POST",
918
+ "address": "/_db/MyDatabase/_api/collection",
919
+ "body": {"name": "newCOLLECTION"},
920
+ "id": "1"
921
+ },
922
+ {
923
+ "type": "GET",
924
+ "address": "/_api/database",
925
+ "id": "2"
926
+ }
927
+ ]
928
+ ```
929
+
930
+ Or the Ruby way (the id will be handled by the system, if not specified):
931
+
932
+ ``` ruby
933
+ batch = server.batch
934
+ batch.addQuery(method: "POST", address: "/_db/MyDatabase/_api/collection",
935
+ body: {"name": "newCOLLECTION"})
936
+ batch.addQuery(method: "GET", address: "/_api/database")
937
+ ```
938
+
939
+ In both the cases the queries will be stored in an hash with key the id of the query and as value the query.
940
+ This query can be handled with the following methods:
941
+
942
+ ``` ruby
943
+ batch.to_h # Retrieve an hash version of the instance
944
+ batch.modifyQuery(id: "1", method: "GET", address: "/_db/MyDatabase/_api/collection/newCOLLECTION") # Modify the Query with id "1"
945
+ batch.removeQuery(id: "1") # Remove query
946
+ ```
947
+
948
+ To execute the query use:
949
+
950
+ ``` ruby
951
+ batch.execute
952
+ ```
953
+
954
+ To manage how the server handle the batch, Arango::Server offers the following functions:
955
+
956
+ ``` ruby
957
+ server.createDumpBatch ttl: 10 # Create a new dump batch with 10 second time-to-live (return id of the dumpBatch)
958
+ server.prolongDumpBatch id: idDumpBatch, ttl: 20 # Prolong the life of a batch for 20 seconds
959
+ server.destroyDumpBatch id: idDumpBatch # Delete a selected batch
960
+ ```
961
+
962
+ <a name="ArangoView"></a>
963
+ ## Arango::View
964
+
965
+ Views are managed by Arango::View.
966
+
967
+ ``` ruby
968
+ myView = myDatabase.view name: "MyView"
969
+ myView = Arango::View.new name: "MyView", database: myDatabase
970
+ ```
971
+
972
+ ``` ruby
973
+ myView.addLink(collection: myCollection) # Add a collection to the link
974
+ myView.retrieve # Retrieve view
975
+ myView.create # Create a view
976
+ myView.replaceProperties # Replace properties
977
+ myView.updateProperties # Update properties
978
+ myView.rename name: "MyView2" # Change name
979
+ myView.properties # Check properties
980
+ myView.destroy # Delete view
981
+ ```
982
+
983
+ <a name="ArangoFoxx"></a>
984
+ ## Arango::Foxx
985
+
986
+ Views are managed by Arango::Foxx. This instance of Foxx is untested.
987
+
988
+ ``` ruby
989
+ myFoxx = myDatabase.foxx mount: address
990
+ myFoxx = Arango::Foxx.new mount: address, database: myDatabase
991
+ ```
992
+
993
+ ``` ruby
994
+ myFoxx.retrieve # Retrieve foxx
995
+ myView.create # Create a foxx
996
+ myFoxx.update # Update foxx
997
+ myFoxx.replace # Replace foxx
998
+ myFoxx.destroy # Delete foxx
999
+ ```
1000
+
1001
+ Other methods
1002
+
1003
+ ``` ruby
1004
+ myFoxx.retrieveConfiguration
1005
+ myView.updateConfiguration body: body
1006
+ myFoxx.replaceConfiguration body: body
1007
+ myFoxx.retrieveDependencies
1008
+ myFoxx.updateDependencies body: body
1009
+ myFoxx.replaceDependencies body: body
1010
+ myFoxx.scripts
1011
+ myFoxx.run_script name: "test"
1012
+ myFoxx.tests
1013
+ myFoxx.enableDevelopment
1014
+ myFoxx.disableDevelopment
1015
+ myFoxx.readme
1016
+ myFoxx.swagger
1017
+ myFoxx.download path: path
1018
+ myFoxx.commit body: body
1019
+ ```
1020
+
1021
+ <a name="ArangoCache"></a>
1022
+ ## Arango::Cache
1023
+
1024
+ Arango::Cache is to manage ArangoRB Cache (NOT ArangoDB cache) and it helps you to manage your documents around your code. In this way if you update an Arango::Document in your code, it will updated everywhere.
1025
+ An Arango::Cache instance is created together with the initialization of a server instance with active_cache true.
1026
+
1027
+ ``` ruby
1028
+ cache = server.cache # Arango::Cache instance
1029
+ cache.max # Max number of variable stored in the cache
1030
+ cache.updateMax(type: :document, val: 400) # Update how many documents store in the cache
1031
+ cache.clear # Clear cache
1032
+ cache.to_h # Hash of the cache
1033
+ ```
1034
+
1035
+ NB: If you insert a max value higher than the quantity of elements in the Cache, then the first elements in excess will be removed from the Cache.
1036
+
1037
+ If the limit of the Cache for one type is reached, then the first element cached of that type will be deleted from the Cache.
1038
+
1039
+
1040
+ <a name="ArangoError"></a>
1041
+ ## Arango::Error
1042
+
1043
+ Error from ArangoRB are managed by Arango::Error.
1044
+ Each ArangoRB error is provided of a code and a message. The list of code can be find in the file lib/Error.rb
1045
+
1046
+ ``` ruby
1047
+ begin
1048
+ Arango::Collection.new name: "Test", database: not_a_database
1049
+ rescue Arango::Error => e
1050
+ e.message # Message of the error
1051
+ e.code # ArangoRB code, each ArangoRB errors provides a list of errors
1052
+ e.data # More information about the error
1053
+ e.to_h # Hash version of the error
1054
+ end
1055
+ ```
1056
+
1057
+ Arango::Error has a children class called Arango::ErrorDB to handle Errors coming from wrong HTTP requests.
1058
+
1059
+ ``` ruby
1060
+ begin
1061
+ Arango::Collection.new(name: "DuplicateCollection", database: myDatabase).create
1062
+ rescue Arango::Error => e
1063
+ e.message # Message of the error
1064
+ e.code # HTTP error code
1065
+ e.data # More information about the error
1066
+ e.errorNum # ArangoDB errorNum code
1067
+ e.action # Type of request done to ArangoDB (POST, GET, ...)
1068
+ e.url # URL requested to ArangoDB
1069
+ e.request # Request made to ArangoDB
1070
+ e.to_h # Hash version of the error
1071
+ end
1072
+ ```
1073
+
1074
+ <a name="testing"></a>
1075
+ ## Testing
1076
+
1077
+ To test ArangoRB you can use:
1078
+
1079
+ ``` ruby
1080
+ rspec spec/arangoRB_helper.rb
1081
+ ruby examples/year.rb
1082
+ ruby examples/year2.rb
1083
+ ```
1084
+
1085
+ Remember however the following:
1086
+ * Setup the correct server in lib/spec_helper.rb and in the examples
1087
+ * The test examples/year2.rb should run much after the test examples/year.rb, since the last test is dependent from the conclusion of the first test (that is running in async).
1088
+
1089
+ <a name="differences"></a>
1090
+ ## Differences between version 1.4 and 2.0
1091
+
1092
+ ArangoRB 1.4 and ArangoRB 2.0 are not compatible.
1093
+ The new version provide different improvements.
1094
+ * Now all the instances are in a module Arango. This means that previous classes like ArangoServer will become Arango::Server.
1095
+ * Arango::Server is now an instance. This means that ArangoRB 2.0 will permits to use different servers.
1096
+ * ArangoRB has implemented connection_pool.
1097
+ * ArangoRB has now a better implementation of Cache.
1098
+ * The returned values are returned with symbols as keys.
1099
+ * Oj is used for parsing instead of JSON.
1100
+ * Add supports for View and Foxx. The least is untested.
1101
+ * Better hierarchy handling between the different instances. For example now myDocument.database will return the database instance that includes the document.
1102
+ * Better handling of replication (untested).
1103
+ * Clean in general the code (for future maintainer).
1104
+ * Now errors are handled by Arango::Error.